Compare commits
No commits in common. "main" and "master" have entirely different histories.
|
|
@ -5,17 +5,9 @@
|
||||||
!python_bindings/**
|
!python_bindings/**
|
||||||
!src/
|
!src/
|
||||||
!src/**
|
!src/**
|
||||||
!help/
|
|
||||||
!help/**
|
|
||||||
!resources/
|
|
||||||
!resources/**
|
|
||||||
!*.bat
|
!*.bat
|
||||||
!*.rc
|
!*.rc
|
||||||
!*.prp
|
!*.prp
|
||||||
!*.cpp
|
!*.cpp
|
||||||
!*.qrc
|
!*.qrc
|
||||||
!*.h
|
|
||||||
!*.pro
|
|
||||||
!*.md
|
|
||||||
!.gitignore
|
!.gitignore
|
||||||
!.gitkeep
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
# 图标设置说明
|
|
||||||
|
|
||||||
## 已完成配置
|
|
||||||
|
|
||||||
1. **应用程序窗口图标** - 已设置为 `resources/icons/转码工具.svg`
|
|
||||||
2. **资源文件** - 图标已添加到 `resources.qrc`
|
|
||||||
|
|
||||||
## Windows 可执行程序图标(可选)
|
|
||||||
|
|
||||||
如需设置 Windows 可执行文件的图标(任务栏、文件管理器显示的图标),需要:
|
|
||||||
|
|
||||||
### 方法 1:使用在线工具转换
|
|
||||||
1. 将 `resources/images/转码工具.png` 转换为 `.ico` 格式
|
|
||||||
2. 推荐尺寸:包含 16x16, 32x32, 48x48, 256x256 等多种尺寸
|
|
||||||
3. 保存为 `app.ico` 并放在项目根目录
|
|
||||||
4. `app.rc` 已配置引用 `app.ico`
|
|
||||||
|
|
||||||
### 方法 2:使用 ImageMagick 转换
|
|
||||||
```bash
|
|
||||||
magick convert 转码工具.png -define icon:auto-resize=256,128,96,64,48,32,16 app.ico
|
|
||||||
```
|
|
||||||
|
|
||||||
### 重新编译
|
|
||||||
设置好图标后重新编译项目即可。
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
QT += core gui widgets sql
|
|
||||||
|
|
||||||
TARGET = Uft30ChangeCode
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
DEFINES += QT_DEPRECATED_WARNINGS
|
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
|
||||||
src/mainwindow/mainwindow.cpp \
|
|
||||||
src/pythonrunner/PythonRunner.cpp \
|
|
||||||
src/pages/about/aboutdialog.cpp \
|
|
||||||
src/pages/batchconvert/batchconvertpage.cpp \
|
|
||||||
src/pages/functionsearch/functionsearchpage.cpp \
|
|
||||||
src/pages/functionsearch/uf20functionsearchpage.cpp \
|
|
||||||
src/pages/functionsearch/uft3functionsearchpage.cpp \
|
|
||||||
src/components/elasearchedit.cpp \
|
|
||||||
src/components/interdialog.cpp \
|
|
||||||
src/pages/help/helpdocpage.cpp \
|
|
||||||
src/pages/settings/settingspage.cpp \
|
|
||||||
src/pages/metadatupdate/metadatupdatepage.cpp \
|
|
||||||
src/metadataupdate/filedb.cpp \
|
|
||||||
src/metadataupdate/uf2interface.cpp \
|
|
||||||
src/metadataupdate/uft3interface.cpp \
|
|
||||||
src/metadataupdate/metadataprocessor.cpp \
|
|
||||||
src/metadataupdate/uf2datatype.cpp \
|
|
||||||
src/metadataupdate/uf2stdfields.cpp \
|
|
||||||
src/metadataupdate/uf2errnumber.cpp \
|
|
||||||
src/metadataupdate/uft3datatype.cpp \
|
|
||||||
src/metadataupdate/uft3stdfields.cpp \
|
|
||||||
src/metadataupdate/uft3table.cpp \
|
|
||||||
src/utils/datacache.cpp \
|
|
||||||
src/utils/uf2configreader.cpp \
|
|
||||||
src/utils/uft3configreader.cpp \
|
|
||||||
src/utils/logmanager.cpp \
|
|
||||||
src/utils/configmanager.cpp \
|
|
||||||
src/utils/version.cpp
|
|
||||||
|
|
||||||
HEADERS += src/mainwindow/mainwindow.h \
|
|
||||||
src/pythonrunner/PythonRunner.h \
|
|
||||||
src/pages/about/aboutdialog.h \
|
|
||||||
src/pages/batchconvert/batchconvertpage.h \
|
|
||||||
src/pages/functionsearch/functionsearchpage.h \
|
|
||||||
src/pages/functionsearch/uf20functionsearchpage.h \
|
|
||||||
src/pages/functionsearch/uft3functionsearchpage.h \
|
|
||||||
src/components/elasearchedit.h \
|
|
||||||
src/components/interdialog.h \
|
|
||||||
src/pages/help/helpdocpage.h \
|
|
||||||
src/pages/settings/settingspage.h \
|
|
||||||
src/pages/metadatupdate/metadatupdatepage.h \
|
|
||||||
src/metadataupdate/filedb.h \
|
|
||||||
src/metadataupdate/uf2interface.h \
|
|
||||||
src/metadataupdate/uft3interface.h \
|
|
||||||
src/metadataupdate/metadataprocessor.h \
|
|
||||||
src/metadataupdate/uf2datatype.h \
|
|
||||||
src/metadataupdate/uf2stdfields.h \
|
|
||||||
src/metadataupdate/uf2errnumber.h \
|
|
||||||
src/metadataupdate/uft3datatype.h \
|
|
||||||
src/metadataupdate/uft3stdfields.h \
|
|
||||||
src/metadataupdate/uft3table.h \
|
|
||||||
src/utils/datacache.h \
|
|
||||||
src/utils/uf2configreader.h \
|
|
||||||
src/utils/uft3configreader.h \
|
|
||||||
src/utils/logmanager.h \
|
|
||||||
src/utils/configmanager.h \
|
|
||||||
src/utils/version.h
|
|
||||||
|
|
||||||
RESOURCES += resources.qrc
|
|
||||||
|
|
||||||
CONFIG += c++17
|
|
||||||
CONFIG += debug_and_release
|
|
||||||
|
|
||||||
QMAKE_CXXFLAGS += -Wall -Wextra
|
|
||||||
QMAKE_LFLAGS += -fno-use-linker-plugin
|
|
||||||
|
|
||||||
INCLUDEPATH += src
|
|
||||||
INCLUDEPATH += 3rd/ElaWidgetTools/include
|
|
||||||
|
|
||||||
win32 {
|
|
||||||
LIBS += -L$$PWD/3rd/ElaWidgetTools/lib -lElaWidgetTools
|
|
||||||
LIBS += -ld3d11 -ldxgi
|
|
||||||
RC_FILE = app.rc
|
|
||||||
}
|
|
||||||
|
|
||||||
DESTDIR = $$PWD/bin
|
|
||||||
OBJECTS_DIR = $$PWD/build
|
|
||||||
MOC_DIR = $$PWD/build
|
|
||||||
RCC_DIR = $$PWD/build
|
|
||||||
|
|
||||||
|
|
||||||
2
app.rc
|
|
@ -1 +1 @@
|
||||||
IDI_ICON1 ICON DISCARDABLE "resources/images/ChangeCode.ico"
|
IDI_ICON1 ICON DISCARDABLE "app.ico"
|
||||||
|
|
@ -66,8 +66,8 @@ echo [OK] qmake done
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
REM Compile
|
REM Compile
|
||||||
echo [4/4] Compiling Release version...
|
echo [4/4] Compiling Debug version...
|
||||||
mingw32-make release
|
mingw32-make debug
|
||||||
if errorlevel 1 (
|
if errorlevel 1 (
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: Compilation failed
|
echo ERROR: Compilation failed
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# 默认忽略的文件
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Uft30ChangeCodeHelp
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectRootManager">
|
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/help.iml" filepath="$PROJECT_DIR$/help.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# 默认忽略的文件
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/Writerside.iml" filepath="$PROJECT_DIR$/.idea/Writerside.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE categories
|
|
||||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/categories.dtd">
|
|
||||||
<categories>
|
|
||||||
<category id="wrs" name="Writerside documentation" order="1"/>
|
|
||||||
</categories>
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE buildprofiles SYSTEM "https://resources.jetbrains.com/writerside/1.0/build-profiles.dtd">
|
|
||||||
<buildprofiles xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/build-profiles.xsd"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
|
|
||||||
<variables>
|
|
||||||
<custom-favicons>ChangeCode.png</custom-favicons>
|
|
||||||
</variables>
|
|
||||||
|
|
||||||
</buildprofiles>
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE terms SYSTEM "https://resources.jetbrains.com/writerside/1.0/glossary.dtd">
|
|
||||||
<terms>
|
|
||||||
<term name="foo">
|
|
||||||
Description of what "foo" is.
|
|
||||||
</term>
|
|
||||||
</terms>
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE instance-profile
|
|
||||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/product-profile.dtd">
|
|
||||||
|
|
||||||
<instance-profile id="hi"
|
|
||||||
name="Uft30ChangeCode"
|
|
||||||
start-page="Uft30ChangeCode.md">
|
|
||||||
<toc-element topic="Uft30ChangeCode.md">
|
|
||||||
<toc-element topic="设置.md"/>
|
|
||||||
</toc-element>
|
|
||||||
<toc-element topic="功能转码.md">
|
|
||||||
<toc-element topic="业务转码.md"/>
|
|
||||||
</toc-element>
|
|
||||||
<toc-element topic="功能查询.md">
|
|
||||||
<toc-element topic="UFT3功能查询.md"/>
|
|
||||||
<toc-element topic="UF20功能查询.md"/>
|
|
||||||
</toc-element>
|
|
||||||
<toc-element topic="元数据更新.md"/>
|
|
||||||
<toc-element topic="更新记录.md">
|
|
||||||
<toc-element topic="update-1-0-0.md"/>
|
|
||||||
</toc-element>
|
|
||||||
<toc-element topic="下载.md"/>
|
|
||||||
</instance-profile>
|
|
||||||
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
|
@ -1,13 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE rules SYSTEM "https://resources.jetbrains.com/writerside/1.0/redirection-rules.dtd">
|
|
||||||
<rules>
|
|
||||||
<!-- format is as follows
|
|
||||||
<rule id="<unique id>">
|
|
||||||
<accepts>page.html</accepts>
|
|
||||||
</rule>
|
|
||||||
-->
|
|
||||||
<rule id="42b8a0d">
|
|
||||||
<description>Created after removal of "Empty MD Topic" from Uft30ChangeCode</description>
|
|
||||||
<accepts>Empty-MD-Topic.html</accepts>
|
|
||||||
</rule>
|
|
||||||
</rules>
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
# UF20功能查询
|
|
||||||
|
|
||||||
查询UFT3系统中的函数信息。
|
|
||||||
|
|
||||||
## 查询条件
|
|
||||||
从下拉框选择查询(功能名称、功能编号),输入框输入查询关键词,点击"Aa"切换精确/模糊匹配模式,点击放大镜图标或按回车执行查询
|
|
||||||
|
|
||||||
- 功能名称
|
|
||||||
<img src="功能名称查询.png" alt="功能名称查询"/>
|
|
||||||
|
|
||||||
- 功能编号
|
|
||||||
<img src="模糊查询uf20.png" alt="模糊查询uf20"/>
|
|
||||||
<img src="精准查询uf20.png" alt="精准查询uf20"/>
|
|
||||||
|
|
||||||
## 双击添加
|
|
||||||
双击选中行添加转码业务,只支持LS功能添加
|
|
||||||
<img src="双击添加.png" alt="双击添加"/>
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
# UFT3功能查询
|
|
||||||
|
|
||||||
查询UFT3系统中的函数信息。
|
|
||||||
|
|
||||||
## 查询条件
|
|
||||||
从下拉框选择查询(功能名称、功能编号),输入框输入查询关键词,点击"Aa"切换精确/模糊匹配模式,点击放大镜图标或按回车执行查询
|
|
||||||
|
|
||||||
- 功能名称
|
|
||||||
<img src="功能名称查询uft3.png" alt="功能名称查询uft3"/>
|
|
||||||
- 功能编号
|
|
||||||
<img src="模糊查询UFT3.png" alt="模糊查询UFT3"/>
|
|
||||||
<img src="精准查询uft3.png" alt="精准查询uft3"/>
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# Uft30ChangeCode
|
|
||||||
|
|
||||||
提供UFT30元数据、UF20公共资源搜索功能,支持业务转码
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
# 1.0.0
|
|
||||||
|
|
||||||
1.支持业务转码
|
|
||||||
|
|
||||||
2.支持代码uf20、uft3功能查找
|
|
||||||
|
|
||||||
3.支持帮助菜单和在线帮助文档
|
|
||||||
|
|
||||||
4.支持接口元数据更新
|
|
||||||
|
|
||||||
5.设置菜单UFT30项目环境路径、UF20项目环境路径、UF20账户环境路径、转码生成路径、支持弹窗选择目录。
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# 下载
|
|
||||||
|
|
||||||
## 全量更新
|
|
||||||
下载全量包,解压即用。
|
|
||||||
|
|
||||||
> 1.0.0版本是基础版本,包含所需功能,如果是第一次下载,请选择全量包。
|
|
||||||
{style="note"}
|
|
||||||
## 增量更新
|
|
||||||
下载增量包,解压后替换原文件即可
|
|
||||||
> 1.0.0版本是基础版本,如若要从旧版升级到1.0.0及以上版本,可以选择增量版本下载,并将旧版根目录下的uf2touft3和当前目录替换覆盖到新版根目录。
|
|
||||||
{style="note"}
|
|
||||||
|
|
||||||
## 下载
|
|
||||||
|
|
||||||
| 版本 | 更新日期 | 全量包 | 增量包 |
|
|
||||||
|------|------------|---------------------------------------------------------------------------------|-----|
|
|
||||||
| 1.0.0 | 2026-06-01 | [Uft30ChangeCode-1.0.0.zip](http://10.20.163.105:6045/download/uft3changecode/Uft30ChangeCode-1.0.0.zip) | |
|
|
||||||
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
# 业务转码
|
|
||||||
|
|
||||||
将UF20函数转换为UFT3函数格式的核心功能。
|
|
||||||
|
|
||||||
## 功能列表管理
|
|
||||||
|
|
||||||
点击"添加"按钮,输入函数名添加到转码列表
|
|
||||||
<img src="添加函数.png" alt="添加函数"/>
|
|
||||||
|
|
||||||
点击表格操作按钮可编辑函数名,如下:
|
|
||||||
<img src="编辑.png" alt="编辑"/>
|
|
||||||
|
|
||||||
选中行后点击"删除"移除函数、点击"清空"清空所有函数,如下:
|
|
||||||
<img src="删除.png" alt="删除"/>
|
|
||||||
|
|
||||||
## 配置文件同步
|
|
||||||
|
|
||||||
- 自动读取 uf2touft3/cust.json 配置
|
|
||||||
- 配置文件外部修改时自动刷新列表
|
|
||||||
|
|
||||||
## 转换操作
|
|
||||||
|
|
||||||
点击"开始转换"启动转换任务,转换过程中可查看进度条和状态信息,如下:
|
|
||||||
<img src="转码.png" alt="转码"/>
|
|
||||||
|
|
||||||
点击"停止转换"中止当前任务,如下:
|
|
||||||
<img src="停止转码.png" alt="停止转码"/>
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
# 元数据更新
|
|
||||||
|
|
||||||
更新UF20和UFT3系统的元数据配置。
|
|
||||||
|
|
||||||
## 项目配置
|
|
||||||
需要先配置UFT30项目路径和UF20项目路径。
|
|
||||||
|
|
||||||
在设置-首选项页面,配置UFT30项目路径,例如:
|
|
||||||
``在设置-首选项页面,配置UFT30项目路径,例如:``
|
|
||||||
<img src="UFT3项目环境路径.png" alt="UFT3项目环境路径"/>
|
|
||||||
|
|
||||||
在设置-首选项页面,配置UF20项目路径,例如:
|
|
||||||
``E:\05.code\04.SVN\secu\dep1\hstrade20\trunk\Sources\DevCodes\经纪业务运营平台V21``
|
|
||||||
<img src="UF20项目环境路径.png" alt="UF20项目环境路径"/>
|
|
||||||
|
|
||||||
## UFT3元数据
|
|
||||||
在 元数据更新 页面,选择更新范围(标准字段、接口数据等)并点击更新UFT3按钮完成元数据更新。
|
|
||||||
<img src="UFT3元数据.png" alt="UFT3元数据"/>
|
|
||||||
**备注:接口数据更新比较久**
|
|
||||||
|
|
||||||
## 更新UF20元数据
|
|
||||||
在 元数据更新 页面,选择更新范围(标准字段、标准组件等)并点击更新UF2按钮完成公共资源更新
|
|
||||||
<img src="UF20元数据.png" alt="UF20元数据"/>
|
|
||||||
**备注:接口数据更新比较久**
|
|
||||||
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# 功能查询
|
|
||||||
|
|
||||||
## 快速跳转
|
|
||||||
[UFT3功能查询](http://10.20.163.105:6045/uft3changecode/UFT3功能查询.html)
|
|
||||||
|
|
||||||
[UF20功能查询](http://10.20.163.105:6045/uft3changecode/UF20功能查询.html)
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
# 功能转码
|
|
||||||
提供UFT3业务转码功能,将uf20代码转成UFT3代码
|
|
||||||
|
|
||||||
## 项目配置
|
|
||||||
在使用UFT3功能转码前,需要先配置UFT30项目路径,并更新UFT3、UF20元数据
|
|
||||||
|
|
||||||
1.配置项目路径
|
|
||||||
- UFT3项目环境路径
|
|
||||||
|
|
||||||
在设置-首选项页面,配置UFT30项目路径,转码使用,例如:
|
|
||||||
``E:\05.code\03.GIT\feature_ses``
|
|
||||||
<img src="UFT3项目环境路径.png" alt="UFT3项目环境路径"/>
|
|
||||||
|
|
||||||
- UF20项目环境路径
|
|
||||||
|
|
||||||
在设置-首选项页面,UF20项目环境路径, 转码需要读取相关的文件, 例如:
|
|
||||||
``E:\05.code\04.SVN\secu\dep1\hstrade20\trunk\Sources\DevCodes\经纪业务运营平台V21``
|
|
||||||
<img src="UF20项目环境路径.png" alt="UF20项目环境路径"/>
|
|
||||||
|
|
||||||
- UF20账户环境路径
|
|
||||||
|
|
||||||
在设置-首选项页面,配置UF20账户环境路径, 转码需要读取账户相关的文件,例如:
|
|
||||||
``E:\05.code\04.SVN\secu\dep1\hstrade20\trunk\Sources\DevCodes_Acct1\客户账户管理系统V22``
|
|
||||||
<img src="UF20账户环境路径.png" alt="UF20账户环境路径"/>
|
|
||||||
- 转码生成路径
|
|
||||||
|
|
||||||
在设置-首选项页面,配置转码生成路径, 用于存放生成的转码文件, 例如:
|
|
||||||
``F:\07.tools\01.hstools\Uft30ChangeCode\bin\uf2touft3\change_code``
|
|
||||||
<img src="转码生成路径.png" alt="转码生成路径"/>
|
|
||||||
|
|
||||||
## 快速跳转
|
|
||||||
[业务转码](http://10.20.163.105:6045/uft3changecode/业务转码.html)
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# 更新记录
|
|
||||||
|
|
||||||
Start typing here...
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
# 设置
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## UFT3项目环境路径
|
|
||||||
|
|
||||||
在设置-首选项页面,配置UFT30项目路径,转码使用,例如:
|
|
||||||
``E:\05.code\03.GIT\feature_ses``
|
|
||||||
|
|
||||||
## UF20项目环境路径 {id="uf20_1"}
|
|
||||||
|
|
||||||
在设置-首选项页面,UF20项目环境路径, 转码需要读取相关的文件, 例如:
|
|
||||||
``E:\05.code\04.SVN\secu\dep1\hstrade20\trunk\Sources\DevCodes\经纪业务运营平台V21``
|
|
||||||
|
|
||||||
## UF20账户环境路径
|
|
||||||
|
|
||||||
在设置-首选项页面,配置UF20账户环境路径, 转码需要读取账户相关的文件,例如:
|
|
||||||
``E:\05.code\04.SVN\secu\dep1\hstrade20\trunk\Sources\DevCodes_Acct1\客户账户管理系统V22``
|
|
||||||
|
|
||||||
## 转码生成路径
|
|
||||||
|
|
||||||
在设置-首选项页面,配置转码生成路径, 用于存放生成的转码文件, 例如:
|
|
||||||
``F:\07.tools\01.hstools\Uft30ChangeCode\bin\uf2touft3\change_code``
|
|
||||||
|
|
||||||
## 主题切换
|
|
||||||
包含日间模式和夜间模式。
|
|
||||||
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE vars SYSTEM "https://resources.jetbrains.com/writerside/1.0/vars.dtd">
|
|
||||||
<vars>
|
|
||||||
<var name="product" value="Writerside"/>
|
|
||||||
</vars>
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE ihp SYSTEM "https://resources.jetbrains.com/writerside/1.0/ihp.dtd">
|
|
||||||
|
|
||||||
<ihp version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/writerside-cfg.xsd">
|
|
||||||
<topics dir="topics"/>
|
|
||||||
<images dir="images" web-path="images"/>
|
|
||||||
<categories src="c.list"/>
|
|
||||||
<vars src="v.list"/>
|
|
||||||
<instance src="hi.tree"/>
|
|
||||||
</ihp>
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
server {
|
|
||||||
listen 6045;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
location /uft3changecode/ {
|
|
||||||
alias /home/taoc/uft30help/uft3changecode/;
|
|
||||||
index index.html;
|
|
||||||
try_files $uri $uri/ /uft3changecode/index.html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
worker_processes 1;
|
|
||||||
pid /home/taoc/nginx/logs/nginx.pid;
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
include /home/taoc/nginx/conf/mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
|
|
||||||
access_log /home/taoc/nginx/logs/help_access.log;
|
|
||||||
error_log /home/taoc/nginx/logs/help_error.log;
|
|
||||||
|
|
||||||
sendfile on;
|
|
||||||
keepalive_timeout 65;
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 6045;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
root /home/taoc/uft30help/html/;
|
|
||||||
index index.html index.htm;
|
|
||||||
|
|
||||||
location /uft3changecode/ {
|
|
||||||
index index.html index.htm;
|
|
||||||
try_files $uri $uri/ /uft3changecode/index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
|
||||||
location = /50x.html {
|
|
||||||
root html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "=== Force Restart Help Documentation Server ==="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "1. Killing all nginx processes..."
|
|
||||||
pkill -f nginx 2>/dev/null || true
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
echo "2. Checking for remaining nginx processes..."
|
|
||||||
if pgrep nginx > /dev/null; then
|
|
||||||
echo " Force killing remaining nginx processes..."
|
|
||||||
pkill -9 nginx 2>/dev/null || true
|
|
||||||
sleep 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "3. Checking port 6045..."
|
|
||||||
lsof -i :6045 2>/dev/null || echo " Port 6045 is free"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "4. Starting fresh nginx instance..."
|
|
||||||
|
|
||||||
NGINX_BIN="/home/taoc/nginx/sbin/nginx"
|
|
||||||
HELP_DOCS_DIR="/home/taoc/uft30help/"
|
|
||||||
CONF_FILE="$HELP_DOCS_DIR/workspace/nginx.conf"
|
|
||||||
|
|
||||||
if [ ! -f "$CONF_FILE" ]; then
|
|
||||||
echo " Copying nginx configuration..."
|
|
||||||
cp "$(dirname "$0")/nginx.conf" "$CONF_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "$HELP_DOCS_DIR/workspace/help.conf" ]; then
|
|
||||||
echo " Copying server configuration..."
|
|
||||||
cp "$(dirname "$0")/help.conf" "$HELP_DOCS_DIR/workspace/help.conf"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "$HELP_DOCS_DIR/uft3changecode/index.html" ]; then
|
|
||||||
echo " Creating default index.html..."
|
|
||||||
cat > "$HELP_DOCS_DIR/uft3changecode/index.html" << 'EOF'
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>UFT30ChangeCode Help</title>
|
|
||||||
<style>
|
|
||||||
body { font-family: Arial, sans-serif; text-align: center; padding: 50px; background: #f5f5f5; }
|
|
||||||
.container { background: white; padding: 40px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); display: inline-block; }
|
|
||||||
.logo { font-size: 64px; margin-bottom: 20px; }
|
|
||||||
h1 { color: #667eea; margin: 0; }
|
|
||||||
.subtitle { color: #666; margin-top: 10px; }
|
|
||||||
.path { background: #f0f0f0; padding: 10px 20px; border-radius: 5px; margin-top: 20px; font-family: monospace; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="logo">📖</div>
|
|
||||||
<h1>UFT30ChangeCode Help</h1>
|
|
||||||
<p class="subtitle">Help Documentation Server</p>
|
|
||||||
<div class="path">Path: /uft3changecode/</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "5. Testing configuration..."
|
|
||||||
"$NGINX_BIN" -t -c "$CONF_FILE"
|
|
||||||
|
|
||||||
echo "6. Starting nginx..."
|
|
||||||
"$NGINX_BIN" -c "$CONF_FILE"
|
|
||||||
|
|
||||||
sleep 2
|
|
||||||
echo ""
|
|
||||||
echo "=== Server Status ==="
|
|
||||||
if pgrep nginx > /dev/null; then
|
|
||||||
SERVER_IP=$(ip addr show | grep inet | grep -v '127.0.0.1' | grep -v '::1' | head -1 | awk '{print $2}' | cut -d'/' -f1)
|
|
||||||
echo "✅ Server started successfully!"
|
|
||||||
echo ""
|
|
||||||
echo "Access URLs:"
|
|
||||||
echo " Local: http://localhost:6045/uft3changecode/"
|
|
||||||
if [ -n "$SERVER_IP" ]; then
|
|
||||||
echo " Remote: http://$SERVER_IP:6045/uft3changecode/"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
echo "Verify with:"
|
|
||||||
echo " curl http://localhost:6045/uft3changecode/"
|
|
||||||
else
|
|
||||||
echo "❌ Failed to start server"
|
|
||||||
echo "Check error log: /home/taoc/uft30help/workspace/logs/help_error.log"
|
|
||||||
fi
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
NGINX_BIN="/home/taoc/nginx/sbin/nginx"
|
|
||||||
CONF_DIR="/home/taoc/uft30help/workspace"
|
|
||||||
HTML_DIR="/home/taoc/uft30help/html/uft3changecode"
|
|
||||||
CONF_FILE="$CONF_DIR/nginx.conf"
|
|
||||||
|
|
||||||
echo "=== Starting Help Documentation Server (Port 6045) ==="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "1. Checking directories..."
|
|
||||||
if [ ! -d "$CONF_DIR" ]; then
|
|
||||||
mkdir -p "$CONF_DIR"
|
|
||||||
echo " Created config dir: $CONF_DIR"
|
|
||||||
else
|
|
||||||
echo " Config dir exists: $CONF_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d "$HTML_DIR" ]; then
|
|
||||||
mkdir -p "$HTML_DIR"
|
|
||||||
echo " Created HTML dir: $HTML_DIR"
|
|
||||||
else
|
|
||||||
echo " HTML dir exists: $HTML_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "2. Killing all nginx processes..."
|
|
||||||
pkill -f nginx 2>/dev/null || true
|
|
||||||
sleep 2
|
|
||||||
pkill -9 nginx 2>/dev/null || true
|
|
||||||
sleep 1
|
|
||||||
echo " Done"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "3. Starting nginx..."
|
|
||||||
"$NGINX_BIN" -c "$CONF_FILE"
|
|
||||||
|
|
||||||
sleep 2
|
|
||||||
echo ""
|
|
||||||
echo "4. Testing..."
|
|
||||||
echo ""
|
|
||||||
echo "=== Server Status ==="
|
|
||||||
if pgrep nginx > /dev/null; then
|
|
||||||
SERVER_IP=$(ip addr show | grep inet | grep -v '127.0.0.1' | grep -v '::1' | head -1 | awk '{print $2}' | cut -d'/' -f1)
|
|
||||||
echo "✅ Server running!"
|
|
||||||
echo ""
|
|
||||||
echo "=== Access URLs ==="
|
|
||||||
echo " Local: http://localhost:6045/uft3changecode/"
|
|
||||||
if [ -n "$SERVER_IP" ]; then
|
|
||||||
echo " Remote: http://$SERVER_IP:6045/uft3changecode/"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "❌ Server not running"
|
|
||||||
echo "Error log:"
|
|
||||||
tail -20 /home/taoc/uft30help/workspace/logs/help_error.log
|
|
||||||
fi
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "Checking Help Documentation Server status..."
|
|
||||||
|
|
||||||
if pgrep nginx &> /dev/null; then
|
|
||||||
echo "✅ Help Documentation Server is running"
|
|
||||||
echo "📄 Access URL: http://localhost:8080"
|
|
||||||
else
|
|
||||||
echo "❌ Help Documentation Server is not running"
|
|
||||||
fi
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
NGINX_DIR="/home/taoc/nginx"
|
|
||||||
NGINX_BIN="$NGINX_DIR/sbin/nginx"
|
|
||||||
|
|
||||||
echo "Stopping Help Documentation Server..."
|
|
||||||
|
|
||||||
if [ ! -f "$NGINX_BIN" ]; then
|
|
||||||
echo "Error: nginx binary not found at $NGINX_BIN"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
"$NGINX_BIN" -s stop
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "✅ Help Documentation Server stopped successfully"
|
|
||||||
else
|
|
||||||
echo "❌ Failed to stop nginx"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
10
main.cpp
|
|
@ -1,20 +1,12 @@
|
||||||
#include "src/mainwindow/mainwindow.h"
|
#include "src/mainwindow/mainwindow.h"
|
||||||
#include "ElaApplication.h"
|
#include "ElaApplication.h"
|
||||||
#include "src/utils/configmanager.h"
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QIcon>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
a.setWindowIcon(QIcon(":resources/images/ChangeCode.png"));
|
|
||||||
eApp->init();
|
eApp->init();
|
||||||
|
|
||||||
QString basePath = QCoreApplication::applicationDirPath();
|
|
||||||
ConfigManager::instance()->loadConfig(basePath);
|
|
||||||
|
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
w.showMaximized();
|
w.show();
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,4 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>resources/images/ChangeCode.png</file>
|
|
||||||
<file>resources/images/bianji.png</file>
|
|
||||||
<file>resources/images/zhedie_left.png</file>
|
|
||||||
<file>resources/images/zhedie_right.png</file>
|
|
||||||
<file>resources/images/max.png</file>
|
|
||||||
<file>resources/images/min.png</file>
|
|
||||||
<file>resources/images/update.png</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
# 资源目录
|
|
||||||
|
|
||||||
此目录用于存放项目使用的图标、图片等资源文件。
|
|
||||||
|
|
||||||
## 目录结构
|
|
||||||
|
|
||||||
```
|
|
||||||
resources/
|
|
||||||
├── icons/ # 图标文件
|
|
||||||
└── images/ # 图片文件
|
|
||||||
```
|
|
||||||
|
|
||||||
## 添加新资源
|
|
||||||
|
|
||||||
1. 将资源文件放入对应目录
|
|
||||||
2. 更新 resources.qrc 文件添加资源引用
|
|
||||||
3. 重新编译项目
|
|
||||||
|
|
@ -1,164 +0,0 @@
|
||||||
# 使用帮助
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
|
|
||||||
欢迎使用 UFT30 Change Code 工具!这是一款强大的编码转换工具,支持批量转码和非LS格式转换。
|
|
||||||
|
|
||||||
### 功能导航
|
|
||||||
|
|
||||||
```
|
|
||||||
UFT30 Change Code
|
|
||||||
├── 📁 功能转码
|
|
||||||
│ └── 业务转码
|
|
||||||
├── 📁 功能查询
|
|
||||||
│ ├── UF20功能查询
|
|
||||||
│ └── UFT3功能查询
|
|
||||||
├── 元数据更新
|
|
||||||
├── 设置
|
|
||||||
├── 关于
|
|
||||||
└── 使用技巧
|
|
||||||
```
|
|
||||||
|
|
||||||
点击左侧导航栏的功能项,查看详细的使用说明。
|
|
||||||
|
|
||||||
## 功能转码
|
|
||||||
|
|
||||||
### 业务转码
|
|
||||||
|
|
||||||
将UF20函数转换为UFT3函数格式的核心功能。
|
|
||||||
|
|
||||||
#### 功能列表管理
|
|
||||||
|
|
||||||
- 点击"添加"按钮,输入函数名添加到转码列表
|
|
||||||
- 双击表格行可编辑函数名
|
|
||||||
- 选中行后点击"删除"移除函数
|
|
||||||
- 点击"清空"清空所有函数
|
|
||||||
|
|
||||||
#### 配置文件同步
|
|
||||||
|
|
||||||
- 自动读取 uf2touft3/cust.json 配置
|
|
||||||
- 配置文件外部修改时自动刷新列表
|
|
||||||
|
|
||||||
#### 转换操作
|
|
||||||
|
|
||||||
- 点击"开始转换"启动转换任务
|
|
||||||
- 转换过程中可查看进度条和状态信息
|
|
||||||
- 点击"停止转换"中止当前任务
|
|
||||||
|
|
||||||
## 功能查询
|
|
||||||
|
|
||||||
### UF20功能查询
|
|
||||||
|
|
||||||
查询UF20系统中的函数信息。
|
|
||||||
|
|
||||||
#### 查询条件
|
|
||||||
|
|
||||||
- 从下拉框选择查询字段:功能名称、英文名称、功能编号
|
|
||||||
- 输入框输入查询关键词
|
|
||||||
- 点击"Aa"切换精确/模糊匹配模式
|
|
||||||
- 点击放大镜图标或按回车执行查询
|
|
||||||
|
|
||||||
#### 结果操作
|
|
||||||
|
|
||||||
- 双击查询结果可直接添加到转码列表
|
|
||||||
- 结果表格显示:功能名称、英文名称、功能编号
|
|
||||||
|
|
||||||
### UFT3功能查询
|
|
||||||
|
|
||||||
查询UFT3系统中的函数信息。
|
|
||||||
|
|
||||||
#### 查询条件
|
|
||||||
|
|
||||||
- 从下拉框选择查询字段:功能名称、英文名称、功能编号
|
|
||||||
- 输入框输入查询关键词
|
|
||||||
- 点击"Aa"切换精确/模糊匹配模式
|
|
||||||
- 点击放大镜图标或按回车执行查询
|
|
||||||
|
|
||||||
#### 结果显示
|
|
||||||
|
|
||||||
- 结果表格显示:功能名称、英文名称、功能编号
|
|
||||||
|
|
||||||
## 元数据更新
|
|
||||||
|
|
||||||
更新UF20和UFT3系统的元数据配置。
|
|
||||||
|
|
||||||
### UF20配置更新
|
|
||||||
|
|
||||||
- 勾选需要更新的UF20接口项
|
|
||||||
- 点击"全选"选中所有UF20项
|
|
||||||
- 点击"取消"清除UF20选择
|
|
||||||
- 点击"更新UF20"执行更新
|
|
||||||
|
|
||||||
### UFT3配置更新
|
|
||||||
|
|
||||||
- 勾选需要更新的UFT3接口项
|
|
||||||
- 点击"全选"选中所有UFT3项
|
|
||||||
- 点击"取消"清除UFT3选择
|
|
||||||
- 点击"更新UFT3"执行更新
|
|
||||||
|
|
||||||
### 更新内容
|
|
||||||
|
|
||||||
- UF20: 接口、标准字段、数据类型、错误编号
|
|
||||||
- UFT3: 接口、标准字段、数据类型、表结构
|
|
||||||
|
|
||||||
## 设置
|
|
||||||
|
|
||||||
配置工具的运行参数和选项。
|
|
||||||
|
|
||||||
### 路径配置
|
|
||||||
|
|
||||||
- 设置Python脚本路径
|
|
||||||
- 配置转换工具路径
|
|
||||||
- 设置配置文件目录
|
|
||||||
|
|
||||||
### 显示设置
|
|
||||||
|
|
||||||
- 调整界面主题
|
|
||||||
- 设置字体大小
|
|
||||||
- 配置语言选项
|
|
||||||
|
|
||||||
### 高级设置
|
|
||||||
|
|
||||||
- 设置自动保存间隔
|
|
||||||
- 配置日志级别
|
|
||||||
- 设置最大并发任务数
|
|
||||||
|
|
||||||
## 关于
|
|
||||||
|
|
||||||
### UFT30 Change Code
|
|
||||||
|
|
||||||
一款强大的编码转换工具,支持批量转码和非LS格式转换。
|
|
||||||
|
|
||||||
#### 基本信息
|
|
||||||
|
|
||||||
- **版本**: 1.0.0
|
|
||||||
- **作者**: UFT30 Team
|
|
||||||
- **版权**: Copyright © 2024
|
|
||||||
- **联系方式**: support@uft30.com
|
|
||||||
|
|
||||||
#### 功能特性
|
|
||||||
|
|
||||||
- 支持UF20到UFT3函数格式转换
|
|
||||||
- 批量转换处理
|
|
||||||
- 非LS格式转换支持
|
|
||||||
- 功能查询与快速添加
|
|
||||||
- 元数据自动更新
|
|
||||||
|
|
||||||
## 使用技巧
|
|
||||||
|
|
||||||
### 高效使用技巧
|
|
||||||
|
|
||||||
- 在功能查询中找到需要转换的函数,双击可快速添加到转码列表
|
|
||||||
- 精确匹配适合已知完整函数名的查询
|
|
||||||
- 模糊匹配可以使用部分关键词查找
|
|
||||||
- 配置文件可以手动编辑,工具会自动检测变化
|
|
||||||
- 批量转换前建议先进行元数据更新
|
|
||||||
- 使用Ctrl+F快速搜索帮助内容
|
|
||||||
|
|
||||||
### 注意事项
|
|
||||||
|
|
||||||
- 首次使用前请先执行"元数据更新"加载最新配置
|
|
||||||
- 转换前建议备份重要文件
|
|
||||||
- 确保 uf2touft3/uf2touft3.exe 存在且可执行
|
|
||||||
- 配置文件 uf2touft3/cust.json 会自动同步转码列表
|
|
||||||
- 大文件转换可能需要较长时间,请耐心等待
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# 💡 使用技巧
|
|
||||||
|
|
||||||
## 高效使用技巧
|
|
||||||
|
|
||||||
- 在功能查询中找到需要转换的函数,双击可快速添加到转码列表
|
|
||||||
- 精确匹配适合已知完整函数名的查询
|
|
||||||
- 模糊匹配可以使用部分关键词查找
|
|
||||||
- 配置文件可以手动编辑,工具会自动检测变化
|
|
||||||
- 批量转换前建议先进行元数据更新
|
|
||||||
- 使用Ctrl+F快速搜索帮助内容
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
- 首次使用前请先执行"元数据更新"加载最新配置
|
|
||||||
- 转换前建议备份重要文件
|
|
||||||
- 确保 uf2touft3/uf2touft3.exe 存在且可执行
|
|
||||||
- 配置文件 uf2touft3/cust.json 会自动同步转码列表
|
|
||||||
- 大文件转换可能需要较长时间,请耐心等待
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
# 此文件用于保持icons目录在Git仓库中
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
# 此文件用于保持images目录在Git仓库中
|
|
||||||
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
|
@ -1,116 +0,0 @@
|
||||||
#include "elasearchedit.h"
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include "ElaIcon.h"
|
|
||||||
|
|
||||||
ElaSearchEdit::ElaSearchEdit(QWidget* parent)
|
|
||||||
: QWidget(parent), m_exactMatch(false)
|
|
||||||
{
|
|
||||||
initUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
ElaSearchEdit::~ElaSearchEdit()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::initUI()
|
|
||||||
{
|
|
||||||
QHBoxLayout* mainLayout = new QHBoxLayout(this);
|
|
||||||
mainLayout->setSpacing(0);
|
|
||||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
|
|
||||||
m_lineEdit = new ElaLineEdit(this);
|
|
||||||
m_lineEdit->setFixedHeight(35);
|
|
||||||
m_lineEdit->setPlaceholderText("输入查询内容");
|
|
||||||
m_lineEdit->setIsClearButtonEnable(false);
|
|
||||||
|
|
||||||
QHBoxLayout* inputLayout = new QHBoxLayout(m_lineEdit);
|
|
||||||
inputLayout->setContentsMargins(0, 0, 4, 0);
|
|
||||||
inputLayout->addStretch();
|
|
||||||
|
|
||||||
m_exactMatchBtn = addToolButton(m_lineEdit, ElaIconType::FontCase, "区分大小写", QSize(26, 26), true, false);
|
|
||||||
inputLayout->addWidget(m_exactMatchBtn);
|
|
||||||
|
|
||||||
resetInputMargin();
|
|
||||||
|
|
||||||
mainLayout->addWidget(m_lineEdit);
|
|
||||||
|
|
||||||
m_searchBtn = addToolButton(this, ElaIconType::MagnifyingGlass, "搜索", QSize(35, 35), false, false);
|
|
||||||
mainLayout->addWidget(m_searchBtn);
|
|
||||||
|
|
||||||
connectSignals();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::connectSignals()
|
|
||||||
{
|
|
||||||
connect(m_lineEdit, &ElaLineEdit::textChanged, this, &ElaSearchEdit::textChanged);
|
|
||||||
connect(m_lineEdit, &ElaLineEdit::returnPressed, this, &ElaSearchEdit::returnPressed);
|
|
||||||
connect(m_searchBtn, &ElaToolButton::clicked, this, &ElaSearchEdit::searchClicked);
|
|
||||||
connect(m_exactMatchBtn, &ElaToolButton::clicked, this, [this](bool checked) {
|
|
||||||
m_exactMatch = checked;
|
|
||||||
emit exactMatchChanged(checked);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::resetInputMargin()
|
|
||||||
{
|
|
||||||
m_lineEdit->setTextMargins(0, 0, 30, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ElaToolButton* ElaSearchEdit::addToolButton(QWidget* parent, ElaIconType::IconName icon, const QString& tooltip, const QSize& size, bool checkable, bool checked)
|
|
||||||
{
|
|
||||||
ElaToolButton* btn = new ElaToolButton(parent);
|
|
||||||
btn->setElaIcon(icon);
|
|
||||||
btn->setFixedSize(size);
|
|
||||||
btn->setToolTip(tooltip);
|
|
||||||
btn->setCheckable(checkable);
|
|
||||||
btn->setChecked(checked);
|
|
||||||
btn->setCursor(Qt::PointingHandCursor);
|
|
||||||
return btn;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ElaSearchEdit::text() const
|
|
||||||
{
|
|
||||||
return m_lineEdit->text();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::setText(const QString& text)
|
|
||||||
{
|
|
||||||
m_lineEdit->setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::setPlaceholderText(const QString& placeholderText)
|
|
||||||
{
|
|
||||||
m_lineEdit->setPlaceholderText(placeholderText);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::setFixedSize(const QSize& size)
|
|
||||||
{
|
|
||||||
m_lineEdit->setFixedSize(size.width() - 35, size.height());
|
|
||||||
m_searchBtn->setFixedSize(35, size.height());
|
|
||||||
QWidget::setFixedSize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::setFixedSize(int w, int h)
|
|
||||||
{
|
|
||||||
m_lineEdit->setFixedSize(w - 35, h);
|
|
||||||
m_searchBtn->setFixedSize(35, h);
|
|
||||||
QWidget::setFixedSize(w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::setFixedHeight(int h)
|
|
||||||
{
|
|
||||||
m_lineEdit->setFixedHeight(h);
|
|
||||||
m_searchBtn->setFixedSize(35, h);
|
|
||||||
QWidget::setFixedHeight(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ElaSearchEdit::isExactMatch() const
|
|
||||||
{
|
|
||||||
return m_exactMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElaSearchEdit::setExactMatch(bool exact)
|
|
||||||
{
|
|
||||||
m_exactMatch = exact;
|
|
||||||
m_exactMatchBtn->setChecked(exact);
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
#ifndef ELASEARCHEDIT_H
|
|
||||||
#define ELASEARCHEDIT_H
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QList>
|
|
||||||
#include "ElaLineEdit.h"
|
|
||||||
#include "ElaToolButton.h"
|
|
||||||
|
|
||||||
class ElaSearchEdit : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ElaSearchEdit(QWidget* parent = nullptr);
|
|
||||||
~ElaSearchEdit() override;
|
|
||||||
|
|
||||||
QString text() const;
|
|
||||||
void setText(const QString& text);
|
|
||||||
void setPlaceholderText(const QString& placeholderText);
|
|
||||||
void setFixedSize(const QSize& size);
|
|
||||||
void setFixedSize(int w, int h);
|
|
||||||
void setFixedHeight(int h);
|
|
||||||
|
|
||||||
bool isExactMatch() const;
|
|
||||||
void setExactMatch(bool exact);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void textChanged(const QString& text);
|
|
||||||
void returnPressed();
|
|
||||||
void exactMatchChanged(bool exact);
|
|
||||||
void searchClicked();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initUI();
|
|
||||||
void connectSignals();
|
|
||||||
void resetInputMargin();
|
|
||||||
ElaToolButton* addToolButton(QWidget* parent, ElaIconType::IconName icon, const QString& tooltip, const QSize& size, bool checkable = false, bool checked = false);
|
|
||||||
|
|
||||||
ElaLineEdit* m_lineEdit;
|
|
||||||
ElaToolButton* m_searchBtn;
|
|
||||||
ElaToolButton* m_exactMatchBtn;
|
|
||||||
bool m_exactMatch;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ELASEARCHEDIT_H
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
#include "interdialog.h"
|
|
||||||
|
|
||||||
#include "ElaText.h"
|
|
||||||
#include "ElaPushButton.h"
|
|
||||||
|
|
||||||
#include <QSpacerItem>
|
|
||||||
|
|
||||||
InterDialog::InterDialog(QWidget* parent) : ElaDialog(parent)
|
|
||||||
{
|
|
||||||
this->setIsFixedSize(true);
|
|
||||||
this->setWindowModality(Qt::ApplicationModal);
|
|
||||||
this->setWindowButtonFlags(ElaAppBarType::CloseButtonHint);
|
|
||||||
this->setAppBarHeight(30);
|
|
||||||
|
|
||||||
_mainLayout = new QVBoxLayout(this);
|
|
||||||
_mainLayout->setContentsMargins(10, 10, 10, 10);
|
|
||||||
|
|
||||||
_centralWidget = new QWidget(this);
|
|
||||||
auto* centralVLayout = new QVBoxLayout(_centralWidget);
|
|
||||||
centralVLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
_messageLabel = new ElaText("这是消息", _centralWidget);
|
|
||||||
_messageLabel->setIsWrapAnywhere(true);
|
|
||||||
centralVLayout->addWidget(_messageLabel);
|
|
||||||
|
|
||||||
_buttonWidget = new QWidget(this);
|
|
||||||
_btnLayout = new QHBoxLayout(_buttonWidget);
|
|
||||||
_btnLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
_btnLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Minimum));
|
|
||||||
|
|
||||||
auto *defaultButton = new QPushButton(_buttonWidget);
|
|
||||||
defaultButton->setDefault(true);
|
|
||||||
defaultButton->hide();
|
|
||||||
|
|
||||||
_okButton = new ElaPushButton("确认", _buttonWidget);
|
|
||||||
connect(_okButton, &ElaPushButton::clicked, this, [=]
|
|
||||||
{
|
|
||||||
emit okButtonClicked();
|
|
||||||
accept();
|
|
||||||
});
|
|
||||||
_okButton->setLightDefaultColor(ElaThemeColor(ElaThemeType::Light, PrimaryNormal));
|
|
||||||
_okButton->setLightHoverColor(ElaThemeColor(ElaThemeType::Light, PrimaryHover));
|
|
||||||
_okButton->setLightPressColor(ElaThemeColor(ElaThemeType::Light, PrimaryPress));
|
|
||||||
_okButton->setLightTextColor(ElaThemeColor(ElaThemeType::Dark, BasicText));
|
|
||||||
_okButton->setDarkDefaultColor(ElaThemeColor(ElaThemeType::Dark, PrimaryNormal));
|
|
||||||
_okButton->setDarkHoverColor(ElaThemeColor(ElaThemeType::Dark, PrimaryHover));
|
|
||||||
_okButton->setDarkPressColor(ElaThemeColor(ElaThemeType::Dark, PrimaryPress));
|
|
||||||
_okButton->setDarkTextColor(ElaThemeColor(ElaThemeType::Light, BasicText));
|
|
||||||
_okButton->setMinimumSize(0, 0);
|
|
||||||
_okButton->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
|
|
||||||
_okButton->setFixedHeight(38);
|
|
||||||
_btnLayout->addWidget(_okButton);
|
|
||||||
|
|
||||||
_cancelButton = new ElaPushButton("取消", _buttonWidget);
|
|
||||||
connect(_cancelButton, &ElaPushButton::clicked, this, [=]
|
|
||||||
{
|
|
||||||
emit cancelButtonClicked();
|
|
||||||
reject();
|
|
||||||
});
|
|
||||||
_cancelButton->setMinimumSize(0, 0);
|
|
||||||
_cancelButton->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
|
|
||||||
_cancelButton->setFixedHeight(38);
|
|
||||||
_btnLayout->addWidget(_cancelButton);
|
|
||||||
|
|
||||||
_mainLayout->addWidget(_centralWidget);
|
|
||||||
_mainLayout->addWidget(_buttonWidget);
|
|
||||||
|
|
||||||
setFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
InterDialog::~InterDialog() = default;
|
|
||||||
|
|
||||||
void InterDialog::setMessage(const QString& message)
|
|
||||||
{
|
|
||||||
if (_messageLabel)
|
|
||||||
{
|
|
||||||
_messageLabel->setText(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterDialog::setCentralWidget(QWidget* centralWidget)
|
|
||||||
{
|
|
||||||
_mainLayout->removeWidget(_centralWidget);
|
|
||||||
delete _messageLabel;
|
|
||||||
_messageLabel = nullptr;
|
|
||||||
delete _centralWidget;
|
|
||||||
_centralWidget = centralWidget;
|
|
||||||
QSizePolicy sizePolicy(QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Expanding);
|
|
||||||
sizePolicy.setHorizontalStretch(0);
|
|
||||||
sizePolicy.setVerticalStretch(0);
|
|
||||||
sizePolicy.setHeightForWidth(centralWidget->sizePolicy().hasHeightForWidth());
|
|
||||||
centralWidget->setSizePolicy(sizePolicy);
|
|
||||||
_mainLayout->insertWidget(0, _centralWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterDialog::setStandardButtons(const QDialogButtonBox::StandardButtons buttons) const
|
|
||||||
{
|
|
||||||
if (buttons.testFlag(QDialogButtonBox::NoButton))
|
|
||||||
{
|
|
||||||
_buttonWidget->setVisible(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_okButton->setVisible(buttons.testFlag(QDialogButtonBox::StandardButton::Ok));
|
|
||||||
_cancelButton->setVisible(buttons.testFlag(QDialogButtonBox::StandardButton::Cancel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterDialog::addFirstButton(QPushButton* button) const
|
|
||||||
{
|
|
||||||
_btnLayout->insertWidget(1, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterDialog::addLastButton(QPushButton* button) const
|
|
||||||
{
|
|
||||||
_btnLayout->addWidget(button);
|
|
||||||
}
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
#ifndef METASEARCH_INTERDIALOG_H
|
|
||||||
#define METASEARCH_INTERDIALOG_H
|
|
||||||
|
|
||||||
#include "ElaDialog.h"
|
|
||||||
#include "ElaTheme.h"
|
|
||||||
#include "ElaText.h"
|
|
||||||
#include "ElaPushButton.h"
|
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 带按钮栏的弹窗
|
|
||||||
*/
|
|
||||||
class InterDialog : public ElaDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit InterDialog(QWidget* parent = nullptr);
|
|
||||||
~InterDialog() override;
|
|
||||||
|
|
||||||
// 设置消息
|
|
||||||
virtual void setMessage(const QString& message);
|
|
||||||
|
|
||||||
// 设置中心区域
|
|
||||||
void setCentralWidget(QWidget* centralWidget);
|
|
||||||
|
|
||||||
// 设置按钮
|
|
||||||
void setStandardButtons(QDialogButtonBox::StandardButtons buttons) const;
|
|
||||||
|
|
||||||
// 头部添加按钮
|
|
||||||
void addFirstButton(QPushButton* button) const;
|
|
||||||
|
|
||||||
// 尾部添加按钮
|
|
||||||
void addLastButton(QPushButton* button) const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void okButtonClicked();
|
|
||||||
void cancelButtonClicked();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// 主题
|
|
||||||
ElaThemeType::ThemeMode _themeMode;
|
|
||||||
|
|
||||||
// 主布局
|
|
||||||
QVBoxLayout* _mainLayout{nullptr};
|
|
||||||
|
|
||||||
// 中心区域
|
|
||||||
QWidget* _centralWidget{nullptr};
|
|
||||||
// 中心区域文本
|
|
||||||
ElaText* _messageLabel{nullptr};
|
|
||||||
|
|
||||||
// 按钮区域
|
|
||||||
QWidget* _buttonWidget{nullptr};
|
|
||||||
// 按钮区域布局
|
|
||||||
QHBoxLayout* _btnLayout{nullptr};
|
|
||||||
// 确认按钮
|
|
||||||
ElaPushButton* _okButton{nullptr};
|
|
||||||
// 取消按钮
|
|
||||||
ElaPushButton* _cancelButton{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //METASEARCH_INTERDIALOG_H
|
|
||||||
|
|
@ -2,10 +2,6 @@
|
||||||
#include "ElaIcon.h"
|
#include "ElaIcon.h"
|
||||||
#include "ElaText.h"
|
#include "ElaText.h"
|
||||||
#include "ElaTheme.h"
|
#include "ElaTheme.h"
|
||||||
#include "ElaToolButton.h"
|
|
||||||
#include "utils/uf2configreader.h"
|
|
||||||
#include "utils/uft3configreader.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
@ -20,82 +16,42 @@
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTimer>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: ElaWindow(parent)
|
: ElaWindow(parent)
|
||||||
, m_pythonRunner(new PythonRunner(this))
|
, m_pythonRunner(new PythonRunner(this))
|
||||||
, m_iconsSet(false)
|
|
||||||
, m_navigationButton(nullptr)
|
|
||||||
, m_isNavigationExpanded(true)
|
|
||||||
{
|
{
|
||||||
initWindow();
|
initWindow();
|
||||||
initContent();
|
initContent();
|
||||||
|
|
||||||
LogManager::instance()->initLogFile();
|
// 获取应用程序目录
|
||||||
LogManager::instance()->logInfo("应用程序启动");
|
|
||||||
|
|
||||||
QString appDir = QCoreApplication::applicationDirPath();
|
QString appDir = QCoreApplication::applicationDirPath();
|
||||||
|
|
||||||
loadConfigCache();
|
// 配置 Python 运行器 - 只使用打包好的 exe,路径是 uf2touft3/uf2touft3.exe
|
||||||
|
|
||||||
m_pythonRunner->setRunMode(PythonRunner::UsePackagedExe);
|
m_pythonRunner->setRunMode(PythonRunner::UsePackagedExe);
|
||||||
|
|
||||||
|
// 设置打包好的可执行文件路径和工作目录
|
||||||
QString exePath = appDir + "/uf2touft3/uf2touft3.exe";
|
QString exePath = appDir + "/uf2touft3/uf2touft3.exe";
|
||||||
QString workDir = appDir + "/uf2touft3";
|
QString workDir = appDir + "/uf2touft3";
|
||||||
|
|
||||||
m_pythonRunner->setPackagedExePath(exePath);
|
m_pythonRunner->setPackagedExePath(exePath);
|
||||||
m_pythonRunner->setWorkingDirectory(workDir);
|
m_pythonRunner->setWorkingDirectory(workDir);
|
||||||
|
|
||||||
|
// 检查 exe 是否存在
|
||||||
QFileInfo exeInfo(exePath);
|
QFileInfo exeInfo(exePath);
|
||||||
if (!exeInfo.exists() || !exeInfo.isFile()) {
|
if (!exeInfo.exists() || !exeInfo.isFile()) {
|
||||||
LogManager::instance()->logError(QString("未找到转换工具: %1").arg(exePath));
|
m_batchLogEdit->append("⚠️ 警告:未找到 uf2touft3/uf2touft3.exe!");
|
||||||
|
m_batchLogEdit->append(QString(" 期望位置:%1").arg(exePath));
|
||||||
|
} else {
|
||||||
|
m_batchLogEdit->append("✓ Python 工具准备就绪");
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(m_pythonRunner, &PythonRunner::finished, this, &MainWindow::onPythonRunnerFinished);
|
connect(m_pythonRunner, &PythonRunner::finished, this, &MainWindow::onPythonRunnerFinished);
|
||||||
connect(m_pythonRunner, &PythonRunner::standardOutput, this, &MainWindow::onPythonRunnerOutput);
|
connect(m_pythonRunner, &PythonRunner::standardOutput, this, &MainWindow::onPythonRunnerOutput);
|
||||||
connect(m_pythonRunner, &PythonRunner::standardError, this, &MainWindow::onPythonRunnerError);
|
connect(m_pythonRunner, &PythonRunner::standardError, this, &MainWindow::onPythonRunnerError);
|
||||||
|
connect(m_pythonRunner, &PythonRunner::started, [this]() {
|
||||||
connect(this, &ElaWindow::navigationNodeClicked, this, &MainWindow::onNavigationNodeClicked);
|
m_batchLogEdit->append("转换任务已启动...");
|
||||||
|
});
|
||||||
QTimer::singleShot(100, this, &MainWindow::updateNavigationButtonIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::loadConfigCache()
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("正在加载配置缓存...");
|
|
||||||
|
|
||||||
UF2ConfigReader uf2Reader;
|
|
||||||
bool uf2Loaded = uf2Reader.loadAllUF20Config();
|
|
||||||
|
|
||||||
UFT3ConfigReader uft3Reader;
|
|
||||||
bool uft3Loaded = uft3Reader.loadAllUFT3Config();
|
|
||||||
|
|
||||||
if (uf2Loaded && uft3Loaded) {
|
|
||||||
LogManager::instance()->log("✓ 配置缓存加载完成");
|
|
||||||
} else {
|
|
||||||
LogManager::instance()->logWarning("⚠️ 部分配置加载失败");
|
|
||||||
|
|
||||||
QStringList uf2Failed = uf2Reader.getFailedFiles();
|
|
||||||
QStringList uft3Failed = uft3Reader.getFailedFiles();
|
|
||||||
|
|
||||||
if (!uf2Failed.isEmpty()) {
|
|
||||||
LogManager::instance()->log(" UF20 加载失败:");
|
|
||||||
foreach (const QString& file, uf2Failed) {
|
|
||||||
LogManager::instance()->log(QString(" - %1").arg(file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uft3Failed.isEmpty()) {
|
|
||||||
LogManager::instance()->log(" UFT3 加载失败:");
|
|
||||||
foreach (const QString& file, uft3Failed) {
|
|
||||||
LogManager::instance()->log(QString(" - %1").arg(file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
|
@ -104,41 +60,36 @@ MainWindow::~MainWindow()
|
||||||
|
|
||||||
void MainWindow::initWindow()
|
void MainWindow::initWindow()
|
||||||
{
|
{
|
||||||
setWindowTitle(QString("UFT30 Change Code %1").arg(Version::getVersionString()));
|
setWindowTitle("UFT30 Change Code");
|
||||||
setWindowIcon(QIcon(":/resources/images/ChangeCode.png"));
|
setWindowIcon(QIcon(":/Resource/Image/Cirno.jpg"));
|
||||||
resize(900, 600);
|
resize(900, 600);
|
||||||
setMinimumSize(800, 500);
|
setUserInfoCardTitle("UFT30");
|
||||||
setUserInfoCardVisible(false);
|
setUserInfoCardSubTitle("Change Code Tool");
|
||||||
|
|
||||||
// 隐藏返回和前进按钮
|
|
||||||
|
|
||||||
setWindowButtonFlag(ElaAppBarType::RouteBackButtonHint, false);
|
|
||||||
setWindowButtonFlag(ElaAppBarType::RouteForwardButtonHint, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initContent()
|
void MainWindow::initContent()
|
||||||
{
|
{
|
||||||
addExpanderNode("功能转码", m_funcConvertKey, ElaIconType::FileCode);
|
QString helpKey;
|
||||||
addPageNode("业务转码", createBatchConvertPage(), m_funcConvertKey, ElaIconType::ArrowsRepeat);
|
QString aboutKey;
|
||||||
|
QString settingKey;
|
||||||
addExpanderNode("功能查询", m_funcSearchKey, ElaIconType::MagnifyingGlass);
|
addPageNode("转码业务", createBatchConvertPage(), ElaIconType::FileCode);
|
||||||
addPageNode("UF20功能查询", createUF20FunctionSearchPage(), m_funcSearchKey, ElaIconType::MagnifyingGlassPlus);
|
addPageNode("功能搜索", createFunctionSearchPage(), ElaIconType::MagnifyingGlass);
|
||||||
addPageNode("UFT3功能查询", createUFT3FunctionSearchPage(), m_funcSearchKey, ElaIconType::MagnifyingGlassPlus);
|
addFooterNode("帮助", createHelpPage(), helpKey, 0, ElaIconType::CircleQuestion);
|
||||||
expandNavigationNode(m_funcConvertKey);
|
addFooterNode("关于", createAboutPage(), aboutKey, 0, ElaIconType::User);
|
||||||
|
addFooterNode("设置", createSettingsPage(), settingKey, 0, ElaIconType::GearComplex);
|
||||||
addPageNode("元数据更新", createMetadataUpdatePage(), ElaIconType::ArrowsRotate);
|
|
||||||
|
|
||||||
addFooterNode("帮助", m_helpKey, 0, ElaIconType::CircleQuestion);
|
|
||||||
addFooterNode("关于", m_aboutKey, 0, ElaIconType::Info);
|
|
||||||
addFooterNode("设置", createSettingsPage(), m_settingKey, 0, ElaIconType::GearComplex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* MainWindow::createBatchConvertPage()
|
QWidget* MainWindow::createBatchConvertPage()
|
||||||
{
|
{
|
||||||
m_batchConvertPage = new BatchConvertPage;
|
BatchConvertPage *page = new BatchConvertPage;
|
||||||
connect(m_batchConvertPage, &BatchConvertPage::startConvert, this, &MainWindow::onBatchConvertStart);
|
m_batchLogEdit = page->getLogEdit();
|
||||||
connect(m_batchConvertPage, &BatchConvertPage::stopConvert, this, &MainWindow::onBatchConvertStop);
|
connect(page, &BatchConvertPage::startConvert, this, &MainWindow::onBatchConvertStart);
|
||||||
return m_batchConvertPage;
|
connect(m_pythonRunner, &PythonRunner::started, [this]() {
|
||||||
|
if (m_batchLogEdit) {
|
||||||
|
m_batchLogEdit->append("转换任务已启动...");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* MainWindow::createFunctionSearchPage()
|
QWidget* MainWindow::createFunctionSearchPage()
|
||||||
|
|
@ -146,17 +97,14 @@ QWidget* MainWindow::createFunctionSearchPage()
|
||||||
return new FunctionSearchPage;
|
return new FunctionSearchPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* MainWindow::createUF20FunctionSearchPage()
|
QWidget* MainWindow::createHelpPage()
|
||||||
{
|
{
|
||||||
UF20FunctionSearchPage *page = new UF20FunctionSearchPage;
|
return new HelpPage;
|
||||||
connect(page, &UF20FunctionSearchPage::addFunctionToConvert,
|
|
||||||
m_batchConvertPage, &BatchConvertPage::addFunction);
|
|
||||||
return page;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* MainWindow::createUFT3FunctionSearchPage()
|
QWidget* MainWindow::createAboutPage()
|
||||||
{
|
{
|
||||||
return new UFT3FunctionSearchPage;
|
return new AboutPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* MainWindow::createSettingsPage()
|
QWidget* MainWindow::createSettingsPage()
|
||||||
|
|
@ -164,15 +112,10 @@ QWidget* MainWindow::createSettingsPage()
|
||||||
return new SettingsPage();
|
return new SettingsPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* MainWindow::createMetadataUpdatePage()
|
|
||||||
{
|
|
||||||
return new MetadataUpdatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onBatchConvertStart()
|
void MainWindow::onBatchConvertStart()
|
||||||
{
|
{
|
||||||
if (m_pythonRunner->isRunning()) {
|
if (m_pythonRunner->isRunning()) {
|
||||||
LogManager::instance()->logWarning("警告: 上一个任务还在运行中...");
|
m_batchLogEdit->append("警告: 上一个任务还在运行中...");
|
||||||
QMessageBox::warning(this, "提示", "上一个转换任务正在运行,请等待完成或停止当前任务。");
|
QMessageBox::warning(this, "提示", "上一个转换任务正在运行,请等待完成或停止当前任务。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -181,213 +124,46 @@ void MainWindow::onBatchConvertStart()
|
||||||
QString exePath = appDir + "/uf2touft3/uf2touft3.exe";
|
QString exePath = appDir + "/uf2touft3/uf2touft3.exe";
|
||||||
|
|
||||||
if (!m_pythonRunner->canRun()) {
|
if (!m_pythonRunner->canRun()) {
|
||||||
LogManager::instance()->logError("错误: 找不到 uf2touft3/uf2touft3.exe!");
|
m_batchLogEdit->append("错误: 找不到 uf2touft3/uf2touft3.exe!");
|
||||||
QMessageBox::critical(this, "错误",
|
QMessageBox::critical(this, "错误",
|
||||||
QString("无法启动转换任务!\n\n请确保:\nuf2touft3/uf2touft3.exe 存在,且该目录下包含 config.ini\n\n期望路径:\n%1")
|
QString("无法启动转换任务!\n\n请确保:\nuf2touft3/uf2touft3.exe 存在,且该目录下包含 config.ini\n\n期望路径:\n%1")
|
||||||
.arg(exePath));
|
.arg(exePath));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_batchConvertPage) {
|
m_batchLogEdit->append("========================================");
|
||||||
m_totalFunctions = m_batchConvertPage->getFunctionCount();
|
m_batchLogEdit->append("开始执行 UFT2 到 UFT3 的代码转换...");
|
||||||
m_functionList = m_batchConvertPage->getFunctionList();
|
m_batchLogEdit->append(QString("工具路径: %1").arg(exePath));
|
||||||
m_currentFunctionIndex = 0;
|
m_batchLogEdit->append("========================================");
|
||||||
} else {
|
|
||||||
m_totalFunctions = 0;
|
|
||||||
m_currentFunctionIndex = 0;
|
|
||||||
m_functionList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log("========================================");
|
|
||||||
LogManager::instance()->log("开始执行 UFT2 到 UFT3 的代码转换...");
|
|
||||||
LogManager::instance()->log(QString("工具路径: %1").arg(exePath));
|
|
||||||
LogManager::instance()->log(QString("待转换函数数量: %1").arg(m_totalFunctions));
|
|
||||||
LogManager::instance()->log("========================================");
|
|
||||||
|
|
||||||
if (!m_pythonRunner->start()) {
|
if (!m_pythonRunner->start()) {
|
||||||
LogManager::instance()->logError("错误: 无法启动转换进程!");
|
m_batchLogEdit->append("错误: 无法启动转换进程!");
|
||||||
} else {
|
|
||||||
if (m_batchConvertPage) {
|
|
||||||
m_batchConvertPage->onConvertStarted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onBatchConvertStop()
|
|
||||||
{
|
|
||||||
if (m_pythonRunner->isRunning()) {
|
|
||||||
LogManager::instance()->log("正在停止转换进程...");
|
|
||||||
m_pythonRunner->stop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onPythonRunnerFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
void MainWindow::onPythonRunnerFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
{
|
{
|
||||||
if (m_batchConvertPage) {
|
m_batchLogEdit->append("========================================");
|
||||||
m_batchConvertPage->onConvertFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log("========================================");
|
|
||||||
if (exitStatus == QProcess::NormalExit && exitCode == 0) {
|
if (exitStatus == QProcess::NormalExit && exitCode == 0) {
|
||||||
LogManager::instance()->log("✓ 代码转换完成!");
|
m_batchLogEdit->append("✓ 代码转换完成!");
|
||||||
QMessageBox::information(this, "完成", "代码转换任务已成功完成!");
|
QMessageBox::information(this, "完成", "代码转换任务已成功完成!");
|
||||||
} else {
|
} else {
|
||||||
LogManager::instance()->logError(QString("✗ 转换失败! 退出码: %1").arg(exitCode));
|
m_batchLogEdit->append(QString("✗ 转换失败! 退出码: %1").arg(exitCode));
|
||||||
QMessageBox::warning(this, "失败", QString("代码转换任务失败,退出码: %1").arg(exitCode));
|
QMessageBox::warning(this, "失败", QString("代码转换任务失败,退出码: %1").arg(exitCode));
|
||||||
}
|
}
|
||||||
LogManager::instance()->log("========================================");
|
m_batchLogEdit->append("========================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onPythonRunnerOutput(const QString &output)
|
void MainWindow::onPythonRunnerOutput(const QString &output)
|
||||||
{
|
{
|
||||||
if (!output.trimmed().isEmpty()) {
|
if (!output.trimmed().isEmpty()) {
|
||||||
LogManager::instance()->log(output);
|
m_batchLogEdit->append(output);
|
||||||
|
|
||||||
QString trimmedOutput = output.trimmed();
|
|
||||||
|
|
||||||
QRegularExpression progressRegExp(R"(progress\s*[:=]\s*(\d+))");
|
|
||||||
QRegularExpressionMatch match = progressRegExp.match(trimmedOutput);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
int progress = match.captured(1).toInt();
|
|
||||||
QString status = trimmedOutput;
|
|
||||||
if (status.contains("progress", Qt::CaseInsensitive)) {
|
|
||||||
status = status.replace(progressRegExp, "").trimmed();
|
|
||||||
if (status.isEmpty()) {
|
|
||||||
status = QString("转换中 %1%").arg(progress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_batchConvertPage) {
|
|
||||||
m_batchConvertPage->onProgressUpdate(progress, status);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (m_batchConvertPage) {
|
|
||||||
QString currentFunction;
|
|
||||||
QRegularExpression funcRegExp(R"(([\w_]+))");
|
|
||||||
QRegularExpressionMatch funcMatch = funcRegExp.match(trimmedOutput);
|
|
||||||
if (funcMatch.hasMatch()) {
|
|
||||||
currentFunction = funcMatch.captured(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentFunction.isEmpty() && m_totalFunctions > 0) {
|
|
||||||
int index = m_functionList.indexOf(currentFunction);
|
|
||||||
if (index >= 0 && index >= m_currentFunctionIndex) {
|
|
||||||
m_currentFunctionIndex = index + 1;
|
|
||||||
int progress = 20 + (m_currentFunctionIndex * 80) / m_totalFunctions;
|
|
||||||
QString status = QString("正在转换: %1").arg(currentFunction);
|
|
||||||
m_batchConvertPage->onProgressUpdate(progress, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int currentProgress = 20;
|
|
||||||
if (trimmedOutput.contains("开始转换", Qt::CaseInsensitive)) {
|
|
||||||
currentProgress = 25;
|
|
||||||
} else if (trimmedOutput.contains("处理文件", Qt::CaseInsensitive)) {
|
|
||||||
currentProgress = 30;
|
|
||||||
} else if (trimmedOutput.contains("生成代码", Qt::CaseInsensitive)) {
|
|
||||||
currentProgress = 75;
|
|
||||||
} else if (trimmedOutput.contains("完成", Qt::CaseInsensitive)) {
|
|
||||||
currentProgress = 95;
|
|
||||||
}
|
|
||||||
m_batchConvertPage->onProgressUpdate(currentProgress, trimmedOutput);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onPythonRunnerError(const QString &error)
|
void MainWindow::onPythonRunnerError(const QString &error)
|
||||||
{
|
{
|
||||||
if (!error.trimmed().isEmpty()) {
|
if (!error.trimmed().isEmpty()) {
|
||||||
LogManager::instance()->logError(QString("[ERROR] %1").arg(error));
|
m_batchLogEdit->append(QString("[ERROR] %1").arg(error));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::updateNavigationButtonIcon()
|
|
||||||
{
|
|
||||||
// 使用资源文件中的图标
|
|
||||||
QIcon leftIcon(":/resources/images/zhedie_left.png");
|
|
||||||
|
|
||||||
if (leftIcon.isNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查找所有 ElaToolButton
|
|
||||||
QList<ElaToolButton*> allButtons = this->findChildren<ElaToolButton*>(QString(), Qt::FindChildrenRecursively);
|
|
||||||
|
|
||||||
// 尝试查找导航按钮 - 可能在不同位置
|
|
||||||
for (int i = 0; i < allButtons.size(); i++) {
|
|
||||||
ElaToolButton* btn = allButtons[i];
|
|
||||||
QString objName = btn->objectName();
|
|
||||||
|
|
||||||
// 检查是否是导航按钮(可能的名称)
|
|
||||||
if (objName.contains("Nav", Qt::CaseInsensitive) ||
|
|
||||||
objName.contains("Menu", Qt::CaseInsensitive) ||
|
|
||||||
objName.contains("Navigation", Qt::CaseInsensitive)) {
|
|
||||||
m_navigationButton = btn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果没有找到有名称的导航按钮,使用第一个可见按钮
|
|
||||||
if (!m_navigationButton) {
|
|
||||||
for (ElaToolButton* btn : allButtons) {
|
|
||||||
if (btn->isVisible()) {
|
|
||||||
m_navigationButton = btn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_navigationButton) {
|
|
||||||
m_navigationButton->setProperty("ElaIconType", "");
|
|
||||||
m_navigationButton->setIcon(leftIcon);
|
|
||||||
m_navigationButton->setIconSize(QSize(24, 24));
|
|
||||||
m_navigationButton->update();
|
|
||||||
|
|
||||||
// 先断开可能存在的连接,然后重新连接,避免多次连接
|
|
||||||
disconnect(m_navigationButton, &ElaToolButton::clicked, this, &MainWindow::onNavigationButtonClicked);
|
|
||||||
connect(m_navigationButton, &ElaToolButton::clicked, this, &MainWindow::onNavigationButtonClicked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
|
|
||||||
{
|
|
||||||
if (!m_iconsSet && event->type() == QEvent::Show) {
|
|
||||||
// 窗口显示后尝试设置图标
|
|
||||||
updateNavigationButtonIcon();
|
|
||||||
m_iconsSet = true;
|
|
||||||
}
|
|
||||||
return ElaWindow::eventFilter(obj, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onNavigationButtonClicked()
|
|
||||||
{
|
|
||||||
if (!m_navigationButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon leftIcon(":/resources/images/zhedie_left.png");
|
|
||||||
QIcon rightIcon(":/resources/images/zhedie_right.png");
|
|
||||||
|
|
||||||
// 使用状态变量来判断当前状态,而不是依赖 cacheKey
|
|
||||||
if (m_isNavigationExpanded) {
|
|
||||||
// 当前是展开状态,切换到折叠状态
|
|
||||||
m_navigationButton->setIcon(rightIcon);
|
|
||||||
m_isNavigationExpanded = false;
|
|
||||||
} else {
|
|
||||||
// 当前是折叠状态,切换到展开状态
|
|
||||||
m_navigationButton->setIcon(leftIcon);
|
|
||||||
m_isNavigationExpanded = true;
|
|
||||||
}
|
|
||||||
m_navigationButton->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onNavigationNodeClicked(ElaNavigationType::NavigationNodeType nodeType, QString nodeKey)
|
|
||||||
{
|
|
||||||
Q_UNUSED(nodeType);
|
|
||||||
if (nodeKey == m_helpKey) {
|
|
||||||
QDesktopServices::openUrl(QUrl("http://10.20.163.105:6045/uft3changecode"));
|
|
||||||
} else if (nodeKey == m_aboutKey) {
|
|
||||||
std::make_unique<AboutDialog>(this)->exec();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,14 @@
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
#include "ElaWindow.h"
|
#include "ElaWindow.h"
|
||||||
#include "ElaToolButton.h"
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QTextEdit>
|
||||||
#include "src/pythonrunner/PythonRunner.h"
|
#include "src/pythonrunner/PythonRunner.h"
|
||||||
#include "src/pages/batchconvert/batchconvertpage.h"
|
#include "src/pages/batchconvert/batchconvertpage.h"
|
||||||
#include "src/pages/functionsearch/functionsearchpage.h"
|
#include "src/pages/functionsearch/functionsearchpage.h"
|
||||||
#include "src/pages/functionsearch/uf20functionsearchpage.h"
|
#include "src/pages/help/helppage.h"
|
||||||
#include "src/pages/functionsearch/uft3functionsearchpage.h"
|
#include "src/pages/about/aboutpage.h"
|
||||||
|
|
||||||
#include "src/pages/about/aboutdialog.h"
|
|
||||||
#include "src/pages/settings/settingspage.h"
|
#include "src/pages/settings/settingspage.h"
|
||||||
#include "src/pages/metadatupdate/metadatupdatepage.h"
|
|
||||||
#include "src/utils/version.h"
|
|
||||||
|
|
||||||
class MainWindow : public ElaWindow
|
class MainWindow : public ElaWindow
|
||||||
{
|
{
|
||||||
|
|
@ -29,38 +25,17 @@ private:
|
||||||
|
|
||||||
QWidget* createBatchConvertPage();
|
QWidget* createBatchConvertPage();
|
||||||
QWidget* createFunctionSearchPage();
|
QWidget* createFunctionSearchPage();
|
||||||
QWidget* createUF20FunctionSearchPage();
|
QWidget* createHelpPage();
|
||||||
QWidget* createUFT3FunctionSearchPage();
|
QWidget* createAboutPage();
|
||||||
QWidget* createSettingsPage();
|
QWidget* createSettingsPage();
|
||||||
QWidget* createMetadataUpdatePage();
|
|
||||||
|
|
||||||
void loadConfigCache();
|
|
||||||
|
|
||||||
void onBatchConvertStart();
|
void onBatchConvertStart();
|
||||||
void onBatchConvertStop();
|
|
||||||
void onPythonRunnerFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
void onPythonRunnerFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
void onPythonRunnerOutput(const QString &output);
|
void onPythonRunnerOutput(const QString &output);
|
||||||
void onPythonRunnerError(const QString &error);
|
void onPythonRunnerError(const QString &error);
|
||||||
|
|
||||||
void updateNavigationButtonIcon();
|
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
|
||||||
void onNavigationButtonClicked();
|
|
||||||
void onNavigationNodeClicked(ElaNavigationType::NavigationNodeType nodeType, QString nodeKey);
|
|
||||||
|
|
||||||
PythonRunner *m_pythonRunner;
|
PythonRunner *m_pythonRunner;
|
||||||
bool m_iconsSet;
|
QTextEdit *m_batchLogEdit;
|
||||||
ElaToolButton* m_navigationButton;
|
|
||||||
bool m_isNavigationExpanded;
|
|
||||||
BatchConvertPage *m_batchConvertPage;
|
|
||||||
|
|
||||||
int m_totalFunctions;
|
|
||||||
int m_currentFunctionIndex;
|
|
||||||
QStringList m_functionList;
|
|
||||||
QString m_helpKey;
|
|
||||||
QString m_aboutKey;
|
|
||||||
QString m_settingKey;
|
|
||||||
QString m_funcSearchKey;
|
|
||||||
QString m_funcConvertKey;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
#include "filedb.h"
|
|
||||||
|
|
||||||
FileDB* FileDB::m_instance = nullptr;
|
|
||||||
|
|
||||||
FileDB::FileDB(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
FileDB* FileDB::instance()
|
|
||||||
{
|
|
||||||
if (!m_instance) {
|
|
||||||
m_instance = new FileDB();
|
|
||||||
}
|
|
||||||
return m_instance;
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef FILEDB_H
|
|
||||||
#define FILEDB_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
class FileDB : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
static FileDB* instance();
|
|
||||||
|
|
||||||
QStringList uft3RealFunctionList;
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit FileDB(QObject *parent = nullptr);
|
|
||||||
static FileDB* m_instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FILEDB_H
|
|
||||||
|
|
@ -1,529 +0,0 @@
|
||||||
#include "metadataprocessor.h"
|
|
||||||
#include "uf2interface.h"
|
|
||||||
#include "uft3interface.h"
|
|
||||||
#include "filedb.h"
|
|
||||||
#include "uf2stdfields.h"
|
|
||||||
#include "uf2datatype.h"
|
|
||||||
#include "uf2errnumber.h"
|
|
||||||
#include "uft3stdfields.h"
|
|
||||||
#include "uft3datatype.h"
|
|
||||||
#include "uft3table.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include "utils/configmanager.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
MetadataProcessor::MetadataProcessor(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetadataProcessor::initConfig(const QString& basePath)
|
|
||||||
{
|
|
||||||
m_basePath = basePath;
|
|
||||||
m_uf2touft3Path = QDir(basePath).filePath("uf2touft3");
|
|
||||||
|
|
||||||
LogManager::instance()->log("========== 初始化配置 ==========");
|
|
||||||
|
|
||||||
ConfigManager* configManager = ConfigManager::instance();
|
|
||||||
|
|
||||||
m_uf20Path = configManager->getValue("projectPath", "uf20");
|
|
||||||
m_ufAcct20Path = configManager->getValue("projectPath", "ufAcct20");
|
|
||||||
m_uftDbSettPath = configManager->getValue("projectPath", "UftdbSett");
|
|
||||||
m_uft30PubPath = configManager->getValue("projectPath", "uft30pub");
|
|
||||||
m_uft30CbptransPath = configManager->getValue("projectPath", "uft30cbptrans");
|
|
||||||
m_uft30Path = configManager->getValue("projectPath", "uft30");
|
|
||||||
|
|
||||||
m_supportUftdbSett = configManager->getValue("testConfig", "supportUftdbSett");
|
|
||||||
m_moduleGenerationCheck = configManager->getValue("testConfig", "moduleGenerationCheck");
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UF2TOUFT3路径: %1").arg(m_uf2touft3Path));
|
|
||||||
LogManager::instance()->log(QString("UF20路径: %1").arg(m_uf20Path));
|
|
||||||
LogManager::instance()->log(QString("UF20会计路径: %1").arg(m_ufAcct20Path));
|
|
||||||
LogManager::instance()->log(QString("UFT数据库设置路径: %1").arg(m_uftDbSettPath));
|
|
||||||
LogManager::instance()->log(QString("UFT30公共路径: %1").arg(m_uft30PubPath));
|
|
||||||
LogManager::instance()->log(QString("UFT30交易路径: %1").arg(m_uft30CbptransPath));
|
|
||||||
LogManager::instance()->log(QString("UFT30路径: %1").arg(m_uft30Path));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool MetadataProcessor::isValidUtf8(const QByteArray& data)
|
|
||||||
{
|
|
||||||
QString test = QString::fromUtf8(data);
|
|
||||||
return test.toUtf8() == data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool MetadataProcessor::writeJson(const QString& filePath, const QJsonObject& jsonObject)
|
|
||||||
{
|
|
||||||
LogManager::instance()->log(QString("准备写入JSON文件: %1, 对象大小: %2").arg(filePath).arg(jsonObject.size()));
|
|
||||||
|
|
||||||
QFile file(filePath);
|
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(filePath));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonDocument doc(jsonObject);
|
|
||||||
qint64 bytesWritten = file.write(doc.toJson(QJsonDocument::Indented));
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("成功写入JSON文件: %1, 写入字节数: %2").arg(filePath).arg(bytesWritten));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject MetadataProcessor::interfaceInfoToUFT3Json(const InterfaceInfo& info)
|
|
||||||
{
|
|
||||||
QJsonObject interfaceJson;
|
|
||||||
interfaceJson["cname"] = info.cname;
|
|
||||||
interfaceJson["eName"] = info.eName;
|
|
||||||
interfaceJson["functionNo"] = info.functionNo;
|
|
||||||
interfaceJson["flag"] = info.flag;
|
|
||||||
interfaceJson["path"] = info.path;
|
|
||||||
interfaceJson["code"] = info.code;
|
|
||||||
interfaceJson["id"] = info.id;
|
|
||||||
interfaceJson["sysStatus"] = info.sysStatus;
|
|
||||||
interfaceJson["description"] = info.description;
|
|
||||||
interfaceJson["moudle"] = info.moudle;
|
|
||||||
|
|
||||||
QJsonObject inputFieldsJson;
|
|
||||||
for (const QString& fieldName : info.inputFields.keys()) {
|
|
||||||
const FieldInfo& field = info.inputFields[fieldName];
|
|
||||||
QJsonObject fieldJson;
|
|
||||||
fieldJson["name"] = field.name;
|
|
||||||
fieldJson["flag"] = field.flag;
|
|
||||||
fieldJson["desc"] = field.desc;
|
|
||||||
fieldJson["uuid"] = field.uuid;
|
|
||||||
inputFieldsJson[fieldName] = fieldJson;
|
|
||||||
}
|
|
||||||
interfaceJson["inputFileds"] = inputFieldsJson;
|
|
||||||
|
|
||||||
QJsonObject outputFieldsJson;
|
|
||||||
for (const QString& fieldName : info.outputFields.keys()) {
|
|
||||||
const FieldInfo& field = info.outputFields[fieldName];
|
|
||||||
QJsonObject fieldJson;
|
|
||||||
fieldJson["name"] = field.name;
|
|
||||||
fieldJson["flag"] = field.flag;
|
|
||||||
fieldJson["desc"] = field.desc;
|
|
||||||
fieldJson["paramType"] = field.paramType;
|
|
||||||
fieldJson["uuid"] = field.uuid;
|
|
||||||
outputFieldsJson[fieldName] = fieldJson;
|
|
||||||
}
|
|
||||||
interfaceJson["outputFileds"] = outputFieldsJson;
|
|
||||||
|
|
||||||
QJsonObject internalFieldsJson;
|
|
||||||
for (const QString& fieldName : info.internalFields.keys()) {
|
|
||||||
const FieldInfo& field = info.internalFields[fieldName];
|
|
||||||
QJsonObject fieldJson;
|
|
||||||
fieldJson["name"] = field.name;
|
|
||||||
fieldJson["type"] = field.type;
|
|
||||||
fieldJson["desc"] = field.desc;
|
|
||||||
fieldJson["paramType"] = field.paramType;
|
|
||||||
fieldJson["uuid"] = field.uuid;
|
|
||||||
internalFieldsJson[fieldName] = fieldJson;
|
|
||||||
}
|
|
||||||
interfaceJson["internalFileds"] = internalFieldsJson;
|
|
||||||
|
|
||||||
return interfaceJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject MetadataProcessor::readJson(const QString& filePath)
|
|
||||||
{
|
|
||||||
QFile file(filePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(filePath));
|
|
||||||
return QJsonObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray data = file.readAll();
|
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
if (doc.isNull()) {
|
|
||||||
LogManager::instance()->logError(QString("无效的 JSON 文件: %1").arg(filePath));
|
|
||||||
return QJsonObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
return doc.object();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString MetadataProcessor::getBasePath() const
|
|
||||||
{
|
|
||||||
return m_basePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetadataProcessor::setBasePath(const QString& path)
|
|
||||||
{
|
|
||||||
m_basePath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataProcessor::processUf2Interfaces(const QString& basePath)
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("========== 开始处理 UF2.0 接口 ==========");
|
|
||||||
LogManager::instance()->log(QString("基础路径(basePath): %1").arg(basePath));
|
|
||||||
|
|
||||||
QString configPath = QDir(m_uf2touft3Path).filePath("config.ini");
|
|
||||||
LogManager::instance()->log(QString("配置文件路径: %1").arg(configPath));
|
|
||||||
|
|
||||||
QStringList completeNameList = {"module.xml", ".project", "冲突检测.wlua"};
|
|
||||||
QStringList containNameList = {".vbusiness", "/公共资源/", "/数据库/", "/脚本/", "/通用数据/", "/.svn/"};
|
|
||||||
|
|
||||||
QMap<QString, QStringList> filterDict;
|
|
||||||
filterDict["completeNameList"] = completeNameList;
|
|
||||||
filterDict["containNameList"] = containNameList;
|
|
||||||
|
|
||||||
QString dirPath = m_uf20Path;
|
|
||||||
QString ufAcct20ProjectDir = m_ufAcct20Path;
|
|
||||||
QString uftDbSett = m_uftDbSettPath;
|
|
||||||
|
|
||||||
QString supportUftdbSett = m_supportUftdbSett;
|
|
||||||
if (supportUftdbSett == "0") {
|
|
||||||
uftDbSett.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UF20 项目路径: %1").arg(dirPath));
|
|
||||||
LogManager::instance()->log(QString("UF20 会计项目路径: %1").arg(ufAcct20ProjectDir));
|
|
||||||
LogManager::instance()->log(QString("UFT 数据库设置路径: %1").arg(uftDbSett));
|
|
||||||
|
|
||||||
QString custJsonPath = QDir(m_uf2touft3Path).filePath("cust.json");
|
|
||||||
LogManager::instance()->log(QString("客户配置文件路径: %1").arg(custJsonPath));
|
|
||||||
QJsonObject custJson = readJson(custJsonPath);
|
|
||||||
|
|
||||||
Uf2Interface uf2;
|
|
||||||
QMap<QString, InterfaceInfo> resultMap = uf2.scanDir(dirPath, ufAcct20ProjectDir, uftDbSett, filterDict);
|
|
||||||
|
|
||||||
QJsonObject resultJson;
|
|
||||||
for (const QString& key : resultMap.keys()) {
|
|
||||||
const InterfaceInfo& info = resultMap[key];
|
|
||||||
|
|
||||||
QJsonObject interfaceJson;
|
|
||||||
interfaceJson["cname"] = info.cname;
|
|
||||||
interfaceJson["eName"] = info.eName;
|
|
||||||
interfaceJson["functionNo"] = info.functionNo;
|
|
||||||
interfaceJson["flag"] = info.flag;
|
|
||||||
interfaceJson["path"] = info.path;
|
|
||||||
interfaceJson["code"] = info.code;
|
|
||||||
interfaceJson["moudle"] = info.moudle;
|
|
||||||
interfaceJson["moudleEName"] = info.moudleEName;
|
|
||||||
interfaceJson["serverType"] = info.serverType;
|
|
||||||
interfaceJson["returnResultSet"] = info.returnResultSet;
|
|
||||||
interfaceJson["needTransMonitor"] = info.needTransMonitor;
|
|
||||||
interfaceJson["checkLicence"] = info.checkLicence;
|
|
||||||
|
|
||||||
QJsonObject inputFieldsJson;
|
|
||||||
for (const QString& fieldName : info.inputFields.keys()) {
|
|
||||||
const FieldInfo& field = info.inputFields[fieldName];
|
|
||||||
QJsonObject fieldJson;
|
|
||||||
fieldJson["name"] = field.name;
|
|
||||||
fieldJson["flag"] = field.flag;
|
|
||||||
fieldJson["desc"] = field.desc;
|
|
||||||
inputFieldsJson[fieldName] = fieldJson;
|
|
||||||
}
|
|
||||||
interfaceJson["inputFileds"] = inputFieldsJson;
|
|
||||||
|
|
||||||
QJsonObject outputFieldsJson;
|
|
||||||
for (const QString& fieldName : info.outputFields.keys()) {
|
|
||||||
const FieldInfo& field = info.outputFields[fieldName];
|
|
||||||
QJsonObject fieldJson;
|
|
||||||
fieldJson["name"] = field.name;
|
|
||||||
fieldJson["flag"] = field.flag;
|
|
||||||
fieldJson["desc"] = field.desc;
|
|
||||||
outputFieldsJson[fieldName] = fieldJson;
|
|
||||||
}
|
|
||||||
interfaceJson["outputFileds"] = outputFieldsJson;
|
|
||||||
|
|
||||||
QJsonObject variableFieldsJson;
|
|
||||||
for (const QString& fieldName : info.variableFields.keys()) {
|
|
||||||
const FieldInfo& field = info.variableFields[fieldName];
|
|
||||||
QJsonObject fieldJson;
|
|
||||||
fieldJson["name"] = field.name;
|
|
||||||
fieldJson["cname"] = field.cname;
|
|
||||||
fieldJson["hsType"] = field.hsType;
|
|
||||||
fieldJson["desc"] = field.desc;
|
|
||||||
variableFieldsJson[fieldName] = fieldJson;
|
|
||||||
}
|
|
||||||
interfaceJson["variableFileds"] = variableFieldsJson;
|
|
||||||
|
|
||||||
resultJson[key] = interfaceJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString outputPath = QDir(m_uf2touft3Path).filePath("uf2.json");
|
|
||||||
|
|
||||||
if (!writeJson(outputPath, resultJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UF2.0 接口处理完成,结果已保存到: %1").arg(outputPath));
|
|
||||||
if (!resultMap.isEmpty()) {
|
|
||||||
QString firstKey = resultMap.keys().first();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataProcessor::processUft3Interfaces(const QString& basePath)
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("========== 开始处理 UFT3.0 接口 ==========");
|
|
||||||
LogManager::instance()->log(QString("基础路径(basePath): %1").arg(basePath));
|
|
||||||
|
|
||||||
QString configPath = QDir(m_uf2touft3Path).filePath("config.ini");
|
|
||||||
LogManager::instance()->log(QString("配置文件路径: %1").arg(configPath));
|
|
||||||
|
|
||||||
QString moduleGenerationCheck = m_moduleGenerationCheck;
|
|
||||||
LogManager::instance()->log(QString("模块生成检查: %1").arg(moduleGenerationCheck));
|
|
||||||
|
|
||||||
QStringList completeNameList = {"module.xml", "project.xml", "冲突检测.wlua"};
|
|
||||||
QStringList containNameList = {".extinterface", ".uftatomfunction", ".uftatomservice", ".uftfunction", ".uftservice"};
|
|
||||||
|
|
||||||
QMap<QString, QStringList> filterDict;
|
|
||||||
filterDict["completeNameList"] = completeNameList;
|
|
||||||
filterDict["containNameList"] = containNameList;
|
|
||||||
|
|
||||||
QString dirPath = m_uft30Path;
|
|
||||||
LogManager::instance()->log(QString("UFT30 项目路径: %1").arg(dirPath));
|
|
||||||
|
|
||||||
Uft3Interface uft3;
|
|
||||||
auto result = uft3.scanDir(dirPath, filterDict, moduleGenerationCheck);
|
|
||||||
|
|
||||||
QMap<QString, InterfaceInfo> resultMap = result.first;
|
|
||||||
QMap<QString, InterfaceInfo> transCodeMap = result.second;
|
|
||||||
|
|
||||||
|
|
||||||
QJsonObject resultJson;
|
|
||||||
for (const QString& key : resultMap.keys()) {
|
|
||||||
const InterfaceInfo& info = resultMap[key];
|
|
||||||
resultJson[key] = interfaceInfoToUFT3Json(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString outputPath = QDir(m_uf2touft3Path).filePath("uft3.json");
|
|
||||||
|
|
||||||
if (!writeJson(outputPath, resultJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject transCodeJson;
|
|
||||||
for (const QString& key : transCodeMap.keys()) {
|
|
||||||
const InterfaceInfo& info = transCodeMap[key];
|
|
||||||
transCodeJson[key] = interfaceInfoToUFT3Json(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString transOutputPath = QDir(m_uf2touft3Path).filePath("uft3Trans.json");
|
|
||||||
|
|
||||||
if (!writeJson(transOutputPath, transCodeJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UFT3.0 接口处理完成,结果已保存到: %1").arg(outputPath));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataProcessor::processUf2DataType()
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("========== 开始处理 UF2.0 数据类型 ==========");
|
|
||||||
|
|
||||||
QString dirPath = m_uf20Path;
|
|
||||||
|
|
||||||
Uf2DataType uf2DataType;
|
|
||||||
auto resultMap = uf2DataType.loadData(dirPath);
|
|
||||||
|
|
||||||
QJsonObject resultJson;
|
|
||||||
for (const QString& key : resultMap.keys()) {
|
|
||||||
const QMap<QString, QString>& typeInfo = resultMap[key];
|
|
||||||
QJsonObject typeJson;
|
|
||||||
for (const QString& attrKey : typeInfo.keys()) {
|
|
||||||
typeJson[attrKey] = typeInfo[attrKey];
|
|
||||||
}
|
|
||||||
resultJson[key] = typeJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString outputPath = QDir(m_uf2touft3Path).filePath("uf2dataType.json");
|
|
||||||
|
|
||||||
if (!writeJson(outputPath, resultJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UF2.0 数据类型处理完成,结果已保存到: %1").arg(outputPath));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataProcessor::processUf2StdFields()
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("========== 开始处理 UF2.0 标准字段 ==========");
|
|
||||||
|
|
||||||
QString dirPath = m_uf20Path;
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> uf2datatypeMap;
|
|
||||||
QString datatypeJsonPath = QDir(m_uf2touft3Path).filePath("uf2dataType.json");
|
|
||||||
QJsonObject datatypeJson = readJson(datatypeJsonPath);
|
|
||||||
for (const QString& key : datatypeJson.keys()) {
|
|
||||||
QJsonObject typeObj = datatypeJson[key].toObject();
|
|
||||||
QMap<QString, QString> typeInfo;
|
|
||||||
for (const QString& attrKey : typeObj.keys()) {
|
|
||||||
typeInfo[attrKey] = typeObj[attrKey].toString();
|
|
||||||
}
|
|
||||||
uf2datatypeMap[key] = typeInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uf2StdFields uf2StdFields;
|
|
||||||
auto resultMap = uf2StdFields.loadData(dirPath, uf2datatypeMap);
|
|
||||||
|
|
||||||
QJsonObject resultJson;
|
|
||||||
for (const QString& key : resultMap.keys()) {
|
|
||||||
const QMap<QString, QString>& fieldInfo = resultMap[key];
|
|
||||||
QJsonObject fieldJson;
|
|
||||||
for (const QString& attrKey : fieldInfo.keys()) {
|
|
||||||
fieldJson[attrKey] = fieldInfo[attrKey];
|
|
||||||
}
|
|
||||||
resultJson[key] = fieldJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString outputPath = QDir(m_uf2touft3Path).filePath("uf2stdfield.json");
|
|
||||||
|
|
||||||
if (!writeJson(outputPath, resultJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UF2.0 标准字段处理完成,结果已保存到: %1").arg(outputPath));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataProcessor::processUf2ErrNumber()
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("========== 开始处理 UF2.0 标准错误号 ==========");
|
|
||||||
|
|
||||||
QString dirPath = m_uf20Path;
|
|
||||||
|
|
||||||
Uf2ErrNumber uf2ErrNumber;
|
|
||||||
auto resultMap = uf2ErrNumber.loadData(dirPath);
|
|
||||||
|
|
||||||
QJsonObject resultJson;
|
|
||||||
for (const QString& key : resultMap.keys()) {
|
|
||||||
const QMap<QString, QString>& errorInfo = resultMap[key];
|
|
||||||
QJsonObject errorJson;
|
|
||||||
for (const QString& attrKey : errorInfo.keys()) {
|
|
||||||
errorJson[attrKey] = errorInfo[attrKey];
|
|
||||||
}
|
|
||||||
resultJson[key] = errorJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString outputPath = QDir(m_uf2touft3Path).filePath("uf2Error.json");
|
|
||||||
|
|
||||||
if (!writeJson(outputPath, resultJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UF2.0 标准错误号处理完成,结果已保存到: %1").arg(outputPath));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataProcessor::processUft3DataType()
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("========== 开始处理 UFT3.0 数据类型 ==========");
|
|
||||||
|
|
||||||
QString dirPath = m_uft30PubPath;
|
|
||||||
|
|
||||||
Uft3DataType uft3DataType;
|
|
||||||
auto resultMap = uft3DataType.loadData(dirPath);
|
|
||||||
|
|
||||||
QJsonObject resultJson;
|
|
||||||
for (const QString& key : resultMap.keys()) {
|
|
||||||
const QMap<QString, QString>& typeInfo = resultMap[key];
|
|
||||||
QJsonObject typeJson;
|
|
||||||
for (const QString& attrKey : typeInfo.keys()) {
|
|
||||||
typeJson[attrKey] = typeInfo[attrKey];
|
|
||||||
}
|
|
||||||
resultJson[key] = typeJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString outputPath = QDir(m_uf2touft3Path).filePath("uft3datatype.json");
|
|
||||||
|
|
||||||
if (!writeJson(outputPath, resultJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UFT3.0 数据类型处理完成,结果已保存到: %1").arg(outputPath));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataProcessor::processUft3StdFields()
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("========== 开始处理 UFT3.0 标准字段 ==========");
|
|
||||||
|
|
||||||
QString dirPath = m_uft30PubPath;
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> uf3datatypeMap;
|
|
||||||
QString datatypeJsonPath = QDir(m_uf2touft3Path).filePath("uft3datatype.json");
|
|
||||||
QJsonObject datatypeJson = readJson(datatypeJsonPath);
|
|
||||||
for (const QString& key : datatypeJson.keys()) {
|
|
||||||
QJsonObject typeObj = datatypeJson[key].toObject();
|
|
||||||
QMap<QString, QString> typeInfo;
|
|
||||||
for (const QString& attrKey : typeObj.keys()) {
|
|
||||||
typeInfo[attrKey] = typeObj[attrKey].toString();
|
|
||||||
}
|
|
||||||
uf3datatypeMap[key] = typeInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uft3StdFields uft3StdFields;
|
|
||||||
auto resultMap = uft3StdFields.loadData(dirPath, uf3datatypeMap);
|
|
||||||
|
|
||||||
QJsonObject resultJson;
|
|
||||||
for (const QString& key : resultMap.keys()) {
|
|
||||||
const QMap<QString, QString>& fieldInfo = resultMap[key];
|
|
||||||
QJsonObject fieldJson;
|
|
||||||
for (const QString& attrKey : fieldInfo.keys()) {
|
|
||||||
fieldJson[attrKey] = fieldInfo[attrKey];
|
|
||||||
}
|
|
||||||
resultJson[key] = fieldJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString outputPath = QDir(m_uf2touft3Path).filePath("uft3stdfields.json");
|
|
||||||
|
|
||||||
if (!writeJson(outputPath, resultJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UFT3.0 标准字段处理完成,结果已保存到: %1").arg(outputPath));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MetadataProcessor::processUft3Table()
|
|
||||||
{
|
|
||||||
LogManager::instance()->log("========== 开始处理 UFT3.0 表结构 ==========");
|
|
||||||
|
|
||||||
QString dirPath = m_uft30PubPath;
|
|
||||||
|
|
||||||
Uft3Table uft3Table;
|
|
||||||
auto resultMap = uft3Table.loadData(dirPath);
|
|
||||||
|
|
||||||
QJsonObject resultJson;
|
|
||||||
for (const QString& key : resultMap.keys()) {
|
|
||||||
const QMap<QString, QVariant>& tableInfo = resultMap[key];
|
|
||||||
QJsonObject tableJson;
|
|
||||||
for (const QString& attrKey : tableInfo.keys()) {
|
|
||||||
QVariant value = tableInfo[attrKey];
|
|
||||||
if (value.canConvert<QJsonValue>()) {
|
|
||||||
tableJson[attrKey] = value.toJsonValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resultJson[key] = tableJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString outputPath = QDir(m_uf2touft3Path).filePath("uft3Table.json");
|
|
||||||
|
|
||||||
if (!writeJson(outputPath, resultJson)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UFT3.0 表结构处理完成,结果已保存到: %1").arg(outputPath));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
#ifndef METADATAPROCESSOR_H
|
|
||||||
#define METADATAPROCESSOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
struct InterfaceInfo;
|
|
||||||
|
|
||||||
class MetadataProcessor : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit MetadataProcessor(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
bool processUf2Interfaces(const QString& basePath);
|
|
||||||
bool processUft3Interfaces(const QString& basePath);
|
|
||||||
|
|
||||||
bool processUf2StdFields();
|
|
||||||
bool processUf2DataType();
|
|
||||||
bool processUf2ErrNumber();
|
|
||||||
|
|
||||||
bool processUft3StdFields();
|
|
||||||
bool processUft3DataType();
|
|
||||||
bool processUft3Table();
|
|
||||||
|
|
||||||
QString getBasePath() const;
|
|
||||||
void setBasePath(const QString& path);
|
|
||||||
|
|
||||||
public:
|
|
||||||
void initConfig(const QString& basePath);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isValidUtf8(const QByteArray& data);
|
|
||||||
bool writeJson(const QString& filePath, const QJsonObject& jsonObject);
|
|
||||||
QJsonObject readJson(const QString& filePath);
|
|
||||||
QJsonObject interfaceInfoToUFT3Json(const InterfaceInfo& info);
|
|
||||||
|
|
||||||
QString m_basePath;
|
|
||||||
QString m_uf2touft3Path;
|
|
||||||
|
|
||||||
QString m_uf20Path;
|
|
||||||
QString m_ufAcct20Path;
|
|
||||||
QString m_uftDbSettPath;
|
|
||||||
QString m_uft30PubPath;
|
|
||||||
QString m_uft30CbptransPath;
|
|
||||||
QString m_uft30Path;
|
|
||||||
|
|
||||||
QString m_supportUftdbSett;
|
|
||||||
QString m_moduleGenerationCheck;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // METADATAPROCESSOR_H
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
#include "uf2datatype.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
|
|
||||||
Uf2DataType::Uf2DataType(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> Uf2DataType::loadData(const QString& dirPath)
|
|
||||||
{
|
|
||||||
QMap<QString, QMap<QString, QString>> resultMap;
|
|
||||||
|
|
||||||
QString filePath = dirPath;
|
|
||||||
filePath.replace('\\', '/');
|
|
||||||
filePath += "/公共资源/datatypes.xml";
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("加载UF2数据类型文件: %1").arg(filePath));
|
|
||||||
|
|
||||||
QFile file(filePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(filePath));
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
|
|
||||||
if (elementName == "userType") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
QString hsType = attrs.value("name").toString();
|
|
||||||
|
|
||||||
QString cValue = "";
|
|
||||||
QString oValue = "";
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString childElementName = xml.name().toString();
|
|
||||||
|
|
||||||
if (childElementName == "language") {
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
token = xml.readNext();
|
|
||||||
if (token == QXmlStreamReader::StartElement && xml.name().toString() == "map") {
|
|
||||||
cValue = xml.attributes().value("value").toString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (childElementName == "database") {
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
token = xml.readNext();
|
|
||||||
if (token == QXmlStreamReader::StartElement && xml.name().toString() == "map") {
|
|
||||||
oValue = xml.attributes().value("value").toString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (token == QXmlStreamReader::EndElement && xml.name().toString() == "userType") {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QString> typeInfo;
|
|
||||||
typeInfo["HsType"] = hsType;
|
|
||||||
typeInfo["CType"] = cValue;
|
|
||||||
typeInfo["OType"] = oValue;
|
|
||||||
|
|
||||||
resultMap[hsType] = typeInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
LogManager::instance()->log(QString("UF2数据类型加载完成,共 %1 条").arg(resultMap.size()));
|
|
||||||
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#ifndef UF2DATATYPE_H
|
|
||||||
#define UF2DATATYPE_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
class Uf2DataType : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Uf2DataType(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> loadData(const QString& dirPath);
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
#include "uf2errnumber.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
|
|
||||||
Uf2ErrNumber::Uf2ErrNumber(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> Uf2ErrNumber::loadData(const QString& dirPath)
|
|
||||||
{
|
|
||||||
QMap<QString, QMap<QString, QString>> resultMap;
|
|
||||||
|
|
||||||
QString filePath = dirPath;
|
|
||||||
filePath.replace('\\', '/');
|
|
||||||
filePath += "/公共资源/errNumbers.xml";
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("加载UF2错误号文件: %1").arg(filePath));
|
|
||||||
|
|
||||||
QFile file(filePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(filePath));
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
|
|
||||||
if (elementName == "error_no") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
|
|
||||||
QString sErrorNo = attrs.value("code").toString();
|
|
||||||
QString sConstant = attrs.value("constant").toString();
|
|
||||||
QString sErrorInfo = attrs.value("info").toString();
|
|
||||||
|
|
||||||
QMap<QString, QString> errorInfo;
|
|
||||||
errorInfo["code"] = sErrorNo;
|
|
||||||
errorInfo["constant"] = sConstant;
|
|
||||||
errorInfo["info"] = sErrorInfo;
|
|
||||||
|
|
||||||
resultMap[sConstant] = errorInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
LogManager::instance()->log(QString("UF2错误号加载完成,共 %1 条").arg(resultMap.size()));
|
|
||||||
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#ifndef UF2ERRNUMBER_H
|
|
||||||
#define UF2ERRNUMBER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
class Uf2ErrNumber : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Uf2ErrNumber(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> loadData(const QString& dirPath);
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,273 +0,0 @@
|
||||||
#include "uf2interface.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QStack>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
Uf2Interface::Uf2Interface(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceInfo Uf2Interface::loadInterface(const QString& filePath)
|
|
||||||
{
|
|
||||||
InterfaceInfo result;
|
|
||||||
result.path = filePath;
|
|
||||||
|
|
||||||
QString sFilePath = filePath;
|
|
||||||
sFilePath.replace('\\', '/');
|
|
||||||
|
|
||||||
QFileInfo fileInfo(sFilePath);
|
|
||||||
if (!fileInfo.exists()) {
|
|
||||||
LogManager::instance()->logError(QString("%1 文件不存在!").arg(sFilePath));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString sCodeName = fileInfo.baseName();
|
|
||||||
result.cname = sCodeName;
|
|
||||||
|
|
||||||
QFile file(sFilePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("%1 无法打开文件").arg(sFilePath));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
|
||||||
QStack<QString> elementStack;
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
elementStack.push(elementName);
|
|
||||||
|
|
||||||
if (elementName == "basic") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
if (attrs.hasAttribute("englishName")) {
|
|
||||||
result.eName = attrs.value("englishName").toString();
|
|
||||||
}
|
|
||||||
if (attrs.hasAttribute("objectId")) {
|
|
||||||
result.functionNo = attrs.value("objectId").toString();
|
|
||||||
}
|
|
||||||
if (attrs.hasAttribute("flag")) {
|
|
||||||
result.flag = attrs.value("flag").toString();
|
|
||||||
}
|
|
||||||
if (attrs.hasAttribute("checkLicence")) {
|
|
||||||
result.checkLicence = (attrs.value("checkLicence").toString() == "true");
|
|
||||||
}
|
|
||||||
if (attrs.hasAttribute("returnResultSet")) {
|
|
||||||
result.returnResultSet = (attrs.value("returnResultSet").toString() == "true");
|
|
||||||
}
|
|
||||||
if (attrs.hasAttribute("needTransMonitor")) {
|
|
||||||
result.needTransMonitor = (attrs.value("needTransMonitor").toString() == "true");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (elementName == "stdFieldQuote") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
|
|
||||||
QString parentName = elementStack.size() > 1 ? elementStack[elementStack.size() - 2] : QString();
|
|
||||||
|
|
||||||
FieldInfo field;
|
|
||||||
field.name = attrs.value("name").toString();
|
|
||||||
field.flag = attrs.value("flag").toString();
|
|
||||||
field.desc = attrs.value("comment").toString();
|
|
||||||
|
|
||||||
if (parentName == "import") {
|
|
||||||
result.inputFields[field.name] = field;
|
|
||||||
} else if (parentName == "export") {
|
|
||||||
result.outputFields[field.name] = field;
|
|
||||||
if (field.flag.contains("IO")) {
|
|
||||||
result.inputFields[field.name] = field;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (elementName == "variableField") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
FieldInfo field;
|
|
||||||
field.name = attrs.value("name").toString();
|
|
||||||
field.cname = attrs.value("cname").toString();
|
|
||||||
field.hsType = attrs.value("type").toString();
|
|
||||||
field.desc = attrs.value("desc").toString();
|
|
||||||
result.variableFields[field.name] = field;
|
|
||||||
}
|
|
||||||
else if (elementName == "code") {
|
|
||||||
result.code = xml.readElementText();
|
|
||||||
if (filePath.contains("不用编译")) {
|
|
||||||
result.code.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (token == QXmlStreamReader::EndElement) {
|
|
||||||
if (!elementStack.isEmpty()) {
|
|
||||||
elementStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Uf2Interface::getModuleEName(const QString& moduleXmlPath)
|
|
||||||
{
|
|
||||||
QFile file(moduleXmlPath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
if (elementName == "info") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
if (attrs.hasAttribute("ename")) {
|
|
||||||
return attrs.value("ename").toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Uf2Interface::shouldFilter(const QString& filePath,
|
|
||||||
const QStringList& completeNameList,
|
|
||||||
const QStringList& containNameList)
|
|
||||||
{
|
|
||||||
QFileInfo fileInfo(filePath);
|
|
||||||
QString fileName = fileInfo.fileName();
|
|
||||||
|
|
||||||
if (completeNameList.contains(fileName)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const QString& name : containNameList) {
|
|
||||||
if (filePath.contains(name, Qt::CaseInsensitive)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, InterfaceInfo> Uf2Interface::scanDir(const QString& dirPath,
|
|
||||||
const QString& ufAcct20ProjectDir,
|
|
||||||
const QString& uftDbSett,
|
|
||||||
const QMap<QString, QStringList>& fileFilterDict)
|
|
||||||
{
|
|
||||||
QMap<QString, InterfaceInfo> resultMap;
|
|
||||||
QStringList completeNameList = fileFilterDict.value("completeNameList");
|
|
||||||
QStringList containNameList = fileFilterDict.value("containNameList");
|
|
||||||
|
|
||||||
QMap<QString, QString> moduleCodeMap;
|
|
||||||
moduleCodeMap["转融通"] = "ref";
|
|
||||||
|
|
||||||
std::function<void(const QString&)> scanModuleXmlRecursive;
|
|
||||||
scanModuleXmlRecursive = [&](const QString& path) {
|
|
||||||
if (path.isEmpty()) return;
|
|
||||||
QDir dir(path);
|
|
||||||
QStringList filters;
|
|
||||||
filters << "module.xml";
|
|
||||||
|
|
||||||
QFileInfoList fileList = dir.entryInfoList(filters, QDir::Files);
|
|
||||||
for (const QFileInfo& fileInfo : fileList) {
|
|
||||||
QString filePath = fileInfo.absoluteFilePath();
|
|
||||||
filePath.replace('\\', '/');
|
|
||||||
|
|
||||||
if (filePath.contains("/数据库/")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString modName = fileInfo.dir().dirName();
|
|
||||||
QString modEName = getModuleEName(filePath);
|
|
||||||
moduleCodeMap[modName] = modEName;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfoList dirList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
for (const QFileInfo& dirInfo : dirList) {
|
|
||||||
scanModuleXmlRecursive(dirInfo.absoluteFilePath());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto scanModuleXml = [&](const QString& path) {
|
|
||||||
scanModuleXmlRecursive(path);
|
|
||||||
};
|
|
||||||
|
|
||||||
scanModuleXml(dirPath);
|
|
||||||
scanModuleXml(ufAcct20ProjectDir);
|
|
||||||
scanModuleXml(uftDbSett);
|
|
||||||
|
|
||||||
std::function<void(const QString&, const QString&)> scanInterfaceFilesRecursive;
|
|
||||||
scanInterfaceFilesRecursive = [&](const QString& path, const QString& serverType) {
|
|
||||||
if (path.isEmpty()) {
|
|
||||||
LogManager::instance()->log("路径为空,跳过");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QDir dir(path);
|
|
||||||
if (!dir.exists()) {
|
|
||||||
LogManager::instance()->log(QString("目录不存在: %1").arg(path));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QStringList filters;
|
|
||||||
filters << "*.*";
|
|
||||||
|
|
||||||
QFileInfoList fileList = dir.entryInfoList(filters, QDir::Files);
|
|
||||||
for (const QFileInfo& fileInfo : fileList) {
|
|
||||||
QString filePath = fileInfo.absoluteFilePath();
|
|
||||||
filePath.replace('\\', '/');
|
|
||||||
if (shouldFilter(filePath, completeNameList, containNameList)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString sFilePath = filePath;
|
|
||||||
int lastSlash = sFilePath.lastIndexOf('/');
|
|
||||||
QString pathWithoutFile = sFilePath.left(lastSlash);
|
|
||||||
int secondLastSlash = pathWithoutFile.lastIndexOf('/');
|
|
||||||
QString pathWithoutLastDir = pathWithoutFile.left(secondLastSlash);
|
|
||||||
int thirdLastSlash = pathWithoutLastDir.lastIndexOf('/');
|
|
||||||
QString modName = pathWithoutLastDir.mid(thirdLastSlash + 1);
|
|
||||||
|
|
||||||
InterfaceInfo interfaceInfo = loadInterface(filePath);
|
|
||||||
interfaceInfo.moudle = modName;
|
|
||||||
QString moudleEName = moduleCodeMap.value(modName);
|
|
||||||
interfaceInfo.moudleEName = moudleEName;
|
|
||||||
interfaceInfo.serverType = serverType;
|
|
||||||
|
|
||||||
QString key = interfaceInfo.cname;
|
|
||||||
if (resultMap.contains(key)) {
|
|
||||||
QString existingPath = resultMap[key].path;
|
|
||||||
if (existingPath.contains("不用编译")) {
|
|
||||||
resultMap[key] = interfaceInfo;
|
|
||||||
} else if (!filePath.contains("不用编译")) {
|
|
||||||
LogManager::instance()->logWarning(QString("存在重复接口名: %1").arg(key));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resultMap[key] = interfaceInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfoList dirList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
for (const QFileInfo& dirInfo : dirList) {
|
|
||||||
QString subDirPath = dirInfo.absoluteFilePath();
|
|
||||||
subDirPath.replace('\\', '/');
|
|
||||||
scanInterfaceFilesRecursive(subDirPath, serverType);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto scanInterfaceFiles = [&](const QString& path, const QString& serverType) {
|
|
||||||
scanInterfaceFilesRecursive(path, serverType);
|
|
||||||
};
|
|
||||||
|
|
||||||
scanInterfaceFiles(dirPath, "trade");
|
|
||||||
scanInterfaceFiles(ufAcct20ProjectDir, "acct");
|
|
||||||
scanInterfaceFiles(uftDbSett, "dbsett");
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("扫描完成,共找到 %1 个接口").arg(resultMap.size()));
|
|
||||||
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
#ifndef UF2INTERFACE_H
|
|
||||||
#define UF2INTERFACE_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
|
|
||||||
struct FieldInfo {
|
|
||||||
QString name;
|
|
||||||
QString flag;
|
|
||||||
QString desc;
|
|
||||||
QString uuid;
|
|
||||||
QString paramType;
|
|
||||||
QString type;
|
|
||||||
QString cname;
|
|
||||||
QString hsType;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InterfaceInfo {
|
|
||||||
QString cname;
|
|
||||||
QString eName;
|
|
||||||
QString functionNo;
|
|
||||||
QString flag;
|
|
||||||
QString path;
|
|
||||||
QString code;
|
|
||||||
QString id;
|
|
||||||
QString sysStatus;
|
|
||||||
QString description;
|
|
||||||
QString moudle;
|
|
||||||
QString moudleEName;
|
|
||||||
QString serverType;
|
|
||||||
bool returnResultSet = false;
|
|
||||||
bool needTransMonitor = false;
|
|
||||||
bool checkLicence = false;
|
|
||||||
|
|
||||||
QMap<QString, FieldInfo> inputFields;
|
|
||||||
QMap<QString, FieldInfo> outputFields;
|
|
||||||
QMap<QString, FieldInfo> variableFields;
|
|
||||||
QMap<QString, FieldInfo> internalFields;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Uf2Interface : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Uf2Interface(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
InterfaceInfo loadInterface(const QString& filePath);
|
|
||||||
QMap<QString, InterfaceInfo> scanDir(const QString& dirPath,
|
|
||||||
const QString& ufAcct20ProjectDir,
|
|
||||||
const QString& uftDbSett,
|
|
||||||
const QMap<QString, QStringList>& fileFilterDict);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString getModuleEName(const QString& moduleXmlPath);
|
|
||||||
bool shouldFilter(const QString& filePath,
|
|
||||||
const QStringList& completeNameList,
|
|
||||||
const QStringList& containNameList);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // UF2INTERFACE_H
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
#include "uf2stdfields.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
|
|
||||||
Uf2StdFields::Uf2StdFields(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> Uf2StdFields::loadData(
|
|
||||||
const QString& dirPath,
|
|
||||||
const QMap<QString, QMap<QString, QString>>& uf2datatypeMap)
|
|
||||||
{
|
|
||||||
QMap<QString, QMap<QString, QString>> resultMap;
|
|
||||||
|
|
||||||
QString filePath = dirPath;
|
|
||||||
filePath.replace('\\', '/');
|
|
||||||
filePath += "/公共资源/stdfields.xml";
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("加载UF2标准字段文件: %1").arg(filePath));
|
|
||||||
|
|
||||||
QFile file(filePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(filePath));
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
|
|
||||||
if (elementName == "stdfield") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
|
|
||||||
QString sFieldName = attrs.value("name").toString();
|
|
||||||
QString sCname = attrs.value("cname").toString();
|
|
||||||
QString sType = attrs.value("type").toString();
|
|
||||||
QString sDesc = attrs.value("desc").toString();
|
|
||||||
sDesc.replace("'", "\"");
|
|
||||||
QString sDictId = attrs.value("dict").toString();
|
|
||||||
|
|
||||||
QString sCtype = "";
|
|
||||||
QString sOType = "";
|
|
||||||
|
|
||||||
if (uf2datatypeMap.contains(sType)) {
|
|
||||||
sCtype = uf2datatypeMap[sType].value("CType");
|
|
||||||
sOType = uf2datatypeMap[sType].value("OType");
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QString> fieldInfo;
|
|
||||||
fieldInfo["name"] = sFieldName;
|
|
||||||
fieldInfo["cname"] = sCname;
|
|
||||||
fieldInfo["type"] = sType;
|
|
||||||
fieldInfo["desc"] = sDesc;
|
|
||||||
fieldInfo["dict"] = sDictId;
|
|
||||||
fieldInfo["cType"] = sCtype;
|
|
||||||
fieldInfo["oType"] = sOType;
|
|
||||||
|
|
||||||
resultMap[sFieldName] = fieldInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
LogManager::instance()->log(QString("UF2标准字段加载完成,共 %1 条").arg(resultMap.size()));
|
|
||||||
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef UF2STDFIELDS_H
|
|
||||||
#define UF2STDFIELDS_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
class Uf2StdFields : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Uf2StdFields(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> loadData(const QString& dirPath,
|
|
||||||
const QMap<QString, QMap<QString, QString>>& uf2datatypeMap);
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
#include "uft3datatype.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
|
|
||||||
Uft3DataType::Uft3DataType(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> Uft3DataType::loadData(const QString& dirPath)
|
|
||||||
{
|
|
||||||
QMap<QString, QMap<QString, QString>> resultMap;
|
|
||||||
|
|
||||||
QString filePath = dirPath;
|
|
||||||
filePath.replace('\\', '/');
|
|
||||||
filePath += "/metadata/datatype.datatype";
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("加载UFT3数据类型文件: %1").arg(filePath));
|
|
||||||
|
|
||||||
QFile file(filePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(filePath));
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
|
|
||||||
if (elementName == "items") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
|
|
||||||
QString hsType = attrs.value("name").toString();
|
|
||||||
QString uftValue = attrs.value("stdType").toString();
|
|
||||||
QString uftLen = "0";
|
|
||||||
|
|
||||||
if (uftValue.toLower() == "string") {
|
|
||||||
uftLen = attrs.value("length").toString();
|
|
||||||
uftValue = "char[" + uftLen + "]";
|
|
||||||
}
|
|
||||||
else if (uftValue.toLower() == "int32") {
|
|
||||||
uftValue = "int";
|
|
||||||
}
|
|
||||||
else if (uftValue.toLower() == "int64") {
|
|
||||||
uftValue = "double";
|
|
||||||
}
|
|
||||||
else if (uftValue.toLower() == "double") {
|
|
||||||
uftValue = "double";
|
|
||||||
}
|
|
||||||
else if (uftValue.toLower() == "char") {
|
|
||||||
uftValue = "char";
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QString> typeInfo;
|
|
||||||
typeInfo["HsType"] = hsType;
|
|
||||||
typeInfo["uftType"] = uftValue;
|
|
||||||
|
|
||||||
resultMap[hsType] = typeInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
LogManager::instance()->log(QString("UFT3数据类型加载完成,共 %1 条").arg(resultMap.size()));
|
|
||||||
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#ifndef TFT3DATATYPE_H
|
|
||||||
#define TFT3DATATYPE_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
class Uft3DataType : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Uft3DataType(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> loadData(const QString& dirPath);
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,245 +0,0 @@
|
||||||
#include "uft3interface.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include "filedb.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QTextStream>
|
|
||||||
|
|
||||||
Uft3Interface::Uft3Interface(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceInfo Uft3Interface::loadInterface(const QString& filePath)
|
|
||||||
{
|
|
||||||
InterfaceInfo result;
|
|
||||||
result.path = filePath;
|
|
||||||
|
|
||||||
QString sFilePath = filePath;
|
|
||||||
sFilePath.replace('\\', '/');
|
|
||||||
|
|
||||||
QFileInfo fileInfo(sFilePath);
|
|
||||||
if (!fileInfo.exists()) {
|
|
||||||
LogManager::instance()->logError(QString("文件不存在: %1").arg(sFilePath));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile file(sFilePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(sFilePath));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextStream in(&file);
|
|
||||||
QString line = in.readLine();
|
|
||||||
line = in.readLine();
|
|
||||||
|
|
||||||
if (!line.isEmpty()) {
|
|
||||||
int pos = line.indexOf("chineseName=\"");
|
|
||||||
if (pos != -1) {
|
|
||||||
pos += QString("chineseName=\"").length();
|
|
||||||
int endPos = line.indexOf('"', pos);
|
|
||||||
if (endPos != -1) {
|
|
||||||
result.cname = line.mid(pos, endPos - pos).trimmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = line.indexOf("objectId=\"");
|
|
||||||
if (pos != -1) {
|
|
||||||
pos += QString("objectId=\"").length();
|
|
||||||
int endPos = line.indexOf('"', pos);
|
|
||||||
if (endPos != -1) {
|
|
||||||
result.functionNo = line.mid(pos, endPos - pos).trimmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = line.indexOf("description=\"");
|
|
||||||
if (pos != -1) {
|
|
||||||
pos += QString("description=\"").length();
|
|
||||||
int endPos = line.indexOf('"', pos);
|
|
||||||
if (endPos != -1) {
|
|
||||||
result.description = line.mid(pos, endPos - pos).trimmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = line.indexOf("interfaceFlag=\"");
|
|
||||||
if (pos != -1) {
|
|
||||||
pos += QString("interfaceFlag=\"").length();
|
|
||||||
int endPos = line.indexOf('"', pos);
|
|
||||||
if (endPos != -1) {
|
|
||||||
result.flag = line.mid(pos, endPos - pos).trimmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = line.indexOf("id=\"");
|
|
||||||
if (pos != -1) {
|
|
||||||
pos += QString("id=\"").length();
|
|
||||||
int endPos = line.indexOf('"', pos);
|
|
||||||
if (endPos != -1) {
|
|
||||||
result.id = line.mid(pos, endPos - pos).trimmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = line.indexOf("sysStatus=\"");
|
|
||||||
if (pos != -1) {
|
|
||||||
pos += QString("sysStatus=\"").length();
|
|
||||||
int endPos = line.indexOf('"', pos);
|
|
||||||
if (endPos != -1) {
|
|
||||||
result.sysStatus = line.mid(pos, endPos - pos).trimmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.eName = fileInfo.baseName();
|
|
||||||
|
|
||||||
file.seek(0);
|
|
||||||
QXmlStreamReader xml(&file);
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
|
|
||||||
if (elementName == "inputParameters") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
FieldInfo field;
|
|
||||||
field.name = attrs.value("id").toString();
|
|
||||||
field.flag = attrs.value("flags").toString();
|
|
||||||
field.desc = attrs.value("comments").toString();
|
|
||||||
field.uuid = attrs.value("uuid").toString();
|
|
||||||
result.inputFields[field.name] = field;
|
|
||||||
}
|
|
||||||
else if (elementName == "outputParameters") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
FieldInfo field;
|
|
||||||
field.name = attrs.value("id").toString();
|
|
||||||
field.flag = attrs.value("flags").toString();
|
|
||||||
field.desc = attrs.value("comments").toString();
|
|
||||||
field.paramType = attrs.value("paramType").toString();
|
|
||||||
field.uuid = attrs.value("uuid").toString();
|
|
||||||
result.outputFields[field.name] = field;
|
|
||||||
|
|
||||||
if (field.flag.contains("IO")) {
|
|
||||||
result.inputFields[field.name] = field;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (elementName == "internalParams") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
FieldInfo field;
|
|
||||||
field.name = attrs.value("id").toString();
|
|
||||||
field.type = attrs.value("type").toString();
|
|
||||||
field.desc = attrs.value("name").toString();
|
|
||||||
field.paramType = attrs.value("paramType").toString();
|
|
||||||
field.uuid = attrs.value("uuid").toString();
|
|
||||||
result.internalFields[field.name] = field;
|
|
||||||
}
|
|
||||||
else if (elementName == "code") {
|
|
||||||
result.code = xml.readElementText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
if (!result.functionNo.isEmpty() && !FileDB::instance()->uft3RealFunctionList.contains(result.functionNo)) {
|
|
||||||
FileDB::instance()->uft3RealFunctionList.append(result.functionNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Uft3Interface::shouldFilter(const QString& filePath,
|
|
||||||
const QString& dirPath,
|
|
||||||
const QStringList& completeNameList,
|
|
||||||
const QStringList& containNameList,
|
|
||||||
const QString& moduleGenerationCheck)
|
|
||||||
{
|
|
||||||
QFileInfo fileInfo(filePath);
|
|
||||||
QString fileName = fileInfo.fileName();
|
|
||||||
QString relPath = filePath.mid(dirPath.length());
|
|
||||||
|
|
||||||
if (completeNameList.contains(fileName)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dotPos = relPath.indexOf('.');
|
|
||||||
QString suffix;
|
|
||||||
if (dotPos != -1) {
|
|
||||||
suffix = relPath.mid(dotPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!containNameList.contains(suffix)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moduleGenerationCheck == "1") {
|
|
||||||
if (filePath.contains("/cbp/") || filePath.contains("/ucbp/")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Uft3Interface::scanDirRecursive(const QString& dirPath,
|
|
||||||
const QStringList& completeNameList,
|
|
||||||
const QStringList& containNameList,
|
|
||||||
const QString& moduleGenerationCheck,
|
|
||||||
QMap<QString, InterfaceInfo>& resultMap,
|
|
||||||
QMap<QString, InterfaceInfo>& transCodeMap)
|
|
||||||
{
|
|
||||||
QDir dir(dirPath);
|
|
||||||
QStringList filters;
|
|
||||||
filters << "*.*";
|
|
||||||
|
|
||||||
QFileInfoList fileList = dir.entryInfoList(filters, QDir::Files);
|
|
||||||
for (const QFileInfo& fileInfo : fileList) {
|
|
||||||
QString filePath = fileInfo.absoluteFilePath();
|
|
||||||
filePath.replace('\\', '/');
|
|
||||||
|
|
||||||
if (shouldFilter(filePath, dirPath, completeNameList, containNameList, moduleGenerationCheck)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isTransCode = (filePath.contains("/cbptrans/") ||
|
|
||||||
filePath.contains("/mgrcbptrans/") ||
|
|
||||||
filePath.contains("/converttrans/") ||
|
|
||||||
filePath.contains("/ses/")) &&
|
|
||||||
!filePath.contains("/cbptrans/cbptranspub/");
|
|
||||||
|
|
||||||
QString modName = fileInfo.dir().dirName();
|
|
||||||
InterfaceInfo interfaceInfo = loadInterface(filePath);
|
|
||||||
interfaceInfo.moudle = modName;
|
|
||||||
|
|
||||||
if (isTransCode) {
|
|
||||||
transCodeMap[interfaceInfo.cname] = interfaceInfo;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
resultMap[interfaceInfo.cname] = interfaceInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfoList dirList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
for (const QFileInfo& dirInfo : dirList) {
|
|
||||||
scanDirRecursive(dirInfo.absoluteFilePath(), completeNameList,
|
|
||||||
containNameList, moduleGenerationCheck, resultMap, transCodeMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPair<QMap<QString, InterfaceInfo>, QMap<QString, InterfaceInfo>>
|
|
||||||
Uft3Interface::scanDir(const QString& dirPath,
|
|
||||||
const QMap<QString, QStringList>& fileFilterDict,
|
|
||||||
const QString& moduleGenerationCheck)
|
|
||||||
{
|
|
||||||
QMap<QString, InterfaceInfo> resultMap;
|
|
||||||
QMap<QString, InterfaceInfo> transCodeMap;
|
|
||||||
|
|
||||||
QStringList completeNameList = fileFilterDict.value("completeNameList");
|
|
||||||
QStringList containNameList = fileFilterDict.value("containNameList");
|
|
||||||
|
|
||||||
scanDirRecursive(dirPath, completeNameList, containNameList, moduleGenerationCheck, resultMap, transCodeMap);
|
|
||||||
|
|
||||||
return qMakePair(resultMap, transCodeMap);
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
#ifndef UFT3INTERFACE_H
|
|
||||||
#define UFT3INTERFACE_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
#include <QPair>
|
|
||||||
|
|
||||||
#include "uf2interface.h"
|
|
||||||
|
|
||||||
class Uft3Interface : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Uft3Interface(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
InterfaceInfo loadInterface(const QString& filePath);
|
|
||||||
QPair<QMap<QString, InterfaceInfo>, QMap<QString, InterfaceInfo>>
|
|
||||||
scanDir(const QString& dirPath,
|
|
||||||
const QMap<QString, QStringList>& fileFilterDict,
|
|
||||||
const QString& moduleGenerationCheck);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool shouldFilter(const QString& filePath,
|
|
||||||
const QString& dirPath,
|
|
||||||
const QStringList& completeNameList,
|
|
||||||
const QStringList& containNameList,
|
|
||||||
const QString& moduleGenerationCheck);
|
|
||||||
|
|
||||||
void scanDirRecursive(const QString& dirPath,
|
|
||||||
const QStringList& completeNameList,
|
|
||||||
const QStringList& containNameList,
|
|
||||||
const QString& moduleGenerationCheck,
|
|
||||||
QMap<QString, InterfaceInfo>& resultMap,
|
|
||||||
QMap<QString, InterfaceInfo>& transCodeMap);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // UFT3INTERFACE_H
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
#include "uft3stdfields.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
|
|
||||||
Uft3StdFields::Uft3StdFields(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> Uft3StdFields::loadData(
|
|
||||||
const QString& dirPath,
|
|
||||||
const QMap<QString, QMap<QString, QString>>& uf3datatypeMap)
|
|
||||||
{
|
|
||||||
QMap<QString, QMap<QString, QString>> resultMap;
|
|
||||||
|
|
||||||
QString filePath = dirPath;
|
|
||||||
filePath.replace('\\', '/');
|
|
||||||
filePath += "/metadata/stdfield.stdfield";
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("加载UFT3标准字段文件: %1").arg(filePath));
|
|
||||||
|
|
||||||
QFile file(filePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(filePath));
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
|
|
||||||
if (elementName == "items") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
|
|
||||||
QString sFieldName = attrs.value("name").toString();
|
|
||||||
QString sCname = attrs.value("chineseName").toString();
|
|
||||||
QString sType = attrs.value("dataType").toString();
|
|
||||||
QString sDesc = attrs.value("description").toString();
|
|
||||||
sDesc.replace("'", "\"");
|
|
||||||
QString sDictId = attrs.value("dictionaryType").toString();
|
|
||||||
|
|
||||||
QString sUftType = "";
|
|
||||||
|
|
||||||
if (uf3datatypeMap.contains(sType)) {
|
|
||||||
sUftType = uf3datatypeMap[sType].value("uftType");
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QString> fieldInfo;
|
|
||||||
fieldInfo["name"] = sFieldName;
|
|
||||||
fieldInfo["cname"] = sCname;
|
|
||||||
fieldInfo["type"] = sType;
|
|
||||||
fieldInfo["desc"] = sDesc;
|
|
||||||
fieldInfo["dict"] = sDictId;
|
|
||||||
fieldInfo["uftType"] = sUftType;
|
|
||||||
|
|
||||||
resultMap[sFieldName] = fieldInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
LogManager::instance()->log(QString("UFT3标准字段加载完成,共 %1 条").arg(resultMap.size()));
|
|
||||||
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef TFT3STDFIELDS_H
|
|
||||||
#define TFT3STDFIELDS_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
class Uft3StdFields : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Uft3StdFields(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> loadData(const QString& dirPath,
|
|
||||||
const QMap<QString, QMap<QString, QString>>& uf3datatypeMap);
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,198 +0,0 @@
|
||||||
#include "uft3table.h"
|
|
||||||
#include "utils/logmanager.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonArray>
|
|
||||||
|
|
||||||
Uft3Table::Uft3Table(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QVariant>> Uft3Table::loadData(const QString& dirPath)
|
|
||||||
{
|
|
||||||
QMap<QString, QMap<QString, QVariant>> resultMap;
|
|
||||||
|
|
||||||
QString scanPath = dirPath;
|
|
||||||
scanPath.replace('\\', '/');
|
|
||||||
scanPath += "/uftstructure";
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("加载UFT3表结构目录: %1").arg(scanPath));
|
|
||||||
|
|
||||||
QDir dir(scanPath);
|
|
||||||
if (!dir.exists()) {
|
|
||||||
LogManager::instance()->logError(QString("表结构目录不存在: %1").arg(scanPath));
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
scanDirectory(scanPath, resultMap);
|
|
||||||
|
|
||||||
for (const QString& filePath : _fileList) {
|
|
||||||
if (filePath.contains(".uftstructure")) {
|
|
||||||
parseTableFile(filePath, resultMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogManager::instance()->log(QString("UFT3表结构加载完成,共 %1 条").arg(resultMap.size()));
|
|
||||||
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Uft3Table::scanDirectory(const QString& dirPath, QMap<QString, QMap<QString, QVariant>>& resultMap)
|
|
||||||
{
|
|
||||||
QDir dir(dirPath);
|
|
||||||
|
|
||||||
QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
|
|
||||||
for (const QFileInfo& fileInfo : fileList) {
|
|
||||||
if (fileInfo.isDir()) {
|
|
||||||
scanDirectory(fileInfo.absoluteFilePath(), resultMap);
|
|
||||||
}
|
|
||||||
else if (fileInfo.isFile()) {
|
|
||||||
_fileList.append(fileInfo.absoluteFilePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Uft3Table::parseTableFile(const QString& filePath, QMap<QString, QMap<QString, QVariant>>& resultMap)
|
|
||||||
{
|
|
||||||
QString sFilePath = filePath;
|
|
||||||
sFilePath.replace('\\', '/');
|
|
||||||
|
|
||||||
QFile file(sFilePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
|
||||||
LogManager::instance()->logError(QString("无法打开表结构文件: %1").arg(sFilePath));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray data = file.readAll();
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
QXmlStreamReader xml(data);
|
|
||||||
|
|
||||||
QString tableEngName = "";
|
|
||||||
QString tablePath = "";
|
|
||||||
QString chineseName = "";
|
|
||||||
QString objectId = "";
|
|
||||||
QString spaceName = "";
|
|
||||||
QStringList fieldList;
|
|
||||||
QMap<QString, QStringList> indexMap;
|
|
||||||
QMap<QString, QStringList> uniqueIndexMap;
|
|
||||||
QMap<QString, QStringList> globalIndexMap;
|
|
||||||
|
|
||||||
int lastSlash = sFilePath.lastIndexOf('/');
|
|
||||||
if (lastSlash != -1) {
|
|
||||||
tableEngName = sFilePath.mid(lastSlash + 1);
|
|
||||||
tableEngName = tableEngName.left(tableEngName.indexOf(".uftstructure"));
|
|
||||||
}
|
|
||||||
|
|
||||||
int uftstructurePos = sFilePath.indexOf("uftstructure");
|
|
||||||
if (uftstructurePos != -1) {
|
|
||||||
tablePath = sFilePath.mid(uftstructurePos);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
QXmlStreamReader::TokenType token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement) {
|
|
||||||
QString elementName = xml.name().toString();
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
|
|
||||||
if (elementName == "Structure") {
|
|
||||||
if (attrs.hasAttribute("chineseName")) {
|
|
||||||
chineseName = attrs.value("chineseName").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.hasAttribute("objectId")) {
|
|
||||||
objectId = attrs.value("objectId").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.hasAttribute("space")) {
|
|
||||||
spaceName = attrs.value("space").toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (elementName == "properties") {
|
|
||||||
QString fieldId = attrs.value("id").toString();
|
|
||||||
if (!fieldId.isEmpty()) {
|
|
||||||
fieldList.append(fieldId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (elementName == "indexs") {
|
|
||||||
QString indexName = attrs.value("name").toString();
|
|
||||||
QStringList indexFieldList;
|
|
||||||
bool isUnique = !attrs.hasAttribute("containerType");
|
|
||||||
bool isGlobal = false;
|
|
||||||
|
|
||||||
if (attrs.hasAttribute("global") && attrs.value("global").toString() == "true") {
|
|
||||||
isGlobal = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
token = xml.readNext();
|
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartElement && xml.name().toString() == "items") {
|
|
||||||
QString fieldAttr = xml.attributes().value("attrname").toString();
|
|
||||||
if (!fieldAttr.isEmpty()) {
|
|
||||||
indexFieldList.append(fieldAttr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (token == QXmlStreamReader::EndElement && xml.name().toString() == "indexs") {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!indexName.isEmpty() && !indexFieldList.isEmpty()) {
|
|
||||||
indexMap[indexName] = indexFieldList;
|
|
||||||
if (isUnique) {
|
|
||||||
uniqueIndexMap[indexName] = indexFieldList;
|
|
||||||
}
|
|
||||||
if (isGlobal) {
|
|
||||||
globalIndexMap[indexName] = indexFieldList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString sUser = "";
|
|
||||||
if (spaceName == "HS_UFT_DATA") {
|
|
||||||
sUser = "hs_uft";
|
|
||||||
}
|
|
||||||
else if (spaceName == "HS_UARG_DATA") {
|
|
||||||
sUser = "hs_uarg";
|
|
||||||
}
|
|
||||||
else if (spaceName == "HS_USMS_DATA") {
|
|
||||||
sUser = "hs_usms";
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QVariant> tableInfoDetail;
|
|
||||||
tableInfoDetail["tableEngName"] = tableEngName;
|
|
||||||
tableInfoDetail["tablePath"] = tablePath;
|
|
||||||
tableInfoDetail["chineseName"] = chineseName;
|
|
||||||
tableInfoDetail["objectId"] = objectId;
|
|
||||||
tableInfoDetail["fieldList"] = fieldList;
|
|
||||||
tableInfoDetail["user"] = sUser;
|
|
||||||
|
|
||||||
QJsonObject indexMapJson;
|
|
||||||
for (const QString& key : indexMap.keys()) {
|
|
||||||
indexMapJson[key] = QJsonArray::fromStringList(indexMap[key]);
|
|
||||||
}
|
|
||||||
tableInfoDetail["indexMap"] = indexMapJson;
|
|
||||||
|
|
||||||
QJsonObject uniqueIndexMapJson;
|
|
||||||
for (const QString& key : uniqueIndexMap.keys()) {
|
|
||||||
uniqueIndexMapJson[key] = QJsonArray::fromStringList(uniqueIndexMap[key]);
|
|
||||||
}
|
|
||||||
tableInfoDetail["uniqueIndexMap"] = uniqueIndexMapJson;
|
|
||||||
|
|
||||||
QJsonObject globalIndexMapJson;
|
|
||||||
for (const QString& key : globalIndexMap.keys()) {
|
|
||||||
globalIndexMapJson[key] = QJsonArray::fromStringList(globalIndexMap[key]);
|
|
||||||
}
|
|
||||||
tableInfoDetail["globalIndexMap"] = globalIndexMapJson;
|
|
||||||
|
|
||||||
if (!tableEngName.isEmpty()) {
|
|
||||||
resultMap[tableEngName] = tableInfoDetail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||