he wei
2024-01-16 0aabc58fd77f8e133ef899113e941afb34c62b88
U 英文版不需要自动升级
3个文件已修改
365 ■■■■■ 已修改文件
src/assets/js/i18n/base.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/background.js 353 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chartContextMenu.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/i18n/base.js
@@ -45,6 +45,9 @@
      ReferenceTime: '基准时间',
      CellVoltageDifferenceLineChart: '单体电压差折线图',
      CellTempDifferenceLineChart: '单体温度差折线图',
      DisplayLimitHiddenValue: '显示/限藏数值',
      SortedinHightoLow: '按高-低排序',
      SortedinLowtoHigh: '按低-高排序',
    }
  },
  US: {
@@ -93,6 +96,9 @@
      ReferenceTime: 'Reference Time',
      CellVoltageDifferenceLineChart: 'Cell Voltage Difference Line Chart',
      CellTempDifferenceLineChart: 'Cell Temp Difference Line Chart',
      DisplayLimitHiddenValue: 'Display/Limit Hidden Value',
      SortedinHightoLow: 'Sorted in High-to-Low',
      SortedinLowtoHigh: 'Sorted in Low-to-High',
    }
  }
}
src/background.js
@@ -1,20 +1,31 @@
'use strict'
"use strict";
import { app, protocol, BrowserWindow, ipcMain, ipcRenderer, dialog, shell, Menu, webContents } from 'electron'
import { autoUpdater } from 'electron-updater';
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import {
  app,
  protocol,
  BrowserWindow,
  ipcMain,
  ipcRenderer,
  dialog,
  shell,
  Menu,
  webContents,
} from "electron";
import { autoUpdater } from "electron-updater";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
// import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
import path from 'path';
import child_process from 'child_process';
import log from 'electron-log';
import update from './update';
import path from "path";
import child_process from "child_process";
import log from "electron-log";
import update from "./update";
import config from "./assets/js/config";
const { lang } = config;
autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'info';
autoUpdater.logger.transports.file.level = "info";
let win = null;
let loadingWin = null;
// 调试自动升级
/**
@@ -39,53 +50,58 @@
// });
// 单例锁
const gotTheLock = app.requestSingleInstanceLock()
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
  app.quit()
  app.quit();
} else {
  app.on('second-instance', (event, commandLine, workingDirectory) => {
  app.on("second-instance", (event, commandLine, workingDirectory) => {
    // 当运行第二个实例时,将会聚焦到myWindow这个窗口
    if (win) {
      if (win.isMinimized()) win.restore()
      win.focus()
      if (win.isMinimized()) win.restore();
      win.focus();
      if (commandLine[2]) {
        win.webContents.send('selected-file', { filePaths: [commandLine[2]] }, 'MenuList');
        win.webContents.send(
          "selected-file",
          { filePaths: [commandLine[2]] },
          "MenuList"
        );
      }
    }
  })
  });
}
const remote = require('@electron/remote/main');
const remote = require("@electron/remote/main");
remote.initialize();
// remote.enable()
const isDevelopment = process.env.NODE_ENV !== 'production'
const isDevelopment = process.env.NODE_ENV !== "production";
// const appUrl = 'http://localhost:8093/res/testParam/factorsAndThreshold';
const appUrl = 'http://localhost:8093/res/testParam/callService?seconds=3';
const requestPromise = require('minimal-request-promise');
const appUrl = "http://localhost:8093/res/testParam/callService?seconds=3";
const requestPromise = require("minimal-request-promise");
const checkService = function (cb) {
  requestPromise.get(appUrl).then(function (response) {
  requestPromise.get(appUrl).then(
    function (response) {
    log.info(response);
    log.info('Server started!');
      log.info("Server started!");
    cb();
  }, function (response) {
    },
    function (response) {
    log.warn(response);
    log.info('Waiting for the server start...');
      log.info("Waiting for the server start...");
    setTimeout(function () {
      checkService(cb);
    }, 500)
  })
      }, 500);
}
  );
};
// const path = require('path');
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
  { scheme: 'app', privileges: { secure: true, standard: true, stream: true } }
])
  { scheme: "app", privileges: { secure: true, standard: true, stream: true } },
]);
// TODO  debug;
// win.webContents.openDevTools()
@@ -94,9 +110,10 @@
  Menu.setApplicationMenu(null);
}
// loading 窗口
const loadingURL = isDevelopment ? path.join(__dirname, './loading.html') : `file://${__dirname}/loading.html`;
const loadingURL = isDevelopment
  ? path.join(__dirname, "./loading.html")
  : `file://${__dirname}/loading.html`;
const showLoading = (cb, argFn) => {
  loadingWin = new BrowserWindow({
    // show: false,
@@ -106,8 +123,8 @@
    resizable: false,
    transparent: true,
    webPreferences: {
      preload: path.join(__dirname, './preload.js')
    }
      preload: path.join(__dirname, "./preload.js"),
    },
  });
  // loadingWin.once('show', () => {
  //   cb(true);
@@ -124,30 +141,35 @@
  //     serverProcess = require('child_process').execFile(dir + '/app_x64.exe');
  //   });
  // }
  requestPromise.get(appUrl).then(function () {
    log.info('窗口初始化 服务正常');
  requestPromise.get(appUrl).then(
    function () {
      log.info("窗口初始化 服务正常");
    // ipcRenderer.send('java-ready');
    loadingWin.webContents.send('java-ready');
  }, function () {
    log.info('窗口初始化 接口不通');
    log.info('正在终止java进程,然后重启服务');
    let stop = child_process.spawn('cmd.exe', ['/c', 'stop.bat']);
    stop.on('exit', function (code) {
      loadingWin.webContents.send("java-ready");
    },
    function () {
      log.info("窗口初始化 接口不通");
      log.info("正在终止java进程,然后重启服务");
      let stop = child_process.spawn("cmd.exe", ["/c", "stop.bat"]);
      stop.on("exit", function (code) {
      if (code > 0) {
        return false;
      }
      log.info('java进程被终止,准备重启服务');
      child_process.exec(`"${process.cwd()}\\ResMeterManager.exe" restart`, (err) => {
        log.info("java进程被终止,准备重启服务");
        child_process.exec(
          `"${process.cwd()}\\ResMeterManager.exe" restart`,
          (err) => {
        if (err) {
          log.info('重启服务出错了stderr: ' + JSON.stringify(err));
          return
              log.info("重启服务出错了stderr: " + JSON.stringify(err));
              return;
        }
        log.info('服务重启成功,连接中');
            log.info("服务重启成功,连接中");
        // 等到服务就绪再重启
        checkService(() => {
          loadingWin.webContents.send('java-ready');
              loadingWin.webContents.send("java-ready");
        });
      });
          }
        );
    });
    // // 重启服务 然后重启应用
    // let restart = child_process.spawn('.\\ResMeterManager.exe', ['restart']);
@@ -169,8 +191,9 @@
    //     loadingWin.webContents.send('java-ready');
    //   });
    // });
  });
}
  );
};
async function createWindow(wait, cb) {
  // Create the browser window.
  win = new BrowserWindow({
@@ -188,46 +211,50 @@
      allowRunningInsecureContent: false,
      contextIsolation: true,
      enableRemoteModule: false,
      preload: path.join(__dirname, 'preload.js')
    }
  })
      preload: path.join(__dirname, "preload.js"),
    },
  });
  // remote.enable(win.webContents);
  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
    if (!process.env.IS_TEST) win.webContents.openDevTools()
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
    if (!process.env.IS_TEST) win.webContents.openDevTools();
  } else {
    createProtocol('app')
    createProtocol("app");
    // Load the index.html when not in development
    win.loadURL('app://./index.html')
    win.loadURL("app://./index.html");
  }
  if (wait) {
    ipcMain.on("java-ready", () => {
      log.info('java-ready!');
      log.info("java-ready!");
      loadingWin.hide();
      loadingWin.close();
      win.show();
    });
  }
  if (cb && 'function' == typeof cb) {
    win.once('ready-to-show', () => {
  if (cb && "function" == typeof cb) {
    win.once("ready-to-show", () => {
      cb(win.webContents);
    })
    });
  }
  // 英文版不做升级
  // 自动检测更新 软件的第一个实例打开后 为了不影响加载速度 在指定时间后做一次自检
  win.once('ready-to-show', () => {
    log.info('ready event');
  win.once("ready-to-show", () => {
    log.info("ready event");
    // TODO
    if ('US' != lang) {
    setTimeout(() => {
      update(win.webContents, true);
    }, 1000 * 30);
    }
  });
  win.webContents.session.on('will-download', (e, item) => {
  win.webContents.session.on("will-download", (e, item) => {
    // const filePath = path.join(saveUrl, item.getFilename());
    // item.setSavePath(filePath); // 'C:\Users\kim\Downloads\第12次.zip'
    // let value;
@@ -249,19 +276,22 @@
    //   }
    // });
    //监听下载结束事件
    item.on('done', (e, state) => {
    item.on("done", (e, state) => {
      //如果窗口还在的话,去掉进度条
      // if (!win.isDestroyed()) {
      //   win.setProgressBar(-1);
      // }
      //下载被取消或中断了
      if (state === 'interrupted') {
        dialog.showErrorBox('下载失败', `文件 ${item.getFilename()} 因为某些原因被中断下载`);
      if (state === "interrupted") {
        dialog.showErrorBox(
          "下载失败",
          `文件 ${item.getFilename()} 因为某些原因被中断下载`
        );
      }
      // 下载成功后打开文件所在文件夹
      if (state === 'completed') {
      if (state === "completed") {
        setTimeout(() => {
          shell.showItemInFolder(item.getSavePath())
          shell.showItemInFolder(item.getSavePath());
        }, 1000);
      }
    });
@@ -269,140 +299,153 @@
}
// Quit when all windows are closed.
app.on('window-all-closed', () => {
app.on("window-all-closed", () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  if (process.platform !== "darwin") {
    app.quit();
  }
})
});
app.on('activate', () => {
  log.info('app activate event');
app.on("activate", () => {
  log.info("app activate event");
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
  if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
  log.info('app ready event');
app.on("ready", async () => {
  log.info("app ready event");
  let cb = undefined;
  if (process.argv[1]) {
    cb = (sender) => {
      log.info('call selected-file..' + process.argv[1]);
      sender.send('selected-file', { filePaths: [process.argv[1]] }, 'MenuList');
    }
      log.info("call selected-file.." + process.argv[1]);
      sender.send(
        "selected-file",
        { filePaths: [process.argv[1]] },
        "MenuList"
      );
    };
  }
  if (isDevelopment) {
    createWindow();
  } else {
    showLoading(createWindow, cb);
  }
})
});
// 所有的新开窗口事件都调用系统默认浏览器来打开页面
app.on('web-contents-created', (e, webContents) => {
  webContents.on('new-window', (event, url) => {
app.on("web-contents-created", (e, webContents) => {
  webContents.on("new-window", (event, url) => {
    event.preventDefault();
    shell.openExternal(url);
  })
  });
});
ipcMain.on('open-file-dialog', (event, data) => {
  dialog.showOpenDialog({
    filters: [{ name: 'xml', extensions: ['xml'] }],
    properties: ['openFile']
  }).then((files) => {
ipcMain.on("open-file-dialog", (event, data) => {
  dialog
    .showOpenDialog({
      filters: [{ name: "xml", extensions: ["xml"] }],
      properties: ["openFile"],
    })
    .then((files) => {
    // console.log(files, '0000000')
    if (files) {
      event.sender.send('selected-file', files, data);
        event.sender.send("selected-file", files, data);
    }
  })
});
ipcMain.on('open-directory-dialog', (event, data) => {
  dialog.showOpenDialog({
    properties: ['openDirectory']
  }).then((files) => {
    if (files) {
      event.sender.send('selected-directory', files, data);
    }
});
ipcMain.on("open-directory-dialog", (event, data) => {
  dialog
    .showOpenDialog({
      properties: ["openDirectory"],
  })
    .then((files) => {
      if (files) {
        event.sender.send("selected-directory", files, data);
      }
    });
});
ipcMain.on('check-update', (event) => {
ipcMain.on("check-update", (event) => {
  // checkForUpdates();
  update(event.sender);
});
ipcMain.on('download-update', () => {
ipcMain.on("download-update", () => {
  autoUpdater.downloadUpdate();
});
ipcMain.on('quitAndInstall', () => {
ipcMain.on("quitAndInstall", () => {
  autoUpdater.quitAndInstall();
});
ipcMain.on('db-export', () => {
ipcMain.on("db-export", () => {
  // 打开窗口选择导出文件的路径
  let path = dialog.showSaveDialogSync({
    title: '导出数据库',
    filters: [{ name: 'db', extensions: ['db'] }],
    title: "导出数据库",
    filters: [{ name: "db", extensions: ["db"] }],
  });
  if (!path) {
    return false;
  }
  let src = 'res.db';
  child_process.exec(`copy "${process.cwd()}\\${src}" "${path}" /Y /V`, (err) => {
  let src = "res.db";
  child_process.exec(
    `copy "${process.cwd()}\\${src}" "${path}" /Y /V`,
    (err) => {
    if (err) {
      log.info('数据库导出出错了stderr: ' + JSON.stringify(err));
      return
        log.info("数据库导出出错了stderr: " + JSON.stringify(err));
        return;
    }
    log.info('数据库导出成功');
      log.info("数据库导出成功");
    // 打开文件夹
    shell.showItemInFolder(path);
  });
    }
  );
});
ipcMain.on('db-import', () => {
  let stop = child_process.spawn('cmd.exe', ['/c', 'stop.bat']);
  stop.on('exit', function (code) {
ipcMain.on("db-import", () => {
  let stop = child_process.spawn("cmd.exe", ["/c", "stop.bat"]);
  stop.on("exit", function (code) {
    if (code > 0) {
      return false;
    }
    // 关闭服务成功后 打开选择文件对话框 让用户选择db文件 然后复制
    let path = dialog.showOpenDialogSync({
      filters: [{ name: 'db', extensions: ['db'] }],
      properties: ['openFile']
      filters: [{ name: "db", extensions: ["db"] }],
      properties: ["openFile"],
    });
    if (path) {
      // 然后复制文件
      let src = 'res.db';
      let src = "res.db";
      // 然后复制文件
      child_process.exec(`copy "${path}" "${process.cwd()}\\${src}" /Y /V`, (err) => {
      child_process.exec(
        `copy "${path}" "${process.cwd()}\\${src}" /Y /V`,
        (err) => {
        if (err) {
          log.info('数据库导入出错了stderr: ' + JSON.stringify(err));
          return
            log.info("数据库导入出错了stderr: " + JSON.stringify(err));
            return;
        }
        log.info('数据库导入成功');
          log.info("数据库导入成功");
        // 打开服务
        let restart = child_process.spawn('ResMeterManager.exe', ['restart']);
        log.info('restart');
        restart.stdout.on('data', function (data) {
          log.info('stdout: ' + data);
          let restart = child_process.spawn("ResMeterManager.exe", ["restart"]);
          log.info("restart");
          restart.stdout.on("data", function (data) {
            log.info("stdout: " + data);
        });
        restart.stderr.on('data', function (data) {
          log.info('stderr: ' + data);
          restart.stderr.on("data", function (data) {
            log.info("stderr: " + data);
        });
        restart.on('exit', (code) => {
          restart.on("exit", (code) => {
          if (code > 0) {
            return false;
          }
          log.info('服务重启成功,准备重启应用');
            log.info("服务重启成功,准备重启应用");
          // 等到服务就绪再重启
          checkService(() => {
            // 重新启动软件
@@ -411,34 +454,34 @@
          });
        });
        let status = child_process.spawn('ResMeterManager.exe', ['status']);
        log.info('restart');
        status.stdout.on('data', function (data) {
          log.info('stdout: ' + data);
          let status = child_process.spawn("ResMeterManager.exe", ["status"]);
          log.info("restart");
          status.stdout.on("data", function (data) {
            log.info("stdout: " + data);
        });
        status.stderr.on('data', function (data) {
          log.info('stderr: ' + data);
          status.stderr.on("data", function (data) {
            log.info("stderr: " + data);
        });
      });
        }
      );
    } else {
      // 重启服务 然后重启应用
      let restart = child_process.spawn('ResMeterManager.exe', ['restart']);
      log.info('restart');
      restart.stdout.on('data', function (data) {
        log.info('stdout: ' + data);
      let restart = child_process.spawn("ResMeterManager.exe", ["restart"]);
      log.info("restart");
      restart.stdout.on("data", function (data) {
        log.info("stdout: " + data);
      });
      restart.stderr.on('data', function (data) {
        log.info('stderr: ' + data);
      restart.stderr.on("data", function (data) {
        log.info("stderr: " + data);
      });
      restart.on('exit', (code) => {
      restart.on("exit", (code) => {
        if (code > 0) {
          return false;
        }
        log.info('服务重启成功,准备重启应用');
        log.info("服务重启成功,准备重启应用");
        // 等到服务就绪再重启
        checkService(() => {
          // 重新启动软件
@@ -452,15 +495,15 @@
// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === 'win32') {
    process.on('message', (data) => {
      if (data === 'graceful-exit') {
        app.quit()
  if (process.platform === "win32") {
    process.on("message", (data) => {
      if (data === "graceful-exit") {
        app.quit();
      }
    })
    });
  } else {
    process.on('SIGTERM', () => {
      app.quit()
    })
    process.on("SIGTERM", () => {
      app.quit();
    });
  }
}
src/components/chartContextMenu.vue
@@ -54,17 +54,17 @@
    const menuList = [
      {
        id: 0,
        title: "显示/限藏数值",
        title: this.$t('other.DisplayLimitHiddenValue'),
        method: "toggleValue",
      },
      {
        id: 1,
        title: "按高-低排序",
        title: this.$t('other.SortedinHightoLow'),
        method: "sortReverse",
      },
      {
        id: 2,
        title: "按低-高排序",
        title: this.$t('other.SortedinLowtoHigh'),
        method: "sort",
      },
    ];