osCtl.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { shell } from 'electron';
  2. import { os } from "../service/os/os";
  3. import path from 'node:path';
  4. import fs from 'node:fs';
  5. import { logger } from "ee-core/log";
  6. /**
  7. * 窗口控制(用于无边框窗口拖拽)
  8. * @class
  9. */
  10. class OsCtl {
  11. /**
  12. * 最小化窗口
  13. */
  14. async minimizeWindow() {
  15. await os.minimizeWindow();
  16. }
  17. /**
  18. * 最大化窗口
  19. */
  20. async maximizeWindow() {
  21. await os.maximizeWindow();
  22. }
  23. /**
  24. * 取消最大化窗口
  25. */
  26. async unmaximizeWindow() {
  27. await os.unmaximizeWindow();
  28. }
  29. /**
  30. * 关闭窗口
  31. */
  32. async closeWindow() {
  33. await os.closeWindow();
  34. }
  35. /**
  36. * 是否最大化窗口
  37. */
  38. async isMaximized() {
  39. return await os.isMaximized();
  40. }
  41. /**
  42. * 切换开发工具
  43. */
  44. async toggleDevTools() {
  45. await os.toggleDevTools();
  46. }
  47. /**
  48. * 打开用户数据目录
  49. */
  50. async openUserDataFolder() {
  51. await os.openUserDataFolder();
  52. }
  53. /**
  54. * 打开安装目录
  55. */
  56. async openInstallFolder() {
  57. await os.openInstallFolder();
  58. }
  59. /**
  60. * 选择目录(返回目录路径)
  61. */
  62. async selectDirectory() {
  63. return await os.selectDirectory();
  64. }
  65. /**
  66. * 选择单个文件(返回文件路径;params: { title?, filterName?, extensions?: string[] })
  67. */
  68. async selectFile(params) {
  69. return await os.selectFile(params);
  70. }
  71. /**
  72. * 获取应用信息
  73. */
  74. async getAppInfo() {
  75. return await os.getAppInfo();
  76. }
  77. /**
  78. * 使用系统默认浏览器打开外部链接
  79. */
  80. /**
  81. * 打开本机文件(默认关联程序)。
  82. *
  83. * 只接受绝对路径,且必须真实存在 —— 调用方是渲染进程里「打开记录关联文件」这类
  84. * 用户显式动作;路径可能来自后端 file_info.file_path。
  85. *
  86. * @param params { path } 本机绝对路径
  87. * @returns { success, data?: { path }, message? }
  88. */
  89. async openPath(params) {
  90. try {
  91. const target = typeof params?.path === 'string' ? params.path.trim() : '';
  92. if (!target) throw new Error('文件路径不能为空');
  93. if (!path.isAbsolute(target)) throw new Error('只支持绝对路径');
  94. if (!fs.existsSync(target)) throw new Error(`文件不存在:${target}`);
  95. if (fs.statSync(target).isDirectory()) throw new Error('目标是目录,不是文件');
  96. const message = await shell.openPath(target);
  97. if (message) throw new Error(message);
  98. return { success: true, data: { path: target } };
  99. } catch (e) {
  100. const msg = e instanceof Error ? e.message : String(e);
  101. logger.warn('[osCtl] openPath failed:', msg);
  102. return { success: false, message: msg };
  103. }
  104. }
  105. async openExternal(url) {
  106. return await os.openExternal(url);
  107. }
  108. /**
  109. * 通过 Node.js 主进程流式上传清鉴数据源文件
  110. * 在 controller 层捕获异常并返回结构化结果,避免异常被 Electron
  111. * 的 ipcMain.handle 包装成 "Error occurred in handler for ..." 前缀
  112. * @param params { dirPath, uploadUrl, token }
  113. * @returns { success: boolean, data?, message? }
  114. */
  115. async uploadQingJianFiles(params) {
  116. try {
  117. const data = await os.uploadQingJianFiles(params);
  118. return { success: true, data };
  119. } catch (e) {
  120. const msg = e instanceof Error ? e.message : String(e);
  121. logger.error('[osCtl] uploadQingJianFiles failed:', msg);
  122. return { success: false, message: msg };
  123. }
  124. }
  125. }
  126. OsCtl.toString = () => "OsCtl";
  127. export default OsCtl;