更新使用手册;修复滚动条问题;新增表映射关系查询
This commit is contained in:
+197
-5
@@ -317,7 +317,7 @@ sequenceDiagram
|
||||
|
||||
**要点:**
|
||||
|
||||
- **全量转码**:引擎读取 `cust.json` 的 `convert.dir` 清单(V2 对象数组 `{name, core, viaUmgr, dialect}`),对清单内 LS_ 功能整体转码,核心/柜面接口/SQL 方言随清单下发(契约见 `docs/转码配置格式契约.md`);
|
||||
- **全量转码**:引擎读取 `cust.json` 的 `convert.dir` 清单(V2 对象数组 `{name, core, viaUmgr, dialect}`),对清单内 LS_ 功能整体转码,核心/柜面接口/SQL 方言随清单下发(契约见 §7.5);
|
||||
- **按需转码**:`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);
|
||||
- **转码后联动**:任务成功后自动静默刷新代码检索索引,保证调用链路反映最新代码。
|
||||
@@ -461,7 +461,7 @@ flowchart TD
|
||||
|
||||
两种模式均**不包含核心文件、module 模块文件**。执行时 `buildArguments()` 组装引擎参数(含 `-m 2`),由 `MainWindow` 统一经 `PythonRunner` 启动引擎。
|
||||
|
||||
### 5.4 功能查询模块(FunctionSearchPage 基类 + UF20/UFT3 子页)
|
||||
### 5.4 功能查询模块(FunctionSearchPage 基类 + UF20/UFT3 子页 + UF20 & 内存表映射查询页)
|
||||
|
||||
**职责**:检索 UF20 / UFT3 功能元数据(依赖 `DataCache`),列:`函数名 / 英文名 / 功能号`;支持函数名/功能号字段切换、精确匹配开关与**多关键词批量查询**。UF20 页结果表支持多选,双击/右键一键加入转码工作台;UFT3 页为纯查询(不接入转码链路)。
|
||||
|
||||
@@ -504,6 +504,63 @@ sequenceDiagram
|
||||
|
||||
> **UFT3 功能查询**:界面与 UF20 版一致(含批量关键词查询),仅用于核对 UFT3 元数据,**双击/右键不加入转码清单**;代码检索中"原代码已支持"行的功能号前缀即来自 UFT3 元数据。
|
||||
|
||||
#### 5.4.3 UF20 & 内存表映射查询页(TableSearchPage)
|
||||
|
||||
**职责**:检索 UF20(2.0)表与内存表(UFT3)之间的映射关系,四列结果:`UF20表名 / UF20表中文名 / 内存表名 / 内存表中文名`;**双击记录行可添加映射到「数据映射 → 表替换」页**。不继承 `FunctionSearchPageBase`(结果结构为 4 列表信息,与 `FunctionInfo` 3 列函数信息不同),UI 风格(边距/搜索框/结果表/主题感知 tip)与功能查询页对齐。
|
||||
|
||||
**数据源三件套**:
|
||||
|
||||
| 列 | 来源 |
|
||||
| --- | --- |
|
||||
| UF20表名 / 内存表名 | `bin/uf2touft3/config/table_mapping.json`(独立映射文件,顶层键 `tableCompareUf2_Uf3`:key=UF20表名,value=内存表名;value 可为字符串(一对一)或字符串数组(一对多,拆为多条映射对,一个 UF20 表展示多行)),每次查询现读(文件小) |
|
||||
| UF20表中文名 | `uf20_cache.db` 的 `uf2_table`:`data` JSON 的 `cname` 字段 |
|
||||
| 内存表中文名 | `uft3_cache.db` 的 `uft3_table`:`data` JSON 的 `chineseName` 字段 |
|
||||
|
||||
**查询流程**(每关键词,支持多关键词 OR 并集,`splitKeywords` 与功能查询页同口径):
|
||||
|
||||
1. **映射命中**(key 或 value)→ 完整行:以 key 取 UF20 中文名、以 value 取内存表中文名;一对多映射(value 为数组)拆为多条记录展示;
|
||||
2. **映射未命中** → 双库单侧探测:命中 `uf2_table` 出单侧行(映射两列置空),命中 `uft3_table` 同理,两侧同时命中出两行;
|
||||
3. **去重**:映射整体行已覆盖的表名不再补单侧行(covered 集合),同一映射对不被多关键词重复输出(seenPairs 集合);
|
||||
4. 精确匹配为全等;模糊匹配为不区分大小写的包含。
|
||||
|
||||
**轻量数据访问**:两库 `data` 列为完整表定义 JSON(单行可达数十 KB),禁止整表搬运逐行解析——`DataCache` 新增 `getUf20TableNameMap()` / `getUft3TableNameMap()`,SQL 层 `json_extract(data, '$.cname' / '$.chineseName')` 只提取中文名,首次调用全量构建"表名→中文名"映射后**内存缓存**(懒加载,表数量远小于接口表,秒级内完成),元数据落库后随 `refreshFunctionCache()` 一并失效重建;构建失败不置有效、下次自动重试;`json_extract` 不可用时回退 `getAllRows` + C++ 逐行解析兜底。
|
||||
|
||||
**tip 反馈**(页面底部,不弹窗):默认提示"💡 输入 UF20 表名或内存表名进行查询,支持精确/模糊匹配;双击记录行可添加到「数据映射 → 表替换」";空输入提示输入表名;双库均为空提示"请先在「元数据更新」页面执行更新";无命中提示"未找到匹配的表";成功显示"已查询 X 条记录(其中 Y 个无映射关系,N 个表中文名缺失,M 个关键词无匹配)"——一对多映射按多条记录计;中文名缺失指映射里有该表但缓存库未收录(元数据更新未覆盖其来源工程,如 `table_mapping.json` 覆盖完整标准套件而本地仅更新了部分工程);`table_mapping.json` 读取失败时附加降级说明(仅展示数据库检索结果)。
|
||||
|
||||
#### 5.4.4 双击添加映射到表替换页
|
||||
|
||||
查询结果行**双击**即可将映射关系添加到「数据映射 → 表替换」页,跨页信号链路与 UF20 功能查询一键加入转码工作台同构:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户
|
||||
participant S as TableSearchPage(映射查询)
|
||||
participant M as MainWindow
|
||||
participant T as TableMappingPage(表替换)
|
||||
|
||||
U->>S: 双击结果行
|
||||
S->>S: 取第 1 列(UF20表名)/第 3 列(内存表名),<br/>任一为空即无完整映射关系,tip 警告
|
||||
S->>M: requestAddMapping(uf20Name, memName)
|
||||
M->>T: appendPairIfAbsent(uf20Name, memName)
|
||||
Note over T: trimmed 口径判重(与添加/收集同口径);<br/>已存在返回提示(含当前映射值,不覆盖);<br/>新增入模型置脏后立即落盘(自动保存)
|
||||
M->>S: onMappingAddResult(error)
|
||||
S->>U: tip 反馈:成功"已添加到表替换并自动保存" / 失败原因
|
||||
```
|
||||
|
||||
**要点:**
|
||||
|
||||
- **完整映射校验**:仅当该行 UF20 表名与内存表名均非空(即有完整映射关系)才可添加;单侧行(无映射)双击提示警告不入库;
|
||||
- **判重不覆盖**:UF20 表名在表替换中已存在时跳过,tip 注明当前映射值——与表替换页手动添加口径一致,避免隐式覆盖;
|
||||
- **自动保存语义**:`appendPairIfAbsent` 追加到模型并置 `m_dirty` 后立即调用 `saveToDisk()` 落盘(无弹窗,成功静默)——`onSave` 的弹窗壳与落盘核心分离,保存窗口(监控抑制)逻辑共用;自动保存失败时原因带回映射查询页 tip 展示;
|
||||
- **table_mapping.json 同步**:表替换页覆写基类落盘钩子 `onSavedToDisk()`——保存成功(含双击自动保存)后,以表替换模型为源与 `table_mapping.json` 的 `tableCompareUf2_Uf3` 对象逐成员对账:
|
||||
- **新增**:模型中存在、tm 中缺失的 key(且 value 非空)按原缩进/换行格式追加到对象末尾;
|
||||
- **修改**:tm 中为字符串值(一对一)且与模型 value 不同的条目就地更新为模型值;
|
||||
- **一对多数组跳过**:tm 中 value 为数组的条目(41 个)一律保留原文不覆盖——表替换是单值模型,覆盖会丢失其余映射;跳过数计入同步日志;
|
||||
- **删除暂不同步**:表替换删除条目仅作用于 cust.json(转码口径),tm 中同名条目保留(tm 是全量参考映射,含 328 个 cust 未维护的独有条目);空 value 也不同步;
|
||||
- **实现要点**:成员级文本解析(key 串/冒号/value 串或跨行数组,括号配对且跳过字符串字面量,记录每个成员原文起止),未变更成员与数组保持原文字节不变,仅替换/追加成员行后按原缩进与换行重建对象内部;写前整体重解析校验,任何结构异常放弃写入并记错误日志;同步结果记 info 日志(新增 N,更新 M,一对多数组跳过 X,空值跳过 Y);
|
||||
- 映射查询页每次查询现读该文件,同步后的新增/修改即时可查;
|
||||
- **页面持有**:`MainWindow` 新增 `m_tableMappingPage` 成员,页面创建 lambda 运行时解引用(构造时序上映射查询页先建、表替换页后建,两页构造完成后成员指针非空)。
|
||||
|
||||
### 5.5 代码检索模块(CodeSearchPage + CallChainAnalyzer)
|
||||
|
||||
**职责**:功能**调用链路查询**(非内容检索)——展示某功能的向上调用方(谁调用了它)与向下被调(它调用了谁),用于转码前评估影响范围、转码后核对结果。
|
||||
@@ -626,7 +683,8 @@ flowchart TD
|
||||
- **写闸门**:`saveDataset()` 全程持有 `m_writeGate` 写闸门;`clearCache()` 以 `tryLock` 探测在途落库任务——在途时仅重置内存状态并记录警告、跳过连接重置,避免关闭正在写入的连接(闸门在 `database()` 取连接之后获取,锁序安全无死锁,详见 §8.4);
|
||||
- **内存功能索引**:`refreshFunctionCache()` 将两库功能表加载至内存(`FunctionInfo{cname, eName, functionNo}`),支撑功能查询页即时检索;启动时 `MainWindow` 经 `warmupFunctionCacheAsync(db)` **异步预热**(后台线程构建内存索引,幂等:已就绪/在途跳过,详见 §8.6);
|
||||
- **检索 API**:`searchUF20Functions()` / `searchUFT3Functions()` 支持按中文名/英文名/功能号字段过滤,均有**单词与多词两个重载**——多词版(`QStringList` + `keywordsWithoutMatch` 出参)实现 OR 并集、按 `cname|functionNo` 去重与零命中统计,单词版内部委托多词版;两库共用匿名命名空间 `filterFunctionInfos()` 过滤实现——代码检索"按功能号检索"即经 `searchUFT3Functions(raw, "function_no", true)` 将功能号解析为函数英文名;
|
||||
- **数据集 API**:`datasetExists()` / `getAllRows()` / `getRowData()` 供功能查询页读取指定功能完整数据。
|
||||
- **数据集 API**:`datasetExists()` / `getAllRows()` / `getRowData()` 供功能查询页读取指定功能完整数据;
|
||||
- **表查询映射缓存**:`getUf20TableNameMap()` / `getUft3TableNameMap()` 返回"表名→中文名"全量轻量映射(SQL 层 `json_extract` 只取中文名字段,避免整表搬运大 JSON;`json_extract` 不可用时回退 `getAllRows` + 逐行解析),首次调用构建后内存缓存,随 `refreshFunctionCache()` 一并失效重建,供 UF20 & 内存表映射查询页使用(见 §5.4.3)。
|
||||
|
||||
### 6.2 LogManager(单例)
|
||||
|
||||
@@ -726,7 +784,7 @@ flowchart TD
|
||||
| `tableCompareUf2_Uf3` | UF20→UFT3 表名映射 | 全量/按需转码的表替换 |
|
||||
| `functionReplace` | 函数替换规则 | 转码的函数替换 |
|
||||
| `noChangeFullNameCode` | 字符串数组(功能函数全名清单) | 转码引擎对清单内功能函数名不做全名替换 |
|
||||
| `convert.dir` | 对象数组 `{name, core, viaUmgr, dialect}`(全量转码清单,V2 格式,见 `docs/转码配置格式契约.md`) | 全量转码页维护、引擎读取 |
|
||||
| `convert.dir` | 对象数组 `{name, core, viaUmgr, dialect}`(全量转码清单,V2 格式,见 §7.5) | 全量转码页维护、引擎读取 |
|
||||
| 其余键 | 引擎自身配置 | 原样透传 |
|
||||
|
||||
- 数据映射三页各自只读写所属顶层键(键名统一引用 `Constants::CustKeys`,见 §6.4),其余内容原样保留;
|
||||
@@ -758,6 +816,140 @@ flowchart TD
|
||||
| config.ini | `[projectPath]` | UFT30/UF20/UF20账户/清算项目环境路径(`uft30` / `uf20` / `ufAcct20` / `UftdbSett`)、转码生成路径;保存时同步维护 `uft30pub = <UFT30路径>\upub\dev_codes` |
|
||||
| change_code.ini | `[log]` | 日志级别/开关,LogManager 启动时读取 |
|
||||
|
||||
### 7.5 转码配置格式契约(cust.json / cust_nonls.json)
|
||||
|
||||
> 版本:1.0(2026-09-16)
|
||||
> 变更发起方:转码工具 UI(Uft30ChangeCode,Qt 客户端)
|
||||
> 契约接收方:转码引擎(uf2touft3)
|
||||
> 状态:已评审确认,待引擎侧实现联调
|
||||
|
||||
#### 1. 变更背景
|
||||
|
||||
全量转码页新增【核心】【是否柜面接口】两列,按需转码页新增【db模式】列(支持 SQL 的 db/mdb 语法转换)。相应地,两份配置文件的 `convert.dir` 节点格式升级,引擎需按本契约完成解析与转码逻辑适配。
|
||||
|
||||
#### 2. cust.json(全量转码清单)
|
||||
|
||||
##### 2.1 格式变更
|
||||
|
||||
```jsonc
|
||||
// 旧格式(V1):字符串数组
|
||||
"convert": {
|
||||
"dir": [
|
||||
"LS_证券参数_股票名单增加.service_design"
|
||||
],
|
||||
"ext": [ ".service_design", ".function_design", ... ]
|
||||
}
|
||||
|
||||
// 新格式(V2):对象数组
|
||||
"convert": {
|
||||
"dir": [
|
||||
{
|
||||
"name": "LS_债券质押协议回购_初始交易委托.service_design",
|
||||
"core": "ucbp",
|
||||
"viaUmgr": true,
|
||||
"dialect": "db"
|
||||
}
|
||||
],
|
||||
"ext": [ ".service_design", ".function_design", ... ]
|
||||
}
|
||||
```
|
||||
|
||||
##### 2.2 字段定义
|
||||
|
||||
| 字段 | 类型 | 必填 | 语义 | 合法取值 |
|
||||
|---|---|---|---|---|
|
||||
| `name` | string | 是 | 功能短名 + 设计器扩展名(后缀由 UI 按清单扩展名拼接,当前固定 `.service_design`) | 非空字符串 |
|
||||
| `core` | string | 是 | 目标核心 | `"ucbp"` \| `"uses"` \| `"uarg"` \| `"usms"` |
|
||||
| `viaUmgr` | bool | 是 | 是否柜面接口 | `true` \| `false` |
|
||||
| `dialect` | string | 是 | SQL 语法方言,由 `core` 派生,UI 不提供独立修改入口 | `"mdb"` \| `"db"` |
|
||||
|
||||
**dialect 派生规则(UI 侧保证,引擎可据此校验):**
|
||||
|
||||
| core | dialect |
|
||||
|---|---|
|
||||
| `ucbp` | `mdb` |
|
||||
| `uses` | `mdb` |
|
||||
| `uarg` | `db` |
|
||||
| `usms` | `db` |
|
||||
|
||||
##### 2.3 引擎解析要求
|
||||
|
||||
1. **双格式兼容**:`dir` 元素为字符串时按旧格式处理(无 core/viaUmgr/dialect,行为与现有引擎一致);为对象时按新格式处理。两者可混合出现的可能性极低,但解析器不应因此崩溃。
|
||||
2. **字段兜底建议**:对象缺字段时,建议按 UI 默认值兜底并记录警告日志——`core="ucbp"`、`viaUmgr=false`、`dialect` 按 2.2 派生表由 core 推导。
|
||||
3. **非法值处理**:`core` 不在枚举内、`dialect` 与派生规则矛盾时,记录警告并按 `dialect` 字段实际值执行(以文件为准,不做强制纠正),或按团队约定明确拒绝该条目——**请引擎侧反馈选定哪种策略**。
|
||||
4. `viaUmgr=true` 时柜面接口的转码行为差异由引擎侧定义并实现。
|
||||
|
||||
#### 3. cust_nonls.json(按需转码清单)
|
||||
|
||||
##### 3.1 格式变更
|
||||
|
||||
```jsonc
|
||||
// 旧格式(V1):功能名 → 数值
|
||||
"convert": {
|
||||
"dir": {
|
||||
"*": -1,
|
||||
"AS_证券日终(用户)_证券信息更新": 0
|
||||
},
|
||||
"ext": [ ".service_design", ... ]
|
||||
}
|
||||
|
||||
// 新格式(V2):清单条目为对象;引擎兜底键 "*" 保持数值原样
|
||||
"convert": {
|
||||
"dir": {
|
||||
"AS_证券参数_交易风险提示证券代码批量导入": { "depth": 0, "dialect": "db" },
|
||||
"*": -1
|
||||
},
|
||||
"ext": [ ".service_design", ... ]
|
||||
}
|
||||
```
|
||||
|
||||
##### 3.2 字段定义
|
||||
|
||||
| 字段 | 类型 | 必填 | 语义 | 合法取值 |
|
||||
|---|---|---|---|---|
|
||||
| `depth` | int | 是 | 递归深度标志,语义与旧格式数值完全一致:`0`=否(单文件转码)、`-1`=是(递归转码) | `0` \| `-1` |
|
||||
| `dialect` | string | 是 | SQL 语法方言,对应 UI【db模式】列:选"是"→`db`,选"否"→`mdb` | `"db"` \| `"mdb"` |
|
||||
|
||||
##### 3.3 特殊键与解析要求
|
||||
|
||||
1. **`"*"` 兜底键**:保持旧格式数值(`0`/`-1`),**不升级为对象、不携带 dialect**。引擎对非清单功能的默认行为不变,UI 侧原样透传、不展示、不修改。
|
||||
2. **双格式兼容**:`dir` 条目值为数值时按旧格式处理(dialect 默认 `mdb`);为对象时按新格式解析。
|
||||
3. **字段兜底建议**:对象缺 `depth` 按 `0`,缺 `dialect` 按 `mdb`,均记警告日志。
|
||||
4. **旧格式数组兼容**:更早期版本 `dir` 为字符串数组(无递归标志),引擎若仍有该格式在途配置,维持现有兼容逻辑即可。
|
||||
|
||||
#### 4. UI 侧写入保证(引擎可信赖的前提)
|
||||
|
||||
| 保证项 | 说明 |
|
||||
|---|---|
|
||||
| 原子写入 | 两份配置均经 `QSaveFile` 原子提交,不会出现写一半的截断文件 |
|
||||
| JSON 合法性 | cust.json 文本级替换写回前做整体 JSON 解析校验,非法即中止保存 |
|
||||
| 字段完整性 | V2 对象条目四字段/两字段总是齐全,不输出缺字段条目(兜底逻辑仅为防御外部手改) |
|
||||
| `ext` 节点 | 不变,引擎按现状使用 |
|
||||
| 顶层键顺序 | cust.json 其余顶层键与格式不被重排(文本级区间替换) |
|
||||
|
||||
#### 5. 版本与联调约定
|
||||
|
||||
1. **不兼容变更**:V2 格式对旧引擎不可解析(全量转码清单会为空)。**UI 与引擎必须同版本发布**,禁止单独升级任一侧。
|
||||
2. **升级方向兼容**:新引擎需兼容读 V1(存量用户配置),新 UI 兼容读 V1/V2。
|
||||
3. **回退方案**:若需回退到旧 UI,旧 UI 读 V2 配置会得到空清单,需手工将配置改回 V1 或删除配置重新生成。
|
||||
4. **待引擎侧反馈**:
|
||||
- 2.3-3 非法值处理策略(告警放行 or 拒绝条目);
|
||||
- `viaUmgr=true` 柜面接口转码的具体行为定义;
|
||||
- `dialect` 驱动 SQL 语法转换(mdb/db)的实现范围与差异点清单。
|
||||
|
||||
#### 6. 格式速查(供引擎实现对照)
|
||||
|
||||
```
|
||||
cust.json convert.dir : V1 string[] → V2 {name, core, viaUmgr, dialect}[]
|
||||
core 枚举 : ucbp | uses | uarg | usms
|
||||
dialect 派生 : ucbp/uses→mdb ; uarg/usms→db
|
||||
|
||||
cust_nonls.json convert.dir : V1 {name: 0|-1, "*": -1}
|
||||
→ V2 {name: {depth: 0|-1, dialect: "db"|"mdb"}, "*": -1}
|
||||
depth 语义 : 0=单文件转码 ; -1=递归转码(与 V1 数值一致)
|
||||
"*" 键 : 保持数值,恒不升级为对象
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 关键设计决策与问题记录
|
||||
@@ -825,7 +1017,7 @@ MainWindow 启动即校验 `bin/uf2touft3/uf2touft3.exe` 是否存在:缺失
|
||||
| --- | --- |
|
||||
| 主窗口与导航、引擎调度 | `src/mainwindow/` |
|
||||
| 业务转码 | `src/pages/businessconvert/`(容器)+ `src/pages/batchconvert/`(全量)+ `src/pages/nonlsconvert/`(按需) |
|
||||
| 功能查询 | `src/pages/functionsearch/`(UF20 / UFT3 双模式) |
|
||||
| 功能查询 | `src/pages/functionsearch/`(UF20 / UFT3 双模式 + UF20 & 内存表映射查询) |
|
||||
| 代码检索 | `src/pages/codesearch/`(含 CallChainAnalyzer) |
|
||||
| 数据映射 | `src/pages/datamapping/`(TableMappingPage / FunctionMappingPage / NoChangeFullNamePage) |
|
||||
| 元数据更新 | `src/pages/metadataupdate/`(页面)+ `src/metadataupdate/`(解析器组) |
|
||||
|
||||
Reference in New Issue
Block a user