feat(编辑能力): 修复重复编号及加密文档编辑异常,统一签名信息顺序,优化弹窗标题与布局
build.yaml / build (push) Successful in 42s

This commit is contained in:
xiaoqidun committed 2026-09-23 23:39:34 +08:00
1 parent 3927929822
commit e3908c1149
8 files changed
+317 -145

No files matched your search

+8 -4
View File
@@ -353,8 +353,9 @@
</div>
</form>
</dialog>
<dialog id="signPanel" class="form-dialog security-dialog" aria-label="签章">
<dialog id="signPanel" class="form-dialog security-dialog" aria-labelledby="signTitle">
<form id="signForm" autocomplete="off">
<h2 id="signTitle" class="form-title">签署文档</h2>
<div class="form-row"><label for="signCertificate">证书</label><input id="signCertificate" type="file" accept=".pem,.cer,.crt,.der" required></div>
<div class="form-row"><label for="signKey">私钥</label><input id="signKey" type="file" accept=".pem,.key,.der" required></div>
<div class="form-row"><label for="signKeyPassword">私钥口令</label><input id="signKeyPassword" type="password" autocomplete="off"></div>
@@ -374,8 +375,9 @@
<div class="form-actions"><div id="signStatus" class="form-status" role="status" aria-live="polite"></div><button id="signCancel" class="button" type="button">取消</button><button class="button" type="submit" title="签署另存">签署</button></div>
</form>
</dialog>
<dialog id="verifyPanel" class="form-dialog security-dialog" aria-label="验签">
<dialog id="verifyPanel" class="form-dialog security-dialog" aria-labelledby="verifyTitle">
<form id="verifyForm">
<h2 id="verifyTitle" class="form-title">验证签名</h2>
<div class="form-row"><label for="verifyRoots">信任根</label><input id="verifyRoots" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
<div class="form-row"><label for="verifyCerts">证书</label><input id="verifyCerts" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
<div class="form-row"><label for="verifyTimeRoots">时间戳根</label><input id="verifyTimeRoots" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
@@ -386,8 +388,9 @@
<div class="form-actions"><div id="verifyStatus" class="form-status" role="status" aria-live="polite"></div><button id="verifyCancel" class="button" type="button">取消</button><button class="button" type="submit">验签</button></div>
</form>
</dialog>
<dialog id="credentialsPanel" class="form-dialog security-dialog" aria-label="解锁文档">
<dialog id="credentialsPanel" class="form-dialog security-dialog" aria-labelledby="credentialsTitle">
<form id="credentialsForm" autocomplete="off">
<h2 id="credentialsTitle" class="form-title">解锁文档</h2>
<div class="form-row"><label for="credentialsType">方式</label><select id="credentialsType"><option value="password">口令</option><option value="certificate">证书</option></select></div>
<div class="form-row"><label for="credentialsUser">用户</label><input id="credentialsUser" type="text" autocomplete="off" spellcheck="false"></div>
<div id="credentialsPasswordRow" class="form-row"><label for="credentialsPassword">口令</label><input id="credentialsPassword" type="password" autocomplete="off" required autofocus></div>
@@ -397,8 +400,9 @@
<div class="form-actions"><div id="credentialsStatus" class="form-status" role="status" aria-live="polite"></div><button id="credentialsCancel" class="button" type="button">取消</button><button class="button" type="submit">解锁</button></div>
</form>
</dialog>
<dialog id="exportPanel" class="form-dialog" aria-label="导出文档">
<dialog id="exportPanel" class="form-dialog" aria-labelledby="exportTitle">
<form id="exportForm">
<h2 id="exportTitle" class="form-title">导出文档</h2>
<div id="encryptionFields" hidden>
<div class="form-row"><label for="encryptionType">方式</label><select id="encryptionType"><option value="password">口令</option><option value="certificate">证书</option></select></div>
<div id="encryptionUserRow" class="form-row"><label for="encryptionUser">用户</label><input id="encryptionUser" type="text" autocomplete="off" spellcheck="false"></div>
+10
View File
@@ -645,6 +645,16 @@ button:not(:disabled):hover {
padding: 12px;
}
.form-title {
margin: -12px -12px 12px;
padding: 10px 12px;
border-bottom: 1px solid var(--line);
background: #eef1f4;
font-size: 14px;
font-weight: 600;
line-height: 1.5;
}
.security-dialog {
width: 360px;
}
+21 -20
View File
@@ -350,6 +350,7 @@ const el = {
exportPageButton: document.querySelector("#exportPageButton"),
exportButton: document.querySelector("#exportButton"),
exportPanel: document.querySelector("#exportPanel"),
exportTitle: document.querySelector("#exportTitle"),
exportForm: document.querySelector("#exportForm"),
exportAll: document.querySelector("#exportAll"),
exportSpecified: document.querySelector("#exportSpecified"),
@@ -1602,7 +1603,7 @@ async function toggleEditor() {
const openSeq = ++state.openSeq;
setBusy(true, "正在准备编辑", null, "正在准备编辑");
try {
const doc = await callWASM("ofdgoEditDocument");
const doc = await callWASM("ofdgoEditDocument", pageIndex);
if (openSeq !== state.openSeq) return;
state.savedRevision = doc.revision;
state.editorViews.clear();
@@ -3961,7 +3962,7 @@ function openExportPanel(encrypted = false) {
el.encryptionFields.hidden = !encrypted;
el.encryptionPassword.required = el.encryptionConfirm.required = encrypted;
updateEncryptionType();
el.exportPanel.setAttribute("aria-label", encrypted ? "加密另存" : "导出文档");
el.exportTitle.textContent = encrypted ? "加密另存" : "导出文档";
el.exportSubmit.textContent = encrypted ? "保存" : "导出";
if (state.editing && state.pageSelection.size) {
el.exportSpecified.checked = true;
@@ -5851,9 +5852,9 @@ function renderSignatures() {
head.append(badges, name);
row.append(head);
appendInfoLine(row, "章名", signature.sealName);
appendInfoLine(row, "签署人", signature.signer);
appendInfoLine(row, "时间", formatDocumentTime(signature.signatureDateTime));
appendInfoLine(row, "章名", signature.sealName);
appendInfoLine(row, "机构", signatureAgency(signature));
appendSignatureCheck(row, "信任", signature.certTrustChecked, signature.certTrustOK);
appendInfoLine(row, "保护文件", signatureReferenceText(signature), signatureReferenceStatus(signature));
@@ -5864,25 +5865,25 @@ function renderSignatures() {
checks.append(checksTitle);
appendSignatureCheck(checks, "原文", signature.dataHashChecked, signature.dataHashOK);
appendSignatureCheck(checks, "签名", signature.signedValueChecked, signature.signedValueOK);
appendSignatureCheck(checks, "证书", signature.certChecked, signature.certOK);
appendSignaturePolicy(checks, "证书期限", signature.certTimeChecked, signature.certTimeOK);
appendInfoLine(checks, "信任错误", signature.certTrustError, "fail");
appendSignaturePolicy(checks, "签署时间", signature.signatureTimeChecked, signature.signatureTimeOK);
if (signature.type !== "Sign") {
appendSignatureCheck(checks, "印章", signature.sealChecked, signature.sealOK);
appendSignaturePolicy(checks, "印章匹配", signature.sealMatchChecked, signature.sealMatchOK);
appendSignaturePolicy(checks, "印章期限", signature.sealTimeChecked, signature.sealTimeOK);
if (signature.sealCertTimeChecked) {
appendInfoLine(checks, "制章证书", signature.sealCertTimeOK ? "有效" : "失效", signature.sealCertTimeOK ? "ok" : "fail");
}
}
appendSignatureCheck(checks, "证书", signature.certChecked, signature.certOK);
appendSignaturePolicy(checks, "签署时间", signature.signatureTimeChecked, signature.signatureTimeOK);
appendSignaturePolicy(checks, "印章期限", signature.sealTimeChecked, signature.sealTimeOK);
if (signature.sealCertTimeChecked) {
appendInfoLine(checks, "制章证书", signature.sealCertTimeOK ? "有效" : "失效", signature.sealCertTimeOK ? "ok" : "fail");
}
appendSignaturePolicy(checks, "证书期限", signature.certTimeChecked, signature.certTimeOK);
appendSignatureCheck(checks, "策略", signature.policyChecked, signature.policyOK);
appendSignatureCheck(checks, "覆盖", signature.coverageChecked, signature.coverageOK);
appendSignatureCheck(checks, "时间戳", signature.timestampChecked, signature.timestampOK);
appendSignatureCheck(checks, "撤销", signature.revocationChecked, signature.revocationOK);
appendInfoLine(checks, "策略错误", signature.policyError, "fail");
appendInfoLine(checks, "信任错误", signature.certTrustError, "fail");
appendInfoLine(checks, "覆盖错误", signature.coverageError, "fail");
appendInfoLine(checks, "未保护", signature.uncoveredFiles?.join("、"), "fail");
appendSignatureCheck(checks, "策略", signature.policyChecked, signature.policyOK);
appendInfoLine(checks, "策略错误", signature.policyError, "fail");
appendSignatureCheck(checks, "时间戳", signature.timestampChecked, signature.timestampOK);
appendSignatureCheck(checks, "撤销", signature.revocationChecked, signature.revocationOK);
row.append(checks);
for (const timestamp of signature.timestamps || []) {
const details = document.createElement("details");
@@ -5917,17 +5918,17 @@ function renderSignatures() {
title.textContent = "签章信息";
details.append(title);
appendInfoLine(details, "编号", signature.id);
appendInfoLine(details, "版本", signature.version);
appendInfoLine(details, "章图", signature.sealType);
appendInfoLine(details, "章号", signature.sealId);
appendInfoLine(details, "厂商", signature.sealVendor);
appendInfoLine(details, "文档", signature.docRoot);
appendInfoLine(details, "算法", signature.signatureMethod);
appendInfoLine(details, "摘要", signature.digestMethod);
appendInfoLine(details, "序列号", signature.signSerial);
appendInfoLine(details, "证书主体", signature.signSubject);
appendInfoLine(details, "颁发者", signature.signIssuer);
appendInfoLine(details, "序列号", signature.signSerial);
appendInfoLine(details, "章号", signature.sealId);
appendInfoLine(details, "章图", signature.sealType);
appendInfoLine(details, "制章证书", signature.sealSubject);
appendInfoLine(details, "印章厂商", signature.sealVendor);
appendInfoLine(details, "组件版本", signature.version);
row.append(details);
fragment.append(row);
}