From 0b6fdcf95f98d5ee63473a7a8c73e16e8400f68c Mon Sep 17 00:00:00 2001 From: xianyi Date: Mon, 8 Dec 2025 14:38:05 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=9C=86=E5=9C=8645s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/UI9/UI9.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/UI9/UI9.tsx b/src/pages/UI9/UI9.tsx index 76b0601..a838e8c 100644 --- a/src/pages/UI9/UI9.tsx +++ b/src/pages/UI9/UI9.tsx @@ -27,8 +27,8 @@ const UI9: React.FC = () => { navigate("/"); }, [navigate]); - const [countdown, setCountdown] = useState(30); - const [backTime, setBackTime] = useState("确认(30S)"); + const [countdown, setCountdown] = useState(45); + const [backTime, setBackTime] = useState("确认(45S)"); useEffect(() => { if (countdown > 0) { From 2ba570a5047f9f3a6a5ef0116806fe2eee22d959 Mon Sep 17 00:00:00 2001 From: xianyi Date: Mon, 8 Dec 2025 14:48:38 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=8F=8C=E9=9D=A2=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/main.js | 4 +++- src/electron.d.ts | 2 +- src/pages/UI8/UI8.css | 31 +++++++++++++++++++++++++++++++ src/pages/UI8/UI8.tsx | 34 ++++++++++++++++++++++++++++++++-- 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/electron/main.js b/electron/main.js index 17703ef..f0a62b5 100644 --- a/electron/main.js +++ b/electron/main.js @@ -300,16 +300,18 @@ ipcMain.handle("print-pdf", async (event, pdfDataOrUrl, printOptions = {}) => { throw new Error(`PDF文件大小异常(${stats.size} bytes),可能文件损坏`); } + const duplexMode = printOptions?.duplex; log.info( `准备打印PDF: ${pdfFilePath}, 打印机: ${ targetPrinterName || "默认打印机" - }` + }, 双面打印: ${duplexMode ? "是" : "否"}` ); // 使用 pdf-to-printer 打印 const printOptions_ptp = { printer: targetPrinterName || undefined, silent: true, // 静默打印 + duplex: duplexMode || false, // 双面打印选项 }; await ptp.print(pdfFilePath, printOptions_ptp); diff --git a/src/electron.d.ts b/src/electron.d.ts index ec3a779..947f081 100644 --- a/src/electron.d.ts +++ b/src/electron.d.ts @@ -14,7 +14,7 @@ interface ElectronAPI { ) => Promise<{ success: boolean; data?: string; error?: string }>; printPdf: ( pdfUrl: string, - options?: { printerName?: string } + options?: { printerName?: string; duplex?: boolean } ) => Promise<{ success: boolean; error?: string }>; getPrinters: () => Promise<{ success: boolean; diff --git a/src/pages/UI8/UI8.css b/src/pages/UI8/UI8.css index a751257..6176201 100644 --- a/src/pages/UI8/UI8.css +++ b/src/pages/UI8/UI8.css @@ -348,4 +348,35 @@ .ui8-printer-error { font-size: 22px; color: #b12651; +} + +.ui8-duplex-option { + margin-top: 15px; + display: flex; + justify-content: flex-end; + align-items: center; +} + +.ui8-duplex-label { + display: flex; + align-items: center; + cursor: pointer; + user-select: none; + border: none; + background-color: inherit; +} + +.ui8-duplex-checkbox { + width: 16px; + height: 16px; + cursor: pointer; + accent-color: rgba(0, 45, 93, 0); + border: none; + background-color: inherit; +} + +.ui8-duplex-text { + font-size: 20px; + font-family: NotoSansCJKsc-Regular; + color: rgba(0, 45, 93, 0); } \ No newline at end of file diff --git a/src/pages/UI8/UI8.tsx b/src/pages/UI8/UI8.tsx index 1a9bfb7..a6f6d86 100644 --- a/src/pages/UI8/UI8.tsx +++ b/src/pages/UI8/UI8.tsx @@ -10,6 +10,7 @@ import ui8B from "../../assets/ui8B.png"; import { getDaojiandanPdf } from "../../api/hisApi"; const PREFERRED_PRINTER_KEY = "preferredPrinterName"; +const PREFERRED_DUPLEX_KEY = "preferredDuplex"; type PrinterInfo = ElectronPrinterInfo; @@ -74,6 +75,7 @@ const UI8: React.FC = () => { const printerDropdownRef = useRef(null); const pdfContainerRef = useRef(null); const [isRightSectionHidden, setIsRightSectionHidden] = useState(false); + const [duplexEnabled, setDuplexEnabled] = useState(false); const getExamId = () => { const storedId = localStorage.getItem("selectedExamId"); @@ -221,6 +223,12 @@ const UI8: React.FC = () => { fetchPrinters(); + // 恢复双面打印设置 + const storedDuplex = localStorage.getItem(PREFERRED_DUPLEX_KEY); + if (storedDuplex === "true") { + setDuplexEnabled(true); + } + return () => { isMounted = false; }; @@ -343,7 +351,10 @@ const UI8: React.FC = () => { const printResult = await window.electronAPI.printPdf( printData, - selectedPrinter ? { printerName: selectedPrinter } : undefined + { + ...(selectedPrinter ? { printerName: selectedPrinter } : {}), + duplex: duplexEnabled, + } ); if (!printResult.success) { @@ -363,7 +374,7 @@ const UI8: React.FC = () => { } finally { setIsPrinting(false); } - }, [originPdfUrls, pdfFiles, printers.length, selectedPrinter, navigate, isPrinting]); + }, [originPdfUrls, pdfFiles, printers.length, selectedPrinter, navigate, isPrinting, duplexEnabled]); const handlePageCountUpdate = useCallback((index: number, numPages: number) => { window.electronAPI?.log("info", `[UI8] PDF渲染成功 (index=${index}),共 ${numPages} 页`); @@ -436,6 +447,25 @@ const UI8: React.FC = () => { {printerError && (
{printerError}
)} + +
+ +
From 578b5a509d5b6c1f3264c7541eb6f33b451027fc Mon Sep 17 00:00:00 2001 From: xianyi Date: Mon, 8 Dec 2025 14:58:11 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8D=95=E5=8F=8C?= =?UTF-8?q?=E9=9D=A2=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DuplexToggle.css | 32 ++++++++++++++++++++++++++++++++ src/components/DuplexToggle.tsx | 30 ++++++++++++++++++++++++++++++ src/pages/UI8/UI8.css | 24 ------------------------ src/pages/UI8/UI8.tsx | 30 ++++++++++++------------------ 4 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 src/components/DuplexToggle.css create mode 100644 src/components/DuplexToggle.tsx diff --git a/src/components/DuplexToggle.css b/src/components/DuplexToggle.css new file mode 100644 index 0000000..cb56ce5 --- /dev/null +++ b/src/components/DuplexToggle.css @@ -0,0 +1,32 @@ +.duplex-toggle { + display: flex; + align-items: center; + cursor: pointer; + user-select: none; + gap: 10px; + transition: opacity 0.2s ease; +} + +.duplex-toggle:hover { + opacity: 0.8; +} + +.duplex-toggle-icon { + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + font-size: 16px; + transition: all 0.2s ease; + flex-shrink: 0; + font-family: NotoSansCJKsc-Medium; +} + + +.duplex-toggle-label { + font-size: 20px; + font-family: NotoSansCJKsc-Regular; + color: rgba(0, 45, 93, 1); +} \ No newline at end of file diff --git a/src/components/DuplexToggle.tsx b/src/components/DuplexToggle.tsx new file mode 100644 index 0000000..f9454ca --- /dev/null +++ b/src/components/DuplexToggle.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import "./DuplexToggle.css"; + +interface DuplexToggleProps { + checked: boolean; + onChange: (checked: boolean) => void; + label?: string; +} + +const DuplexToggle: React.FC = ({ + checked, + onChange, + label = "", +}) => { + const handleClick = () => { + onChange(!checked); + }; + + return ( +
+
+ {checked ? "双" : "单"} +
+ {label} +
+ ); +}; + +export default DuplexToggle; + diff --git a/src/pages/UI8/UI8.css b/src/pages/UI8/UI8.css index 6176201..e33e24a 100644 --- a/src/pages/UI8/UI8.css +++ b/src/pages/UI8/UI8.css @@ -355,28 +355,4 @@ display: flex; justify-content: flex-end; align-items: center; -} - -.ui8-duplex-label { - display: flex; - align-items: center; - cursor: pointer; - user-select: none; - border: none; - background-color: inherit; -} - -.ui8-duplex-checkbox { - width: 16px; - height: 16px; - cursor: pointer; - accent-color: rgba(0, 45, 93, 0); - border: none; - background-color: inherit; -} - -.ui8-duplex-text { - font-size: 20px; - font-family: NotoSansCJKsc-Regular; - color: rgba(0, 45, 93, 0); } \ No newline at end of file diff --git a/src/pages/UI8/UI8.tsx b/src/pages/UI8/UI8.tsx index a6f6d86..db346b4 100644 --- a/src/pages/UI8/UI8.tsx +++ b/src/pages/UI8/UI8.tsx @@ -5,6 +5,7 @@ import "./UI8.css"; import "../../assets/css/basic.css"; import { useNavigate } from "react-router-dom"; import ConfirmButton from "../../components/ConfirmButton"; +import DuplexToggle from "../../components/DuplexToggle"; import ui8A from "../../assets/ui8A.png"; import ui8B from "../../assets/ui8B.png"; import { getDaojiandanPdf } from "../../api/hisApi"; @@ -410,6 +411,17 @@ const UI8: React.FC = () => { } }} > + { + setDuplexEnabled(enabled); + localStorage.setItem(PREFERRED_DUPLEX_KEY, enabled.toString()); + window.electronAPI?.log( + "info", + `[UI8] 双面打印设置为: ${enabled ? "启用" : "禁用"}` + ); + }} + /> {printersLoading ? "打印机加载中..." @@ -447,25 +459,7 @@ const UI8: React.FC = () => { {printerError && (
{printerError}
)} - -
-