使用electron来创建属于自己的utools

electron介绍

Electron是跨平台的桌面应用程序框架。 Electron兼容Mac、Windows和Linux,可以构建出三个平台的应用程序。
官网:https://www.electronjs.org/zh

这是官网给出的一些使用该架构的产品 看看有没有你熟悉的呢?
你好! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

样例展示(以下均为使用快捷键ctrl+k来隐藏和展示窗口)

设置快捷键ctrl+k呼出界面和隐藏界面 密码管理和信息查询需要登录方可使用
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2503476a40e143c7b4129560a971673f.png
是密码管理界面,在这可以对本地新增加密的密码本只有登录上系统方可查看。在这里插入图片描述在这里插入图片描述
这是信息查询读取的excel内容,并加上模糊搜索在这里插入图片描述在这里插入图片描述
从热键呼出开始,进行一系列定制的快捷操作,无论是信息查询还是登记内容还是说各类的上报与跳转 都能在热键的快捷操作下完成,省去页面操作与打开文件操作需要开各种页面或是开各种文件夹的繁琐。

开始编写代码

环境的构建就不多做赘述了,安装nodejs npm 初始化环境 npm install electron
开始我们的代码演示

\\导入我们需要的模块
const { app, BrowserWindow, ipcMain, dialog ,Menu,globalShortcut,shell  } = require('electron');
const mysql = require('mysql');
const xlsx = require('xlsx');
\\创建数据库连接
const pool = mysql.createPool({
    connectionLimit: 10,
    host: '127.0.0.1',
    user: 'root',
    password: 'Asdfg12345',
    database: 'electronsql' 
  });

main.js剩下的内容我直接贴上带上注释

let isLoggedIn = false; // 标记是否已登录成功
\\创建窗口
function createWindow() {
    let mainWindow = new BrowserWindow({
        show: false,
        width: 800,
        height: 600,
        title: '密码管理',
        frame: true,
        // autoHideMenuBar: true,
        // icon: '18.ico',
        \\处理预加载脚本中调用API
        webPreferences: {
            nodeIntegration: true,
        contextIsolation: false,
        enableRemoteModule: true
        }
    });
    \\创建我们的菜单栏
    let menuTemp = [
        {
            label: '密码管理',click(){
                console.log('操作')
                \\如果登录了就可以进行点击
                if (isLoggedIn) {
                    console.log('操作');
                    \\点击密码管理后将窗口跳转到password页面
                    const focusedWindow = BrowserWindow.getFocusedWindow();
    focusedWindow.loadFile('password.html');
                } else {
                    dialog.showMessageBox({
                        type: 'warning',
                        message: '请先登录'
                    });
                }
             }
        },
        {
            label: '信息查询',
            submenu: [
                {label:'交易区VIP查询',
                click(){
                    console.log('操作')
                    if (isLoggedIn) {
                        console.log('操作');
                    } else {
                        dialog.showMessageBox({
                            type: 'warning',
                            message: '请先登录'
                        });
                    }
                 },
                },
                {type: 'separator' },
                {label:'非交易区VIP查询',click(){
                    console.log('操作')
                    if (isLoggedIn) {
                        console.log('操作');
                    } else {
                        dialog.showMessageBox({
                            type: 'warning',
                            message: '请先登录'
                        });
                    }
                 },},
                {type: 'separator' },
                {label:'查询物理机上的虚拟机',click(){
                    console.log('操作')
                    if (isLoggedIn) {
                        console.log('操作');
                    } else {
                        dialog.showMessageBox({
                            type: 'warning',
                            message: '请先登录'
                        });
                    }
                 },},
                 {type: 'separator' },
                 {label:'服务器明细查询',click(){
                     console.log('操作')
                     if (isLoggedIn) {\\查询服务器信息点击后跳转到新页面
                        const focusedWindow = BrowserWindow.getFocusedWindow();
    focusedWindow.loadFile('servermessage.html'); 
                         console.log('操作');
                     } else {
                         dialog.showMessageBox({
                             type: 'warning',
                             message: '请先登录'
                         });
                     }
                  },},
                  {type: 'separator' },
                  {label:'万国服务器',click(){
                      console.log('操作')
                      if (isLoggedIn) {
                         const focusedWindow = BrowserWindow.getFocusedWindow();
     focusedWindow.loadFile('wanguo.html'); 
                          console.log('操作');
                      } else {
                          dialog.showMessageBox({
                              type: 'warning',
                              message: '请先登录'
                          });
                      }
                   },}
            ]
        },
        {
            label: '上报',click(){
                console.log('操作')
                if (isLoggedIn) {
                    console.log('操作');
                } else {
                    dialog.showMessageBox({
                        type: 'warning',
                        message: '请先登录'
                    });
                }
             },
            submenu: [
                {label:'发布上报',
                 click(){
                    console.log('操作')
                    if (isLoggedIn) {
                        console.log('操作');
                    } else {
                        dialog.showMessageBox({
                            type: 'warning',
                            message: '请先登录'
                        });
                    }
                 }
                },
                {type: 'separator' },
                {label:'演练上报',
                click(){
                    console.log('操作')
                    if (isLoggedIn) {
                        console.log('操作');
                    } else {
                        dialog.showMessageBox({
                            type: 'warning',
                            message: '请先登录'
                        });
                    }
                 }},
                {type: 'separator' },
                {label:'故障上报',
                click(){
                    console.log('操作')
                    if (isLoggedIn) {
                        console.log('操作');
                    } else {
                        dialog.showMessageBox({
                            type: 'warning',
                            message: '请先登录'
                        });
                    }
                 }}
            ]
        },
        {
            label: '跳转',click(){
                console.log('操作')
                
             },
            submenu: [
                {label:'交易区workflow跳转',
                 click(){
                    
                    console.log('操作')
                    // if (isLoggedIn) {
                        console.log('操作');
                        const url = 'https://xxxxx; \\跳转到浏览器页面
                        shell.openExternal(url); 
                    // } else {
                    //     dialog.showMessageBox({
                    //         type: 'warning',
                    //         message: '请先登录'
                    //     });
                    // }
                 }
                },
                {type: 'separator' },
                {label:'非交易区工作证跳转',
                click(){
                    console.log('操作')
                    // if (isLoggedIn) {
                        console.log('操作');
                        const url = 'https://xxx'; 
                        shell.openExternal(url); 
                    // } else {
                    //     dialog.showMessageBox({
                    //         type: 'warning',
                    //         message: '请先登录'
                    //     });
                    // }
                 }},
                {type: 'separator' },
                {label:'交易区cmdb跳转',
                click(){
                    console.log('操作')
                    // if (isLoggedIn) {
                        const url = 'https://xxxx'; 
                        shell.openExternal(url); 
                        console.log('操作');
                    // } else {
                    //     dialog.showMessageBox({
                    //         type: 'warning',
                    //         message: '请先登录'
                    //     });
                    // }
                 }}
            ]
        }
    ]
    let menu = Menu.buildFromTemplate(menuTemp)

    Menu.setApplicationMenu(menu)
    mainWindow.loadFile('index.html');
    \\热键注册 触发ctrl+k时就对界面隐藏和显示操作
    globalShortcut.register('CommandOrControl+k', () => {
        if (mainWindow.isVisible()) {
          mainWindow.hide()
        } else {
          mainWindow.show()
        }
      })
    // mainWindow.webContents.openDevTools()
    mainWindow.on('ready-to-show',() => {
        mainWindow.show()
    })
    mainWindow.webContents.on('did-finish-load',()=>{
    })
    mainWindow.webContents.on('dom-ready',()=>{
    })
    mainWindow.on('closed',()=>{
        mainWindow = null
    });
}
//初始化完成
app.on('ready', ()=>{
    console.log('1111-ready')
    createWindow()
    \\监听点击登录按钮后的请求,在数据库查找数据 有该用户即为登录成功
    ipcMain.on('managepwd', (ev,name,password) => {
        console.log(name,password),
        pool.query('SELECT * FROM accounts WHERE username = ? AND password = ?', [name, password], (error, results, fields) => {
            if (error) {
              console.error('Error executing query:', error);
              return;
            }
            if (results.length > 0) {
              console.log('Account and password found:', results[0]);
              isLoggedIn=true
              ev.sender.send('managepwdResult', true);
            } else {
              console.log('Account and password not found');
              ev.sender.send('managepwdResult', false);
            }
          });
      });
    ipcMain.on('openSettingWindow', (ev,data) => {
        console.log(data)
        ev.sender.send('getmsg','getmsg')
        let indexMin = new BrowserWindow({
          width: 200,
          height: 200,
        });
        indexMin.loadFile('password.html');
        indexMin.on('close', () => {
          indexMin = null;
        });
      });
});

接下来是登录界面index.html与他的预加载脚本,很简单的代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
    <link href="./styles.css" rel="stylesheet">
    <title></title>
  </head>
  <body>
    <div id="background-container"></div>
    <input type="text" id="name" placeholder="账号"><br>
    <input type="text" id="password" placeholder="密码"><br>
    <button id="btn">登录</button><br>
    <script src="./renderer.js"></script>

  </body>
  <style>body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
}

input[type="text"], input[type="password"] {
    width: 300px;
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
}

button {
    padding: 10px 20px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

button:hover {
    background-color: #0056b3;
}

#background-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: url('./dg.webp'); 
    background-size: cover; 
    background-position: center; 
    z-index: -1; 
}

</style>
</html>

const { ipcRenderer  } = require('electron')
const name = document.getElementById('name');
const password = document.getElementById('password');
// name.addEventListener('keydown', (event) => {
//   if (event.key === 'Enter') { 
//     const inputValue = textInput.value.trim();
//     if (inputValue === '密码') {
//       window.location.href = 'password.html';
//     }
//   }
// });




window.addEventListener('DOMContentLoaded',() => {
  const oBtn = document.getElementById('btn');
  
  oBtn.addEventListener('click', () => {
    const nameValue = name.value.trim();
    const passwordValue = password.value.trim();
    console.log(nameValue,passwordValue)
    ipcRenderer.send('managepwd',nameValue,passwordValue);
    ipcRenderer.on('managepwdResult',(ev,data) => {
      if (!data) { 
        console.log('无数据')}
    })
  });
})

下面再展示一下密码管理这块的内容

password.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Password Manager</title>
</head>
<body>
    <h1>Password Manager</h1>
    <button onclick="showInputFields()">新增密码</button>
    <div id="inputFields" style="display: none;">
        <input type="text" id="deviceNameInput" placeholder="设备名">
        <input type="text" id="usernameInput" placeholder="账号">
        <input type="password" id="passwordInput" placeholder="密码">
        <button onclick="savePassword()">保存</button>
    </div>
    <table id="passwordTable" border="1">
        <thead>
            <tr>
                <th>设备名</th>
                <th>账号</th>
                <th>密码</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
     <style>.password-hidden {
        display: none;
    }
    body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
}

h1 {
    text-align: center;
}

#inputFields {
    margin-bottom: 20px;
}

#passwordTable {
    width: 100%;
    border-collapse: collapse;
}

#passwordTable th, #passwordTable td {
    padding: 10px;
    text-align: center;
}

#passwordTable th {
    background-color: #f0f0f0;
}

#passwordTable tbody tr:nth-child(even) {
    background-color: #f9f9f9;
}

.password-masked {
    display: inline;
}

.password-hidden {
    display: none;
}

.show-password-btn {
    cursor: pointer;
    background-color: #007bff;
    color: #fff;
    border: none;
    padding: 5px 10px;
    border-radius: 5px;
}

.show-password-btn:hover {
    background-color: #0056b3;
}

    </style>
    <!-- 引入通信脚本 -->
    <script src="./test.js"></script>
</body>
</html>

然后是他的test.js脚本

const fs = require('fs');
const path = require('path');
const CryptoJS = require('crypto-js'); 
const passwordFilePath = path.join('D:', '18tools', 'password.json');\\密码本保存路径
const SECRET_KEY = 'xxxxxxxx';\\ 加密秘钥
function createPasswordFile() {\\创建密码本的函数
    if (!fs.existsSync(passwordFilePath)) {
        const passwordFolder = path.dirname(passwordFilePath);
        if (!fs.existsSync(passwordFolder)) {
            fs.mkdirSync(passwordFolder, { recursive: true });
        }
        fs.writeFileSync(passwordFilePath, '{}');
    }
}

function readPasswordFile() {\\读取密码本的函数,并解密密码本中的加密字段
    try {
        const encryptedData = fs.readFileSync(passwordFilePath, 'utf8');
        const decryptedPasswords = JSON.parse(encryptedData);
        for (const deviceName in decryptedPasswords) {
            const encryptedPassword = decryptedPasswords[deviceName].password;
            const decryptedPassword = CryptoJS.AES.decrypt(encryptedPassword, SECRET_KEY).toString(CryptoJS.enc.Utf8);
            decryptedPasswords[deviceName].password = decryptedPassword;
        }
        return decryptedPasswords;
    } catch (err) {
        console.error('Failed to read password file:', err);
        return {};
    }
}


function showInputFields() {
    const inputFields = document.getElementById('inputFields');
    inputFields.style.display = 'block';
}
#点击保存密码执行函数  将密码字段加密存进密码本
function savePassword() {
    createPasswordFile(); 
    const deviceName = document.getElementById('deviceNameInput').value.trim();
    const username = document.getElementById('usernameInput').value.trim();
    const password = document.getElementById('passwordInput').value.trim();

    if (!deviceName || !username || !password) {
        alert('请填写完整信息!');
        return;
    }

    if (deviceName || username || password) {
        try {
            const passwords = readPasswordFile();
            for (const existingDeviceName in passwords) {
                const existingPassword = passwords[existingDeviceName].password;
                const encryptedExistingPassword = CryptoJS.AES.encrypt(existingPassword, SECRET_KEY).toString();
                passwords[existingDeviceName].password = encryptedExistingPassword;
            }

            const encryptedPassword = CryptoJS.AES.encrypt(password, SECRET_KEY).toString();
            passwords[deviceName] = { username, password: encryptedPassword };

            fs.writeFileSync(passwordFilePath, JSON.stringify(passwords, null, 2), 'utf8'); // 使用 UTF-8 编码

            const inputFields = document.getElementById('inputFields');
            inputFields.style.display = 'none';
            document.getElementById('deviceNameInput').value = '';
            document.getElementById('usernameInput').value = '';
            document.getElementById('passwordInput').value = '';
            loadPasswordTable();
            return true;
        } catch (err) {
            console.error('Failed to save password:', err);
            return false;
        };
    }
}
\\加载页面表格
function loadPasswordTable() {
    const passwords = readPasswordFile();
    const tbody = document.querySelector('#passwordTable tbody');
    tbody.innerHTML = '';

    for (const deviceName in passwords) {
        const tr = document.createElement('tr');
        const password = passwords[deviceName].password;
        const maskedPassword = '*'.repeat(password.length); // 将密码用 * 替代

        tr.innerHTML = `
            <td>${deviceName}</td>
            <td>${passwords[deviceName].username}</td>
            <td>
                <span class="password-masked"  >${maskedPassword}</span>
                <button class="show-password-btn" onclick="togglePasswordVisibility(this)">显示密码</button>
                <span class="password-hidden" style.display = 'none'  >${password}</span>
            </td>
        `;
        tbody.appendChild(tr);
    }
}
#表格中的显示隐藏密码功能
function togglePasswordVisibility(btn) {
    const passwordCell = btn.parentNode;
    const maskedPassword = passwordCell.querySelector('.password-masked');
    const hiddenPassword = passwordCell.querySelector('.password-hidden');

    if (maskedPassword.style.display !== 'none') {
        maskedPassword.style.display = 'none';
        hiddenPassword.style.display = 'inline';
        btn.textContent = '隐藏密码';
    } else {
        maskedPassword.style.display = 'inline';
        hiddenPassword.style.display = 'none';
        btn.textContent = '显示密码';
    }
}
window.addEventListener('DOMContentLoaded', () => {
    loadPasswordTable();
});

本次主要是为了分享一下electron的实用性,在添加了热键之后能将很大一部分需要多次点击才能实现的内容操作直接通过快捷键的方式来完成,且实现的代码也并不复杂,可以说是是实用性很强的一次实践。

剩下的表格展示代码我就不演示了需要完整代码内容的可以联系。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Electron 是一种基于 Node.js 和 Chromium 的框架,可用于创建可扩展的桌面应用程序。以下是使用 Electron 创建可扩展应用程序的基本步骤: 1. 安装 Node.js 和 Electron:首先,您需要安装 Node.js 和 Electron。您可以从官方网站下载并安装 Node.js,然后使用 npm 安装 Electron。 2. 创建项目目录:创建一个新的项目目录并在其中初始化 npm。打开命令行界面并输入以下命令: ``` mkdir my-electron-app cd my-electron-app npm init ``` 然后按照提示进行配置,创建 package.json 文件。 3. 安装 Electron使用 npm 安装 Electron。 ``` npm install electron --save-dev ``` 这将在项目中安装 Electron,并将其添加到 package.json 文件中的 devDependencies。 4. 创建主进程文件:创建一个名为 main.js 的文件,这将是您的应用程序的主进程文件。主进程是使用 Electron API 和 Node.js 模块来控制应用程序的进程。在 main.js 文件中,您可以编写用于初始化应用程序的代码。 5. 创建渲染进程文件:创建一个名为 index.html 的文件,这将是您的应用程序的渲染进程文件。渲染进程是在应用程序窗口中运行的 JavaScript 代码。在 index.html 文件中,您可以编写应用程序的用户界面和其他代码。 6. 编写应用程序代码:使用 Electron API 和 Node.js 模块来编写应用程序的代码。您可以在主进程中添加事件监听器和其他逻辑,例如在应用程序启动时创建窗口。在渲染进程中,您可以使用 HTML、CSS 和 JavaScript 编写应用程序的用户界面。 7. 打包应用程序:一旦您完成了应用程序的开发,可以使用 Electron-packager 或 Electron-builder 等工具将其打包为可执行文件。 这些是使用 Electron 创建可扩展应用程序的基本步骤。请注意,Electron 可以与其他框架和库一起使用,例如 React 和 Angular,以创建更复杂的应用程序。 ### 回答2: Electron是一个开源的框架,用于创建可扩展的跨平台应用程序。它基于Chromium和Node.js,并允许使用前端技术如HTML、CSS和JavaScript来开发应用程序。下面是如何使用Electron创建可扩展应用程序的步骤: 1. 安装Electron:首先,您需要在您的开发环境中安装Electron。您可以使用命令行工具(如npm)来进行安装。 2. 创建新应用程序:创建一个新的应用程序目录,并在其中初始化您的Electron应用程序。您可以使用Electron提供的命令行工具来简化这个过程。 3. 配置主进程:Electron应用程序有两个主要进程:主进程和渲染进程。主进程负责处理系统级的任务,而渲染进程负责显示用户界面。您可以使用Node.js编写主进程代码,并在主进程中创建BrowserWindow实例来加载和显示渲染进程。 4. 编写HTML和CSS代码:您可以使用HTML和CSS来设计和布局应用程序的用户界面。您可以使用DOM API和Web API来处理用户交互和响应。 5. 添加JavaScript逻辑:使用JavaScript编写应用程序的逻辑。您可以访问Node.js的API来处理文件操作、网络请求等任务。您还可以使用Electron的API来访问系统级功能如显示通知、打开文件选择对话框等。 6. 打包和发布:当您完成应用程序的开发后,您可以使用Electron提供的打包工具来将应用程序打包为各个操作系统的可执行文件。您可以选择将应用程序发布到各个应用商店或通过其他方式进行分发。 使用Electron可以轻松地创建可扩展的跨平台应用程序。它使开发人员可以在一个代码库中同时使用前端和后端技术,从而加速开发过程并提高开发效率。同时,Electron还使得应用程序可以跨平台运行,从而扩大了应用程序的受众范围。 ### 回答3: 使用Electron创建可扩展应用程序,需要以下几个步骤: 1. 安装Electron:首先需要在计算机上安装Electron的开发环境。可以通过npm包管理器安装Electron的命令行工具。 2. 初始化项目:通过命令行工具,在项目文件夹中初始化一个Electron项目。这将生成一个包含基本应用程序结构的目录。 3. 编写主进程代码:在主进程文件中编写应用程序的主要逻辑。主进程可以访问底层操作系统的API并控制应用程序的整体流程。 4. 编写渲染进程代码:在渲染进程文件中编写应用程序的界面和交互逻辑。渲染进程使用HTML、CSS和JavaScript创建用户界面,并通过与主进程进行通信来实现应用程序的功能。 5. 扩展应用程序功能:通过使用Electron的API和第三方库,可以为应用程序添加各种功能。例如,可以使用Electron的窗口管理API来创建新窗口或添加自定义菜单。还可以使用第三方库来实现文件系统访问、网络请求、数据库连接等功能。 6. 打包应用程序:完成开发后,可以使用Electron的打包工具将应用程序打包成可执行文件。这样用户就可以在其操作系统上安装和运行应用程序。 总的来说,使用Electron创建可扩展应用程序需要结合主进程和渲染进程的编程,利用Electron的API和第三方库来实现所需功能,并最终通过打包工具将应用程序打包成可执行文件。这样就能创建出一个支持跨平台、易于扩展的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值