electron开发一个pc桌面chatgpt聊天程序
chatgpt为首的人工智能的兴起给aigc带来了重大的发展,我们无需在打开搜索引擎,直接用chatgpt进行搜索,今天我们来使用electron开发一个可在linux、windows、mac运行的chatgpt客户端,先看效果:
这是托盘及菜单
当我们关闭窗体的时候他会自动隐藏起来没有退出,当我们按快捷键ctrl+shift+x的时候,他又会显示出来,非常的方便,那么我们来讲解一下如何开发这样的electron程序。
一、标题
1. 安装electron-forge:在命令行中输入`npm install -g electron-forge`,安装完成后可以使用`electron-forge`命令。2. 创建一个新的electron-forge项目:在命令行中输入`electron-forge init my-app`,其中`my-app`是你的项目名称。3. 进入项目目录:在命令行中输入`cd my-app`。4. 创建主进程文件:在项目根目录下创建一个`main.js`文件,这是应用程序的主进程文件。
5. 编写主进程代码:在`main.js`文件中编写应用程序的主进程代码,例如创建窗口、处理事件等。
import { app, BrowserWindow ,globalShortcut,Menu, Tray } from 'electron'; // Handle creating/removing shortcuts on Windows when installing/uninstalling. if (require('electron-squirrel-startup')) { // eslint-disable-line global-require app.quit(); } // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let mainWindow; let tray = null; let isquit=false; const createWindow = () => { // Create the browser window. mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true }, icon: `${__dirname}/icon.png` }); mainWindow.setMenuBarVisibility(false) // and load the index.html of the app. mainWindow.loadURL(`file://${__dirname}/index.html`); // Open the DevTools. // mainWindow.webContents.openDevTools(); mainWindow.on('close', function (e) { if(!isquit){ e.preventDefault(); mainWindow.hide(); } }) // Emitted when the window is closed. mainWindow.on('closed', () => { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. //mainWindow.minimize() mainWindow = null; }); // 注册全局快捷键 globalShortcut.register('CommandOrControl+Shift+X', () => { mainWindow.show() console.log('全局快捷键被触发') }) }; // 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', createWindow); // Quit when all windows are closed. app.on('window-all-closed', () => { // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q //event.preventDefault(); // 防止默认行为 //mainWindow.minimize(); if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { // On OS X 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 (mainWindow === null) { createWindow(); } }); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and import them here. //const { app, globalShortcut } = require('electron') app.whenReady().then(() => { tray = new Tray(`${__dirname}/icon.png`); const contextMenu = Menu.buildFromTemplate([ {label: '显示',click: () => { mainWindow.show();}}, // {label: '显示, type: 'radio', checked: true}, {label: '退出', click: () => { isquit=true;mainWindow.close();app.quit()}} ]); tray.setContextMenu(contextMenu); tray.on("click",()=>{ mainWindow.show(); //tray.destory() }) }); app.on('will-quit', () => { // 注销全局快捷键 globalShortcut.unregisterAll() })6. 创建渲染进程文件:在项目根目录下创建一个`index.html`文件,这是应用程序的渲染进程文件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta charset="utf-8" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" /> <style> @charset "UTF-8"; @import url("https://fonts.googleapis.com/css?family=Manrope:300,400,500,600,700&display=swap&subset=latin-ext"); :root { --body-bg-color: #e5ecef; --theme-bg-color: #fff; --settings-icon-hover: #9fa7ac; --developer-color: #f9fafb; --input-bg: #f8f8fa; --input-chat-color: #a2a2a2; --border-color: #eef2f4; --body-font: "Manrope", sans-serif; --body-color: #273346; --settings-icon-color: #c1c7cd; --msg-message: #969eaa; --chat-text-bg: #f1f2f6; --theme-color: #0086ff; --msg-date: #c0c7d2; --button-bg-color: #f0f7ff; --button-color: var(--theme-color); --detail-font-color: #919ca2; --msg-hover-bg: rgba(238, 242, 244, 0.4); --active-conversation-bg: linear-gradient( to right, rgba(238, 242, 244, 0.4) 0%, rgba(238, 242, 244, 0) 100% ); --overlay-bg: linear-gradient( to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 65%, rgba(255, 255, 255, 1) 100% ); --chat-header-bg: linear-gradient( to bottom, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 78%, rgba(255, 255, 255, 0) 100% ); } [data-theme=purple] { --theme-color: #9f7aea; --button-color: #9f7aea; --button-bg-color: rgba(159, 122, 234, 0.12); } [data-theme=green] { --theme-color: #38b2ac; --button-color: #38b2ac; --button-bg-color: rgba(56, 178, 171, 0.15); } [data-theme=orange] { --theme-color: #ed8936; --button-color: #ed8936; --button-bg-color: rgba(237, 137, 54, 0.12); } .dark-mode { --body-bg-color: #1d1d1d; --theme-bg-color: #27292d; --border-color: #323336; --body-color: #d1d1d2; --active-conversation-bg: linear-gradient( to right, rgba(47, 50, 56, 0.54), rgba(238, 242, 244, 0) 100% ); --msg-hover-bg: rgba(47, 50, 56, 0.54); --chat-text-bg: #383b40; --chat-text-color: #b5b7ba; --msg-date: #626466; --msg-message: var(--msg-date); --overlay-bg: linear-gradient( to bottom, rgba(0, 0, 0, 0) 0%, #27292d 65%, #27292d 100% ); --input-bg: #2f3236; --chat-header-bg: linear-gradient( to bottom, #27292d 0%, #27292d 78%, rgba(255, 255, 255, 0) 100% ); --settings-icon-color: #7c7e80; --developer-color: var(--border-color); --button-bg-color: #393b40; --button-color: var(--body-color); --input-chat-color: #6f7073; --detail-font-color: var(--input-chat-color); } .blue { background-color: #0086ff; } .purple { background-color: #9f7aea; } .green { background-color: #38b2ac; } .orange { background-color: #ed8936; } * { outline: none; box-sizing: border-box; } img { max-width: 100%; } body { background-color: var(--body-bg-color); font-family: var(--body-font); color: var(--body-color); } html { box-sizing: border-box; -webkit-font-smoothing: antialiased; } .app { display: flex; flex-direction: column; background-color: var(--theme-bg-color); max-width: 1600px; height: 100vh; margin: 0 auto; overflow: hidden; } .header { height: 80px; width: 100%; border-bottom: 1px solid var(--border-color); display: flex; align-items: center; padding: 0 20px; } .wrapper { width: 100%; display: flex; flex-grow: 1; overflow: hidden; } .conversation-area, .detail-area { width: 340px; flex-shrink: 0; } .detail-area { border-left: 1px solid var(--border-color); margin-left: auto; padding: 30px 30px 0 30px; display: flex; flex-direction: column; overflow: auto; } .chat-area { flex-grow: 1; } .search-bar { height: 80px; z-index: 3; position: relative; margin-left: 280px; } .search-bar input { height: 100%; width: 100%; display: block; background-color: transparent; border: none; color: var(--body-color); padding: 0 54px; background-repeat: no-repeat; background-size: 16px; background-position: 25px 48%; font-family: var(--body-font); font-weight: 600; font-size: 15px; } .search-bar input::placeholder { color: var(--input-chat-color); } .logo { color: var(--theme-color); width: 38px; flex-shrink: 0; } .logo svg { width: 100%; } .user-settings { display: flex; align-items: center; cursor: pointer; margin-left: auto; flex-shrink: 0; } .user-settings > * + * { margin-left: 14px; } .dark-light { width: 22px; height: 22px; color: var(--settings-icon-color); flex-shrink: 0; } .dark-light svg { width: 100%; fill: transparent; transition: 0.5s; } .user-profile { width: 40px; height: 40px; border-radius: 50%; } .settings { color: var(--settings-icon-color); width: 22px; height: 22px; flex-shrink: 0; } .conversation-area { border-right: 1px solid var(--border-color); overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; position: relative; } .msg-profile { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; margin-right: 15px; } .msg-profile.group { display: flex; justify-content: center; align-items: center; background-color: var(--border-color); } .msg-profile.group svg { width: 60%; } .msg { display: flex; align-items: center; padding: 20px; cursor: pointer; transition: 0.2s; position: relative; } .msg:hover { background-color: var(--msg-hover-bg); } .msg.active { background: var(--active-conversation-bg); border-left: 4px solid var(--theme-color); } .msg.online:before { content: ""; position: absolute; background-color: #23be7e; width: 9px; height: 9px; border-radius: 50%; border: 2px solid var(--theme-bg-color); left: 50px; bottom: 19px; } .msg-username { margin-bottom: 4px; font-weight: 600; font-size: 15px; } .msg-detail { overflow: hidden; } .msg-content { font-weight: 500; font-size: 13px; display: flex; } .msg-message { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--msg-message); } .msg-date { font-size: 14px; color: var(--msg-date); margin-left: 3px; } .msg-date:before { content: "•"; margin-right: 2px; } .add { position: sticky; bottom: 25px; background-color: var(--theme-color); width: 60px; height: 60px; border: 0; border-radius: 50%; background-repeat: no-repeat; background-position: 50%; background-size: 28px; box-shadow: 0 0 16px var(--theme-color); margin: auto auto -55px; flex-shrink: 0; z-index: 1; cursor: pointer; } .overlay { position: sticky; bottom: 0; left: 0; width: 340px; flex-shrink: 0; background: var(--overlay-bg); height: 80px; } .chat-area { display: flex; flex-direction: column; overflow: auto; } .chat-area-header { display: flex; position: sticky; top: 0; left: 0; z-index: 2; width: 100%; align-items: center; justify-content: space-between; padding: 20px; background: var(--chat-header-bg); } .chat-area-profile { width: 32px; border-radius: 50%; object-fit: cover; } .chat-area-title { font-size: 18px; font-weight: 600; } .chat-area-main { flex-grow: 1; } .chat-msg-img { height: 40px; width: 40px; border-radius: 50%; object-fit: cover; } .chat-msg-profile { flex-shrink: 0; margin-top: auto; margin-bottom: -20px; position: relative; } .chat-msg-date { position: absolute; left: calc(100% + 12px); bottom: 0; font-size: 12px; font-weight: 600; color: var(--msg-date); white-space: nowrap; } .chat-msg { display: flex; padding: 0 20px 45px; } .chat-msg-content { margin-left: 12px; max-width: 70%; display: flex; flex-direction: column; align-items: flex-start; } .chat-msg-text { background-color: var(--chat-text-bg); padding: 15px; border-radius: 20px 20px 20px 0; line-height: 1.5; font-size: 14px; font-weight: 500; } .chat-msg-text + .chat-msg-text { margin-top: 10px; } .chat-msg-text { color: var(--chat-text-color); } .owner { flex-direction: row-reverse; } .owner .chat-msg-content { margin-left: 0; margin-right: 12px; align-items: flex-end; } .owner .chat-msg-text { background-color: var(--theme-color); color: #fff; border-radius: 20px 20px 0 20px; } .owner .chat-msg-date { left: auto; right: calc(100% + 12px); } .chat-msg-text img { max-width: 300px; width: 100%; } .chat-area-footer { display: flex; border-top: 1px solid var(--border-color); width: 100%; padding: 10px 20px; align-items: center; background-color: var(--theme-bg-color); position: sticky; bottom: 0; left: 0; } .chat-area-footer svg { color: var(--settings-icon-color); width: 20px; flex-shrink: 0; cursor: pointer; } .chat-area-footer svg:hover { color: var(--settings-icon-hover); } .chat-area-footer svg + svg { margin-left: 12px; } .chat-area-footer input { border: none; color: var(--body-color); background-color: var(--input-bg); padding: 12px; border-radius: 6px; font-size: 15px; margin: 0 12px; width: 100%; } .chat-area-footer input::placeholder { color: var(--input-chat-color); } .detail-area-header { display: flex; flex-direction: column; align-items: center; } .detail-area-header .msg-profile { margin-right: 0; width: 60px; height: 60px; margin-bottom: 15px; } .detail-title { font-size: 18px; font-weight: 600; margin-bottom: 10px; } .detail-subtitle { font-size: 12px; font-weight: 600; color: var(--msg-date); } .detail-button { border: 0; background-color: var(--button-bg-color); padding: 10px 14px; border-radius: 5px; color: var(--button-color); display: flex; align-items: center; justify-content: center; font-size: 14px; flex-grow: 1; font-weight: 500; } .detail-button svg { width: 18px; margin-right: 10px; } .detail-button:last-child { margin-left: 8px; } .detail-buttons { margin-top: 20px; display: flex; width: 100%; } .detail-area input { background-color: transparent; border: none; width: 100%; color: var(--body-color); background-repeat: no-repeat; background-size: 16px; background-position: 100%; font-family: var(--body-font); font-weight: 600; font-size: 14px; border-bottom: 1px solid var(--border-color); padding: 14px 0; } .detail-area input::placeholder { color: var(--detail-font-color); } .detail-changes { margin-top: 40px; } .detail-change { color: var(--detail-font-color); font-family: var(--body-font); font-weight: 600; font-size: 14px; border-bottom: 1px solid var(--border-color); padding: 14px 0; display: flex; } .detail-change svg { width: 16px; margin-left: auto; } .colors { display: flex; margin-left: auto; } .color { width: 16px; height: 16px; border-radius: 50%; cursor: pointer; } .color.selected { background-size: 10px; background-position: center; background-repeat: no-repeat; } .color:not(:last-child) { margin-right: 4px; } .detail-photo-title { display: flex; align-items: center; } .detail-photo-title svg { width: 16px; } .detail-photos { margin-top: 30px; text-align: center; } .detail-photo-title { color: var(--detail-font-color); font-weight: 600; font-size: 14px; margin-bottom: 20px; } .detail-photo-title svg { margin-right: 8px; } .detail-photo-grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-column-gap: 6px; grid-row-gap: 6px; grid-template-rows: repeat(3, 60px); } .detail-photo-grid img { height: 100%; width: 100%; object-fit: cover; border-radius: 8px; object-position: center; } .view-more { color: var(--theme-color); font-weight: 600; font-size: 15px; margin: 25px 0; } .follow-me { text-decoration: none; font-size: 14px; width: calc(100% + 60px); margin-left: -30px; display: flex; align-items: center; margin-top: auto; overflow: hidden; color: #9c9cab; padding: 0 20px; height: 52px; flex-shrink: 0; position: relative; justify-content: center; } .follow-me svg { width: 16px; height: 16px; margin-right: 8px; } .follow-text { display: flex; align-items: center; transition: 0.3s; } .follow-me:hover .follow-text { transform: translateY(100%); } .follow-me:hover .developer { top: 0; } .developer { position: absolute; color: var(--detail-font-color); font-weight: 600; left: 0; top: -100%; display: flex; transition: 0.3s; padding: 0 20px; align-items: center; justify-content: center; background-color: var(--developer-color); width: 100%; height: 100%; } .developer img { border-radius: 50%; width: 26px; height: 26px; object-fit: cover; margin-right: 10px; } .dark-mode .search-bar input, .dark-mode .detail-area input { } .dark-mode .dark-light svg { fill: #ffce45; stroke: #ffce45; } .dark-mode .chat-area-group span { color: #d1d1d2; } .chat-area-group { flex-shrink: 0; display: flex; } .chat-area-group * { border: 2px solid var(--theme-bg-color); } .chat-area-group * + * { margin-left: -5px; } .chat-area-group span { width: 32px; height: 32px; background-color: var(--button-bg-color); color: var(--theme-color); border-radius: 50%; display: flex; justify-content: center; align-items: center; font-size: 14px; font-weight: 500; } @media (max-width: 1120px) { .detail-area { display: none; } } @media (max-width: 780px) { .conversation-area { display: none; } .search-bar { margin-left: 0; flex-grow: 1; } .search-bar input { padding-right: 10px; } } .confirm_box_wrapper{position: fixed;top: 0;bottom: 0;left: 0;right: 0;text-align: center;z-index: 2000;} .confirm_model {position: fixed;left: 0;top: 0;width: 100%;height: 100%;opacity: .5;background: #000;z-index:2001 ;} .confirm_box{display: inline-block; width: 420px;padding-bottom: 10px;vertical-align: middle; background-color: #fff;border-radius: 4px;border: 1px solid #ebeef5;font-size: 18px;box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);text-align: left; overflow: hidden;backface-visibility: hidden; position: absolute; top:30%; left: 50%; transform: translateY(-30%); transform: translateX(-50%);z-index: 2002;} .confirm_header{ height: auto; overflow: hidden;display: flex;padding: 15px 15px 10px;justify-items: center; align-items: center;} .confirm_header .confirm_title{flex: 1;} .confirm_header .confirm_title span{font-size: 18px;color: #20202A;} .confirm_header .confirm_close{width: 16px; height: 16px;overflow: hidden; cursor: pointer;} .confirm_header .confirm_close i{display: block;width: 16px; height: 16px; background: url('https://repo.bfw.wiki/bfwrepo/images/notice/icon_close.png') no-repeat;background-size:100% ;} .confirm_content{display: flex;padding: 10px 15px; color: #606266;font-size: 14px;align-items: center;} .confirm_content .confirm_icon{width: 25px; height: 25px; overflow: hidden;} .confirm_content .confirm_message{ flex: 1;padding-left: 10px;} .confirm_content .confirm_icon_warning{ background: url("https://repo.bfw.wiki/bfwrepo/images/notice/icon_warning.png") no-repeat; background-size:100% ;} .confirm_content .confirm_icon_success{background: url("https://repo.bfw.wiki/bfwrepo/images/notice/icon_success.png") no-repeat; background-size:100% ;} .confirm_content .confirm_icon_error{background: url("https://repo.bfw.wiki/bfwrepo/images/notice/icon_error.png") no-repeat; background-size:100% ;} .confirm_btns{text-align: center;padding: 15px 15px;} .confirm_btns button{display: inline-block;line-height: 1;white-space: nowrap;cursor: pointer;background: #fff;border: 1px solid #dcdfe6; color: #606266;-webkit-appearance: none;text-align: center;font-size: 14px; box-sizing: border-box;outline: none;margin: 0;transition: .1s;font-weight: 500;-moz-user-select: none; -webkit-user-select: none;-ms-user-select: none; padding: 9px 20px;font-size: 14px;border-radius: 4px; } .confirm_btns button.btns_default{margin-right: 15px;} .confirm_btns button.btns_default:hover{color: #0D53FB; border-color:#0D53FB ;} .confirm_btns button.btns_primary{background: #0D53FB; border-color:#0D53FB ;color: #fff;} .YiJia_message{ position: fixed; top:30px;left: 50%;height: 42px;line-height: 42px; background: #fff;min-width: 200px;color: #666; box-shadow: 0 2px 4px rgb(0 0 0 / 12%), 0 0 6px rgb(0 0 0 / 4%);z-index:99999999; border-radius: 8px;overflow: hidden;} .YiJia_message .YiJia_message_main{display: flex;color: #fff;font-size: 14px; align-items: center;padding: 0px 15px;} .YiJia_message .YiJia_bg_success{background: #4AC396;} .YiJia_message .YiJia_bg_warning{background: #FF8200;} .YiJia_message .YiJia_bg_error{background: #ED7979;} .YiJia_message .YiJia_bg_default{background: #0D53FB;} .YiJia_message .YiJia_message_icon{width: 20px; height: 20px; overflow: hidden;display: block; background-size:100% ;} .YiJia_message .YiJia_message_success{background: url(https://repo.bfw.wiki/bfwrepo/images/notice/success.png) no-repeat;} .YiJia_message .YiJia_message_warning{background: url(https://repo.bfw.wiki/bfwrepo/images/notice/state_remind.png) no-repeat;} .YiJia_message .YiJia_message_error{background: url(https://repo.bfw.wiki/bfwrepo/images/notice/state_error.png) no-repeat;} .YiJia_message .YiJia_message_default{background: url(https://repo.bfw.wiki/bfwrepo/images/notice/state_remind.png) no-repeat;} .YiJia_message .YiJia_content{flex: 1; padding-left: 11px;}; .YiJia_message.messageFadeInDown { -webkit-animation-duration: .6s; animation-duration: .6s; -webkit-animation-fill-mode: both; animation-fill-mode: both ;-webkit-animation-name:messageFadeInDown; animation-name: messageFadeInDown; } .YiJia_message.messageFadeOutUp { -webkit-animation-duration: .6s; animation-duration: .6s; -webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-name: messageFadeOutUp; animation-name: messageFadeOutUp } @keyframes messageFadeOutUp { 0% { opacity: 1; } 100% { opacity: 0; -webkit-transform: translateY(-100%); transform: translateY(-100%); } } @keyframes messageFadeInDown { 0% { -webkit-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); } 100% { -webkit-transform: none; transform: none; } } </style> <script type="text/javascript" src="https://repo.bfw.wiki/bfwrepo/js/jquery.1.4.2.js"></script> <script> $.extend({ message:function(options) { let _this = this; var settings = { type:'default', content:'提示内容', time:'2000', autoClose:true, onClose:function(){}, define:function(){}, }; if(typeof options === "string") { settings.content = options; } if(typeof options === "object") { settings = $.extend({},settings, options) } let top = 30; if($('.header_tps').length>0) { top = 90; } var msghtml = `<div class="YiJia_message messageFadeInDown" style="top:${top}px"> <div class="YiJia_message_main YiJia_bg_${settings.type}"> <i class="YiJia_message_icon YiJia_message_${settings.type}"></i> <div class="YiJia_content">${settings.content}</div> </div> </div>`; var body = $("body"); var msg = $(msghtml); var clearTime; var msgA,msgB; msgA = function(){ msg.addClass("messageFadeOutUp"); msg.one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend", function() { msgB() }) }; msgB = function() { msg.remove(); settings.onClose(settings); clearTimeout(clearTime) }; $(".YiJia_message").remove(); body.append(msg); msg.css({ "margin-left": "-" + msg.width() / 2 + "px", }); msg.one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){ msg.removeClass("messageFadeInDown"); }) if(settings.autoClose){ clearTime = setTimeout(function(){ msgA(); settings.define(); },settings.time); } //function isExitsFunction() }, confirm:function(content,title,options){ var title = title ? title : '提示'; var confirmBody = $('<div class="confirm_box_wrapper"><div class="confirm_model"></div></div>'); var confirmBox = $('<div class="confirm_box"></div>'); var confirmHeader = $('<div class="confirm_header"></div>') var confirmTitle = $(`<div class="confirm_title"><span>${title}</span></div>`); var confirmClose = $('<div class="confirm_close"><i class="icon"></i></div>'); var confirmContent = $('<div class="confirm_content"></div>'); var confirmIcon = $(`<div class="confirm_icon confirm_icon_${options.type}"></div>`); var confirmMessage = $(`<div class="confirm_message">${content}</div>`); var confirmBtns = $('<div class="confirm_btns"></div>') var confirmOffButton = $(`<button type="button" class="btns_default"><span>${options.cancelButtonText}</span></button>`); var confirmYesButton = $(`<button type="button" class="btns_primary"><span>${options.confirmButtonText}</span></button>`); confirmHeader.append(confirmTitle,confirmClose); if(options.type!=undefined) { confirmContent.append(confirmIcon); } confirmContent.append(confirmMessage); if(options.cancelButtonText!=undefined){ confirmBtns.append(confirmOffButton); } confirmBtns.append(confirmYesButton); confirmBox.append(confirmHeader,confirmContent,confirmBtns); confirmBody.append(confirmBox); var body = $('body'); body.append(confirmBody); confirmClose.on('click',function(){ confirmBody.remove(); }); confirmOffButton.on('click',function(){ confirmBody.remove(); setTimeout(function() { options.cancel() }) }) confirmYesButton.on('click',function(){ confirmBody.remove(); setTimeout(function() { options.define() }) }) } }) </script> </head> <body data-theme="green"> <div class="app"> <div class="wrapper"> <div class="chat-area"> <div class="chat-area-main"> <div class="chat-msg"> <div class="chat-msg-profile"> <img class="chat-msg-img" src="https://repo.bfw.wiki/bfwrepo/icon/6408478cce30d.png" alt=""> <div class="chat-msg-date"> ai助手 </div> </div> <div class="chat-msg-content"> <br> <div class="chat-msg-text"> 各种问题我都能回答 </div> </div> </div> </div> <div class="chat-area-main" id="chat-body"> <div class="chat-msg"> <div class="chat-msg-profile"> <img class="chat-msg-img" src="https://repo.bfw.wiki/bfwrepo/icon/6408478cce30d.png" alt=""> <div class="chat-msg-date"> ai助手 </div> </div> <div class="chat-msg-content"> <br> <div class="chat-msg-text"> ai助手 </div> </div> </div> </div> <span id="chatgpt-reflection"></span> <div class="chat-area-footer"> <input type="text" id="message" class="chat_message_up" placeholder="输入问题来问我?"> <button class="detail-button" id="send-button"> <span class="d-none d-md-inline-block me-2"> send </span> <i class="zmdi zmdi-mail-send"> </i> </button> </div> </div> </div> </div> <!-- Suara prompt pemulihan GPT --> <!-- GPT回复消息提示音 --> <audio src="https://repo.bfw.wiki/bfwrepo/sound/60931788cbeaa.mp3" id="gpt_ok"></audio> <!-- 发送消息提示音 --> <audio src="https://repo.bfw.wiki/bfwrepo/sound/6093174800db3.mp3" id="you_success"></audio> <!-- JS Start --> <script> function success() { var audioEle = document.getElementById("you_success"); // Suara pemberitahuan pengiriman audioEle.play(); $.message({ type: 'success', content: "发送成功,等待ai回复~" }); } function gpt_ok() { var audioEle = document.getElementById("gpt_ok"); // Suara prompt pemulihan GPT audioEle.play(); $.message({ type: 'success', content: "ai回复了" }); } document.onkeydown = function(e) { if (!e) e = window.event; //rubah api window.event if ((e.keyCode || e.which) == 13) { document.getElementById("send-button").click(); } } $(document).ready(function() { // Bagian bawah area perpustakaan keliling $('.chat-area').animate({ scrollTop: $('.chat-area')[0].scrollHeight },10); var chatBody = $('#chat-body'); var messageInput = $('#message'); var sendButton = $('#send-button'); // Pengiriman Informasi sendButton.click(function() { var message = messageInput.val(); if (message.trim() !== '') { // Informasi tentang impor bahan tambahan di area perpustakaan appendMessage('You', message); appendloading('ChatGPT'); $('.chat-area').animate({ scrollTop: $('.chat-area')[0].scrollHeight }, 1000); // Kontak ChatGPT untuk penyesuaian $.ajax({ // Selamat datang di API lunak musim panas // Fitur fungsi: Jumlah panggilan telepon yang sangat besar, detik koneksi, respons respons // Ingat kembali "masalah" dan "jawaban" mesin saat ini:https://v1.apigpt.cn/nchatgpt/ url: '后端api接口', type: 'POST', data: { words: message, }, dataType:"json", success: function(response) { // Menambahkan berita pemulihan ChatGPT di area tersebut // response="这个问题应该是这样的"; if(response.err){ $.message({ type: 'fail', content:esponse.data }); return; } deleteMessage('ChatGPT') appendMessage('ChatGPT', response.data); $('.chat-area').animate({ scrollTop: $('.chat-area')[0].scrollHeight }, 1000); } }); // Kotak impor messageInput.val(''); } }); // Salah satu artikel berita di area perpustakaan function appendloading(from) { var messageElement = $('<div class="chat-msg" id="loads"></div>'); var messagePend = $('<div class="chat-msg-profile"></div>') // var avatarElement = $(''); var messageContentElement = $('<div class="chat-msg-text" style="margin-left: 12px;">AI思考中……</div>'); if (from === 'You') { messageElement.addClass('owner'); var avatarElement = $('<img class="chat-msg-img" src="https://repo.bfw.wiki/bfwrepo/icon/5dfc86e11b524.png" alt=""><div class="chat-msg-date">我</div>'); // var avatarElement = $('<div class="chat-msg-date">2023-02-12 00:00:01</div>'); } else { // robot var avatarElement = $('<img class="chat-msg-img" src="https://repo.bfw.wiki/bfwrepo/icon/6408478cce30d.png" alt="">'); var tipsElement = $('<div class="chat-msg-date">ai助手</div>'); var chatgpt_reflection = document.getElementById("chatgpt-reflection").innerText = ''; } messagePend.append(avatarElement); messagePend.append(tipsElement); messageElement.append(messagePend); messageElement.append(messageContentElement); chatBody.append(messageElement); // Bagian bawah area perpustakaan keliling chatBody.scrollTop(chatBody[0].scrollHeight); } function deleteMessage(from) { $("#loads").remove(); } // Salah satu artikel berita di area perpustakaan function appendMessage(from, message) { var messageElement = $('<div class="chat-msg" id="chatai"></div>'); var messagePend = $('<div class="chat-msg-profile"></div>') // var avatarElement = $(''); var messageContentElement = $('<div class="chat-msg-text" style="margin-left: 12px;"></div>'); if (from === 'You') { success(); messageElement.addClass('owner'); var avatarElement = $('<img class="chat-msg-img" src="https://repo.bfw.wiki/bfwrepo/icon/5dfc86e11b524.png" alt=""><div class="chat-msg-date">我</div>'); } else { // robot gpt_ok(); // suara berita var avatarElement = $('<img class="chat-msg-img" src="https://repo.bfw.wiki/bfwrepo/icon/6408478cce30d.png" alt="">'); var tipsElement = $('<div class="chat-msg-date">ai助手</div>'); } // avatarElement.text(from[0]); messageContentElement.html(message); messagePend.append(avatarElement); messagePend.append(tipsElement); messageElement.append(messagePend); messageElement.append(messageContentElement); chatBody.append(messageElement); localStorage.setItem('message',JSON.stringify(chatBody.html())) // Bagian bawah area perpustakaan keliling chatBody.scrollTop(chatBody[0].scrollHeight); } chatBody.html(JSON.parse(localStorage.getItem('message'))) }); </script> <!-- JS End --> <style> /* Chrome, Safari dan Opera */ *::-webkit-scrollbar { display: none; } /* Dukungan untuk IE, Edge dan Firefox */ * { -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } </style> </body> </html>7. 编写渲染进程代码:在`index.html`文件中编写应用程序的渲染进程代码,例如显示页面、处理用户交互等,最终的目录是这样的
8、在package.json中增加build选项
"build": { "appId": "com.example.myApp", "productName": "chatai", "directories": { "output": "out" }, "win": { "target": "nsis" } },
9 打包应用程序:在命令行中输入`electron-forge package或electron-forge make`,将应用程序打包成可执行文件。10. 在开发过程中,可以使用`electron-forge start或npm start`命令启动应用程序,这样可以实时预览应用程序的效果。
最终在out目录下生成下面两个文件夹
make就是程序安装包,发送给别人就行了。
网友评论0