electron-vite-chatgpt 客户端仿制chatgpt会话模板应用

Electron-Chatgpt 一款基于vite4.x构建 搭配electron25跨端技术实现的桌面端模仿chatgpt会话模式的聊天程序。

技术栈

  • 编码工具:vscode
  • 框架技术:electron25+vite4+vue3+pinia2
  • 组件库:veplus (基于vue3自定义组件库)
  • 打包工具:electron-builder^23.6.0
  • 调试工具:electron-devtools-installer^3.2.0
  • 代码高亮:highlight.js^11.7.0
  • markdown组件:vue3-markdown-it
  • 本地缓存:pinia-plugin-persistedstate^3.1.0

项目目录结构

布局模板结构

electron-vite-chatgpt 客户端仿制chatgpt会话模板应用

<template>
    <div class="vegpt__layout flexbox flex-col">
        <!-- //导航栏 -->
        <Toolbar />

        <div class="ve__layout-body flex1 flexbox">
            <!-- //侧边栏 -->
            <div class="ve__layout-menus flexbox" :class="{'hidden': store.config.collapse}">
                <aside class="ve__layout-aside flexbox flex-col">
                    <ChatNew />
                    <Scrollbar class="flex1" autohide size="4" gap="1">
                        <ChatList />
                    </Scrollbar>
                    <ExtraLink />
                    <Collapse />
                </aside>
            </div>

            <!-- //主体区域 -->
            <div class="ve__layout-main flex1 flexbox flex-col">
                <Main />
            </div>
        </div>
    </div>
</template>

electron主入口配置

新建一个electron-main.js作为主进程创建初始化窗体入口文件。

electron-vite-chatgpt 客户端仿制chatgpt会话模板应用

/**
 * 主进程入口
 * @author YXY
 */

const { app, BrowserWindow } = require('electron')

const MultiWindow = require('./src/multiwindow')

// 屏蔽安全警告
// ectron Security Warning (Insecure Content-Security-Policy)
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'

const createWindow = () => {
    let win = new MultiWindow()
    win.createWin({isMainWin: true})
}

app.whenReady().then(() => {
    createWindow()
    app.on('activate', () => {
        if(BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})

app.on('window-all-closed', () => {
    if(process.platform !== 'darwin') app.quit()
})

使用vite-plugin-electron桥接插件,在vite.config.js中配置入口。

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import electron from 'vite-plugin-electron'
import { resolve } from 'path'
import { parseEnv } from './src/utils/env'

export default defineConfig(({ command, mode }) => {
  const viteEnv = loadEnv(mode, process.cwd())
  const env = parseEnv(viteEnv)

  return {
    plugins: [
      vue(),
      electron({
        // 主进程入口文件
        entry: 'electron-main.js'
      })
    ],

    /*构建选项*/
    build: {
      /* minify: 'esbuild', // 打包方式 esbuild(打包快)|terser
      chunkSizeWarningLimit: 2000, // 打包大小警告
      rollupOptions: {
          output: {
              chunkFileNames: 'assets/js/[name]-[hash].js',
              entryFileNames: 'assets/js/[name]-[hash].js',
              assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
          }
      } */

      // 如果打包方式是terser,则配置如下
      /* minify: "terser",
      terserOptions: {
        compress: {
          // 去掉所有console和debugger
          // drop_console: true,
          // drop_debugger: true,

          drop_console: command !== 'serve',
          drop_debugger: command !== 'serve',
          //pure_funcs:['console.log'] // 移除console.log
        }
      } */
    },
    esbuild: {
      // 打包去除 console.log 和 debugger
      drop: env.VITE_DROP_CONSOLE && command === 'build' ? ["console", "debugger"] : []
    },

    /*开发服务器选项*/
    server: {
      // 端口
      port: env.VITE_PORT,
      // ...
    },

    resolve: {
      // 设置别名
      alias: {
        '@': resolve(__dirname, 'src'),
        '@assets': resolve(__dirname, 'src/assets'),
        '@components': resolve(__dirname, 'src/components'),
        '@views': resolve(__dirname, 'src/views')
      }
    }
  }
})

electron创建无边框窗体

创建窗口的时候,设置frame: false 后创建的窗口没有顶部导航,需要自定义组件实现导航条功能。

electron-vite-chatgpt 客户端仿制chatgpt会话模板应用

<template>
    <div class="vegpt__control ve__nodrag">
        <div class="vegpt__control-btns" :style="{'color': color}">
            <slot />
            <div v-if="isTrue(minimizable)" class="btn win-btn win-min" @click="handleMin"><i class="iconfont ve-icon-minimize"></i></div>
            <div v-if="isTrue(maximizable) && winCfg.window.resizable" class="btn win-btn win-maxmin" @click="handleRestore">
                <i class="iconfont" :class="isMaximized ? 've-icon-maxrestore' : 've-icon-maximize'"></i>
            </div>
            <div v-if="isTrue(closable)" class="btn win-btn win-close" @click="handleQuit"><i class="iconfont ve-icon-close"></i></div>
        </div>
    </div>
</template>


<script setup>
    import { onMounted, ref } from 'vue'
    import { winCfg, setWin } from '@/multiwindow/actions'
    import { appStore } from '@/pinia/modules/app'
    import { isTrue } from '@/utils'

    const appState = appStore()

    const props = defineProps({
        // 标题颜色
        color: String,

        // 窗口是否可以最小化
        minimizable: { type: [Boolean, String], default: true },
        // 窗口是否可以最大化
        maximizable: { type: [Boolean, String], default: true },
        // 窗口是否可以关闭
        closable: { type: [Boolean, String], default: true }
    })

    // 是否最大化
    let isMaximized = ref(false)

    onMounted(() => {
        window.electronAPI.invoke('win__isMaximized').then(data => {
            console.log(data)
            isMaximized.value = data
        })
        window.electronAPI.receive('win__hasMaximized', (e, data) => {
            console.log(data)
            isMaximized.value = data
        })
    })

    // 最小化
    const handleMin = () => {
        window.electronAPI.send('win__minimize')
    }
    // 最大化/还原
    const handleRestore = () => {
        window.electronAPI.invoke('win__max2min').then(data => {
            console.log(data)
            isMaximized.value = data
        })
    }
    // 关闭窗体
    const handleQuit = () => {
        if(winCfg.window.isMainWin) {
            MessageBox.confirm('应用提示', '是否最小化到托盘, 不退出程序?', {
                type: 'warning',
                cancelText: '最小化至托盘',
                confirmText: '残忍退出',
                confirmType: 'danger',
                width: 300,
                callback: action => {
                    if(action == 'confirm') {
                        appState.$reset()
                        setWin('close')
                    }else if(action == 'cancel') {
                        setWin('hide', winCfg.window.id)
                    }
                }
            })
        }else {
            setWin('close', winCfg.window.id)
        }
    }
</script>

electron-vite-chatgpt 客户端仿制chatgpt会话模板应用

electron创建托盘

electron-vite-chatgpt 客户端仿制chatgpt会话模板应用

// 创建系统托盘图标
createTray() {
    console.log('——+——+——Start Create Tray!')
    console.log(__dirname)
    console.log(join(process.env.ROOT, 'resource/tray.ico'))

    const trayMenu = Menu.buildFromTemplate([
        {
            label: '打开主界面',
            icon: join(process.env.ROOT, 'resource/home.png'),
            click: () => {
                try {
                    for(let i in this.group) {
                        let win = this.getWin(i)
                        if(!win) return
                        // 是否主窗口
                        if(this.group[i].isMainWin) {
                            if(win.isMinimized()) win.restore()
                            win.show()
                        }
                    }
                } catch (error) {
                    console.log(error)
                }
            }
        },
        {
            label: '设置中心',
            icon: join(process.env.ROOT, 'resource/setting.png'),
            click: () => {
                for(let i in this.group) {
                    let win = this.getWin(i)
                    if(win) win.webContents.send('win__ipcData', { type: 'CREATE_WIN_SETTING', value: null })
                }
            },
        },
        {
            label: '锁屏',
            icon: join(process.env.ROOT, 'resource/lock.png'),
            click: () => null,
        },
        {
            label: '关闭托盘闪烁',
            click: () => {
                this.flashTray(false)
            }
        },
        {type: 'separator'},
        /* {
            label: '重启',
            click: () => {
                // app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) })
                // app.exit(0)
            }
        }, */
        {
            label: '关于',
            click: () => {
                for(let i in this.group) {
                    let win = this.getWin(i)
                    if(win) win.webContents.send('win__ipcData', { type: 'CREATE_WIN_ABOUT', value: null })
                }
            }
        },
        {
            label: '关闭应用并退出',
            icon: join(process.env.ROOT, 'resource/quit.png'),
            click: () => {
                dialog.showMessageBox(this.main, {
                    title: '询问',
                    message: '确定要退出应用程序吗?',
                    buttons: ['取消', '最小化托盘', '退出应用'],
                    type: 'error',
                    noLink: false,  // true传统按钮样式  false链接样式
                    cancelId: 0
                }).then(res => {
                    console.log(res)

                    const index = res.response
                    if(index == 0) {
                        console.log('取消')
                    }if(index == 1) {
                        console.log('最小化托盘')
                        for(let i in this.group) {
                            let win = this.getWin(i)
                            if(win) win.hide()
                        }
                    }else if(index == 2) {
                        console.log('退出应用')

                        try {
                            for(let i in this.group) {
                                let win = this.getWin(i)
                                if(win) win.webContents.send('win__ipcData', { type: 'WIN_LOGOUT', value: null })
                            }
                            // app.quit 和 app.exit(0) 都可退出应用。
                            // 前者可以被打断并触发一些事件,而后者将强制应用程序退出而不触发任何事件或允许应用程序取消操作。
                            app.quit()
                        } catch (error) {
                            console.log(error)
                        }
                    }
                })
            }
        }
    ])
    this.tray = new Tray(this.trayIco1)
    this.tray.setContextMenu(trayMenu)
    this.tray.setToolTip(app.name)
    this.tray.on('double-click', () => {
        console.log('double clicked')
    })

    // 开启托盘闪烁
    // this.flashTray(true)
}

electron构建打包

新建一个electron-builder.json文件用作打包配置参数。

electron-vite-chatgpt 客户端仿制chatgpt会话模板应用

{
    "productName": "Electron-ChatGPT",
    "appId": "com.yxy.electron-chatgpt-vue3",
    "copyright": "Copyright © 2023-present Andy",
    "compression": "maximum",
    "asar": true,
    "directories": {
        "output": "release/${version}"
    },
    "nsis": {
        "oneClick": false,
        "allowToChangeInstallationDirectory": true,
        "perMachine": true,
        "deleteAppDataOnUninstall": true,
        "createDesktopShortcut": true,
        "createStartMenuShortcut": true,
        "shortcutName": "ElectronVite4Vue3"
    },
    "win": {
        "icon": "./resource/shortcut.ico",
        "artifactName": "${productName}-v${version}-${platform}-${arch}-setup.${ext}",
        "target": [
            {
                "target": "nsis",
                "arch": ["ia32"]
            }
        ]
    },
    "mac": {
        "icon": "./resource/shortcut.icns",
        "artifactName": "${productName}-v${version}-${platform}-${arch}-setup.${ext}"
    },
    "linux": {
        "icon": "./resource",
        "artifactName": "${productName}-v${version}-${platform}-${arch}-setup.${ext}"
    }
}

到这里electron+vue3开发跨端会话应用就介绍差不多了。

tauri+vue3跨端仿制微信聊天应用

本作品采用《CC 协议》,转载必须注明作者和本文链接
本文为原创文章,未经作者允许不得转载,欢迎大家一起交流 QQ(282310962) wx(xy190310)
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
文章
62
粉丝
50
喜欢
107
收藏
57
排名:357
访问:2.7 万
私信
所有博文
博客标签
react
1
angular
1
react仿微信
2
react实战开发
2
react+redux
1
react网页聊天
2
angular仿微信
1
angular聊天室
1
angular+node聊天
1
h5仿微信
1
仿微信语音
1
仿微信界面
1
RN弹窗
1
react-native自定义弹窗
1
react-native弹窗
1
React Native
1
reactNative仿微信
1
RN仿微信聊天
1
ReactNative朋友圈
1
uniapp仿微信
1
uniapp聊天室
2
uniapp聊天App
1
uni-app+vue实例
1
uni-app即时通讯
1
uniapp直播
1
uni-app仿抖音
1
uniapp仿陌陌
1
uni-app小视频
1
taro仿微信
1
taro聊天室
1
taro仿微信界面
1
taro+react聊天APP
1
taro即时通讯
1
electron+vue
1
electron-vue仿微信
1
electron聊天
1
electron实例
1
flutter实例
1
flutter仿微信
1
flutter+dart聊天
1
flutter聊天室
1
flutter聊天界面
1
vue自定义弹窗
1
vue全局对话框
1
vue长按弹出框
1
vue右键弹层
1
nuxt对话框
1
vue仿微信弹窗
1
vue仿探探
1
vue仿Tinder
1
vue卡片堆叠
1
vue翻牌滑动
1
nuxt仿探探
1
nuxt聊天室
1
nuxt仿微信
1
nuxt即时聊天
1
vue+nuxt聊天实例
1
nuxt.js朋友圈
1
vue.js自定义对话框
1
vue pc端弹窗
1
vue.js桌面端模态框
1
vue弹窗组件
1
vue仿layer
1
vue.js自定义滚动条
1
vue虚拟滚动条
1
vue美化滚动条
1
vue仿饿了么滚动条
1
Vue-Scrollbar
1
react.js弹窗示例
1
react桌面端弹框
1
react.js自定义对话框
1
react pc自定义弹窗
1
react全局弹框
1
vue3.0自定义组件
2
vue3弹框
1
vue3.x对话框
1
vue3.0弹窗
1
vue3.0实例
1
vue3.0聊天室
1
vue3.0仿微信
2
vue3聊天模板
1
vue3+vant3实战开发
1
vue3.x案例
1
vue3聊天实例
1
vue3.0仿QQ
1
vue3.x实战聊天
1
vue3网页聊天
2
vue3.0仿抖音app
1
vue3短视频
1
vue3.x小视频
1
vue3.0直播实例
1
vue3+vite2+vant3实战
1
vue3跨端开发
1
electron仿QQ
1
electron打包
1
electron聊天室
1
electron仿微信
1
electron仿抖音
1
electron短视频
1
electron直播
1
vite2+electron12
1
vite2+vue3.x+swiper
1
vue3+vite.js+vant3
1
vue3后台系统
1
Electron管理系统
1
vite2+electron后台
1
electron12权限管理
1
electron桌面端后台
1
vue3桌面管理
1
vite2+electron13
1
electron仿mac桌面
1
electron桌面管理
1
vite2桌面应用
1
uniapp短视频
1
uniapp仿抖音
1
uni-app直播
1
uniapp后台
1
uni-app+uview后台系统
1
svelte.js实战开发
1
svelte3仿微信
1
svelte+svelteKit聊天室
1
svelte聊天实例
2
svelte朋友圈
1
svelte.js仿微信
1
svelte.js网页聊天
1
svelte-ui-admin
1
svelte-admin后台管理
1
svelte管理系统
1
tauri桌面应用
1
tauri+vue3
1
vite3+tauri
1
tauri聊天程序
1
tauri仿微信
1
vue3后台管理
1
vite.js管理系统
1
vue3+vite4
1
vite4+pinia
1
vue3+pinia2
1
vue3-chatgpt
2
vite-chatgpt
1
chatgpt-mobile
1
electron-chatgpt
1
electron+vite4+vue3
1
electron25-vue3
1
chatgpt-vite
1
uni-chatgpt
1
uniapp+vue3+pinia
4
vite+uniapp
1
chatgpt-uniapp
1
tauri-admin
1
tauri+rust+vue3
1
tauri后台管理
1
tauri-vite
1
tauri+vue3桌面端后台
1
react18 hooks
2
react18+arco
2
react18+zustand
1
react18-webchat
1
react18-admin
1
react-arco-admin
1
react-vite-admin
1
react18后台管理
1
electron-mateos
1
electron27+react18
1
electron-react-macos
1
electron桌面os
1
react-macos
1
uniapp+vue3直播
1
flutter3-chat
2
flutter3仿微信
2
flutter3聊天
2
flutter3+dart3
1
flutter3桌面端开发
1
flutter3-douyin
1
flutter3仿抖音
1
flutter3短视频
2
flutter3直播
1
flutter3-macos
1
flutter3-osx
2
flutter3桌面os
2
flutter3仿macOS
1
uniapp+vue3聊天
1
uniapp+vue3仿微信
1
uniapp+vue3聊天app
1
uniapp-vue3-wchat
1
uni-vue3-os
1
uniapp+vue3手机后台
1
uniapp-admin
1
uniapp+vue3仿ios桌面
1
uniapp+vite5后台管理
1
flutter3-osadmin
1
flutter3手机后台
1
vite-vue3-chat
1
vite-webchat
1
vue3-chat聊天
1
vite5仿微信
1
electron31+vue3聊天室
1
vite5+electron31仿微信
1
electron31-vite5-wechat聊天
1
electron31聊天exe
1
vue3+electron桌面聊天
1
vue3-webos
1
vue3-macos
1
vue3网页版os
1
vite-os
1
electron31-vue3-admin
1
vite5-electron31-admin
1
vue3+electron31后台系统
1
electron31+vite5桌面端后台
1
electron31轻量级后台
1
electron32-os
1
vue3+electron32桌面os
1
electron32-macos
1
electron32-winos
1
electron-osx
1
tauri2.0
2
tauri2+vue3仿微信
1
tauri2+vite.js聊天
1
tauri2.0+vue3客户端聊天
1
HarmonyOS
1
tauri2-admin
1
tauri2-vue3-admin
1
vue3+tauri2桌面后台
1
tauri2+vite后台系统
1
harmony-chat
1
鸿蒙仿微信
1
鸿蒙聊天app
1
uniapp+vue3酒店预订
1
vue3+uniapp预约酒店
1
uniapp酒店预订
1
uniapp仿携程
1
uniapp仿同程
1
vue3酒店预订
1
tauri2-os
1
tauri2.0-vue3-os
1
tauri2+vue3桌面os
1
tauri2-macos
1
tauri2-winos
1
tauri2.0仿macos
1
tauri2+vite桌面端os
1
flutter3直播app
1
flutter3仿抖音app
1
flutter3短视频直播
1
flutter3聊天室
1
flutter3仿携程
1
flutter3-trip
1
flutter3酒店预订
1
flutter3预约酒店app
1
flutter3旅行酒店app
1
社区赞助商