docs: 添加涉密文件自检工具实施计划
This commit is contained in:
312
UmiOCR-data/qt_res/qml/TabPages/BatchDOC/BatchDOC.qml
Normal file
312
UmiOCR-data/qt_res/qml/TabPages/BatchDOC/BatchDOC.qml
Normal file
@@ -0,0 +1,312 @@
|
||||
// ==================================================
|
||||
// =============== 功能页:批量文档处理 ===============
|
||||
// ==================================================
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import ".."
|
||||
import "../../Widgets"
|
||||
import "../../Widgets/ResultLayout"
|
||||
import "../../Widgets/IgnoreArea"
|
||||
|
||||
/* 文档参数:
|
||||
path 路径
|
||||
pages 页数显示
|
||||
state 状态显示
|
||||
page_count 总页数
|
||||
range_start 范围开始
|
||||
range_end 范围结束
|
||||
is_encrypted 需要密码
|
||||
is_authenticate 密码正确
|
||||
password 密码
|
||||
*/
|
||||
|
||||
TabPage {
|
||||
id: tabPage
|
||||
|
||||
// ========================= 【逻辑】 =========================
|
||||
|
||||
property string msnID: "" // 当前任务ID
|
||||
|
||||
// 异步加载一批文档路径
|
||||
function addDocs(paths) {
|
||||
if(paths.length <= 0) return
|
||||
const isRecurrence = configsComp.getValue("mission.recurrence")
|
||||
qmlapp.asynFilesLoader.run(paths,"doc",isRecurrence,onAddDocs)
|
||||
}
|
||||
// 完毕后,将合法表格加入表格
|
||||
function onAddDocs(docs) {
|
||||
if(docs.length <= 0) return
|
||||
let encryptedCount = 0
|
||||
for(let i in docs) {
|
||||
const info = docs[i]
|
||||
filesTableView.add({
|
||||
// 显示:路径,状态,页范围
|
||||
path: info.path,
|
||||
pages: `${info.page_count}`, // 如果范围为整本,只显示总页数。否则显示 起始-结束
|
||||
state: info.is_encrypted ? qsTr("加密") : "" ,
|
||||
// 数据
|
||||
page_count: info.page_count,
|
||||
range_start: 1,
|
||||
range_end: info.page_count,
|
||||
is_encrypted: info.is_encrypted, // 有密码
|
||||
is_authenticate: !info.is_encrypted, // 已解密(密码正确)
|
||||
password: "",
|
||||
})
|
||||
if(info.is_encrypted) encryptedCount++
|
||||
}
|
||||
if(encryptedCount > 0) {
|
||||
qmlapp.popup.simple(qsTr("%1个加密文档").arg(encryptedCount),
|
||||
qsTr("请点击文件名填写密码"))
|
||||
}
|
||||
}
|
||||
|
||||
// 运行文档任务
|
||||
function docStart() {
|
||||
const fileCount = filesTableView.rowCount
|
||||
if(fileCount <= 0) {
|
||||
ctrlPanel.stopFinished()
|
||||
return
|
||||
}
|
||||
// 获取信息
|
||||
const docs = filesTableView.getColumnsValues([
|
||||
"path","range_start", "range_end", "page_count", "is_encrypted", "is_authenticate", "password"])
|
||||
// 第1次遍历:检查密码填写
|
||||
for(let i = 0; i < fileCount; i++) {
|
||||
const d = docs[i]
|
||||
if(d.is_encrypted && !d.is_authenticate) {
|
||||
qmlapp.popup.message(qsTr("文档已加密"), qsTr("【%1】\n请点击文档名,设置密码").arg(d.path), "warning")
|
||||
ctrlPanel.stopFinished()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 第2次遍历:刷新信息
|
||||
let allPages = 0 // 页总数
|
||||
for(let i = 0; i < fileCount; i++) {
|
||||
const d = docs[i]
|
||||
allPages += d.range_end - d.range_start + 1
|
||||
filesTableView.setProperty(d.path, "state", qsTr("排队"))
|
||||
}
|
||||
// 若tabPanel面板的下标没有变化过,则切换到记录页
|
||||
if(tabPanel.indexChangeNum < 2)
|
||||
tabPanel.currentIndex = 1
|
||||
// 任务进度 开始计时
|
||||
ctrlPanel.runFinished(allPages)
|
||||
// 提交任务
|
||||
const argd = configsComp.getValueDict()
|
||||
tabPage.callPy("msnDocs", docs, argd)
|
||||
}
|
||||
|
||||
// 停止文档任务
|
||||
function docStop() {
|
||||
tabPage.callPy("msnStop")
|
||||
// 刷新表格,清空未执行的任务的状态
|
||||
let msnLength = filesTableView.rowCount
|
||||
for(let i = 0; i < msnLength; i++) {
|
||||
const row = filesTableView.get(i)
|
||||
const s = row.state
|
||||
if(s.length > 0 && s[0] !== "√" && s[0] !== "×") {
|
||||
filesTableView.setProperty(i, "state", "")
|
||||
}
|
||||
}
|
||||
ctrlPanel.stopFinished()
|
||||
}
|
||||
|
||||
// 文件表格中单击文档
|
||||
function onClickDoc(index) {
|
||||
if(ctrlPanel.state_ !== "stop") return
|
||||
const info = filesTableView.get(index)
|
||||
if(Object.keys(info).length > 0)
|
||||
previewDoc.show(info)
|
||||
}
|
||||
|
||||
// 关闭页面
|
||||
function closePage() {
|
||||
if(ctrlPanel.state_ !== "stop") {
|
||||
const argd = { yesText: qsTr("依然关闭") }
|
||||
const callback = (flag)=>{
|
||||
if(flag) {
|
||||
docStop()
|
||||
delPage()
|
||||
}
|
||||
}
|
||||
qmlapp.popup.dialog("", qsTr("任务正在进行中。\n要结束任务并关闭页面吗?"), callback, "warning", argd)
|
||||
}
|
||||
else {
|
||||
delPage()
|
||||
}
|
||||
}
|
||||
|
||||
// ========================= 【python调用qml】 =========================
|
||||
|
||||
// 准备开始处理一个文档
|
||||
function onDocStart(path) {
|
||||
// 刷新表格显示
|
||||
const d = filesTableView.get(path)
|
||||
let state = `0/${d.range_end - d.range_start + 1}`
|
||||
filesTableView.setProperty(path, "state", state)
|
||||
}
|
||||
|
||||
// 获取一个文档的一页的结果
|
||||
function onDocGet(path, page, res) {
|
||||
// 刷新单个文档的信息
|
||||
const d = filesTableView.get(path)
|
||||
const state = `${page - d.range_start + 1}/${d.range_end - d.range_start + 1}`
|
||||
filesTableView.setProperty(path, "state", state)
|
||||
// 提取文字,添加到结果表格
|
||||
const title = path2name(path)
|
||||
res.title = `${title} - ${page}`
|
||||
resultsTableView.addOcrResult(res)
|
||||
ctrlPanel.msnStep(1)
|
||||
}
|
||||
|
||||
// 一个文档处理完毕。 isAll==true 时所有文档处理完毕。
|
||||
function onDocEnd(path, msg, isAll) {
|
||||
const errTitle = qsTr("文档识别异常")
|
||||
// 成功结束
|
||||
if(msg.startsWith("[Success]")) {
|
||||
filesTableView.setProperty(path, "state", "√")
|
||||
msg = ""
|
||||
}
|
||||
// 单个文档任务失败,总体未结束
|
||||
else if(!isAll) {
|
||||
filesTableView.setProperty(path, "state", "× "+ qsTr("失败"))
|
||||
qmlapp.popup.simple(errTitle, msg)
|
||||
}
|
||||
// 所有文档处理完毕
|
||||
if(isAll) {
|
||||
const simpleType = configsComp.getValue("other.simpleNotificationType")
|
||||
qmlapp.popup.simple(qsTr("批量识别完成"), "", simpleType)
|
||||
if(msg) // 如果有异常,则弹窗
|
||||
qmlapp.popup.message(errTitle, msg, "error")
|
||||
ctrlPanel.stopFinished()
|
||||
// 任务完成后续操作
|
||||
qmlapp.globalConfigs.utilsDicts.postTaskHardwareCtrl(
|
||||
configsComp.getValue("postTaskActions.system")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 路径转文件名
|
||||
function path2name(path) {
|
||||
const parts = path.split("/")
|
||||
return parts[parts.length - 1]
|
||||
}
|
||||
|
||||
// ========================= 【布局】 =========================
|
||||
|
||||
// 配置
|
||||
configsComp: BatchDOCConfigs {}
|
||||
|
||||
// 主区域:可切换双栏面板
|
||||
DoubleSwitchableLayout {
|
||||
id: doubleLayout
|
||||
saveKey: "BatchDOC_1"
|
||||
anchors.fill: parent
|
||||
|
||||
// 面板A:控制板+文件表格
|
||||
itemA: Panel {
|
||||
anchors.fill: parent
|
||||
|
||||
// 上方控制板
|
||||
MissionCtrlPanel {
|
||||
id: ctrlPanel
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: size_.spacing
|
||||
height: size_.line * 2
|
||||
|
||||
onRunClicked: tabPage.docStart()
|
||||
onPauseClicked: {
|
||||
tabPage.callPy("msnPause")
|
||||
pauseFinished()
|
||||
}
|
||||
onResumeClicked: {
|
||||
tabPage.callPy("msnResume")
|
||||
resumeFinished()
|
||||
}
|
||||
onStopClicked: tabPage.docStop()
|
||||
}
|
||||
|
||||
// 下方文件表格
|
||||
FilesTableView {
|
||||
id: filesTableView
|
||||
anchors.top: ctrlPanel.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: size_.spacing
|
||||
anchors.topMargin: size_.smallSpacing
|
||||
headers: [
|
||||
{key: "path", title: qsTr("文档"), left: true, display: path2name,
|
||||
btn: true, onClicked:onClickDoc},
|
||||
{key: "state", title: qsTr("状态"), btn: true, onClicked:onClickDoc},
|
||||
{key: "pages", title: qsTr("页数"), btn: true, onClicked:onClickDoc},
|
||||
]
|
||||
openBtnText: qsTr("打开文档")
|
||||
clearBtnText: qsTr("清空")
|
||||
defaultTips: qsTr("拖入文档或文件夹")
|
||||
fileDialogTitle: qsTr("请选择文档")
|
||||
fileDialogNameFilters: [qsTr("文档")+" (*.pdf *.xps *.epub *.mobi *.fb2 *.cbz)"]
|
||||
isLock: ctrlPanel.state_ !== "stop"
|
||||
onAddPaths: {
|
||||
tabPage.addDocs(paths)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 面板B:文字输出 & 设置
|
||||
itemB: Panel {
|
||||
anchors.fill: parent
|
||||
|
||||
// 配置项控制板
|
||||
TabPanel {
|
||||
id: tabPanel
|
||||
anchors.fill: parent
|
||||
anchors.margins: size_.spacing
|
||||
isMenuTop: doubleLayout.isRow // 左右布局时,菜单在顶部;上下布局时菜单在底部
|
||||
menuHeight: size_.line * 2
|
||||
|
||||
// 结果面板
|
||||
ResultsTableView {
|
||||
id: resultsTableView
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
}
|
||||
|
||||
tabsModel: [
|
||||
{
|
||||
"key": "configs",
|
||||
"title": qsTr("设置"),
|
||||
"component": configsComp.panelComponent,
|
||||
},
|
||||
{
|
||||
"key": "ocrResult",
|
||||
"title": qsTr("记录"),
|
||||
"component": resultsTableView,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标拖入文档
|
||||
DropArea_ {
|
||||
id: "addDocsDropArea"
|
||||
anchors.fill: parent
|
||||
callback: tabPage.addDocs
|
||||
}
|
||||
|
||||
// 预览面板
|
||||
PreviewDoc {
|
||||
id: previewDoc
|
||||
anchors.fill: parent
|
||||
configsComp: tabPage.configsComp
|
||||
updateInfo: (path, info) => {
|
||||
let infoA = filesTableView.get(path)
|
||||
Object.assign(infoA, info)
|
||||
filesTableView.set(path, infoA)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user