Merge branch 'main' into wyfMain-dev
This commit is contained in:
commit
903ae24458
@ -1,6 +0,0 @@
|
||||
ENV = 'production'
|
||||
|
||||
VITE_BASE=./
|
||||
VITE_ROUTER_MODE=hash
|
||||
VITE_BASE_API=https://xxx.xxx.com
|
||||
VITE_SOCKET_API=wss://xxx.xxx.com
|
@ -1,23 +0,0 @@
|
||||
/* eslint-env node */
|
||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||
|
||||
module.exports = {
|
||||
env: {
|
||||
node: true // 只需将该项设置为 true 即可
|
||||
},
|
||||
root: true,
|
||||
'extends': [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-typescript',
|
||||
'@vue/eslint-config-prettier/skip-formatting'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest'
|
||||
},
|
||||
rules: {
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
"no-unused-vars":"off"
|
||||
}
|
||||
}
|
143
README.md
143
README.md
@ -1,87 +1,104 @@
|
||||
# Lumen IM 即时聊天
|
||||
# LumenIM - 在线即时通讯应用
|
||||
|
||||
<img alt="GitHub stars badge" src="https://img.shields.io/github/stars/gzydong/LumenIM"> <img alt="GitHub forks badge" src="https://img.shields.io/github/forks/gzydong/LumenIM"> <img alt="GitHub license badge" src="https://img.shields.io/github/license/gzydong/LumenIM">
|
||||
LumenIM 是一个基于 Vue 3 开发的现代化在线即时通讯应用,提供实时聊天、消息管理、笔记等功能。
|
||||
|
||||
### 项目介绍
|
||||
## 功能特性
|
||||
|
||||
Lumen IM 是一个网页版在线聊天项目,前端使用 Naive UI + Vue3,后端采用 GO 开发。
|
||||
- 📱 实时聊天:支持一对一即时通讯
|
||||
- 📝 消息管理:高效管理各类消息
|
||||
- 📓 笔记功能:支持Markdown格式的笔记编辑与管理
|
||||
- 🌓 暗色模式:支持明暗主题切换,呵护您的眼睛
|
||||
- 🔒 用户认证:完善的登录注册系统
|
||||
|
||||
### 功能模块
|
||||
## 技术栈
|
||||
|
||||
- 支持私聊及群聊
|
||||
- 支持多种聊天消息类型 例如:文本消息、代码块、群投票、图片及其它类型文件,并支持文件下载
|
||||
- 支持聊天消息撤回、删除(批量删除)、转发消息(逐条转发、合并转发)
|
||||
- 支持编写笔记
|
||||
- **前端框架**:Vue 3 + TypeScript
|
||||
- **状态管理**:Pinia
|
||||
- **UI组件库**:Naive UI
|
||||
- **路由管理**:Vue Router
|
||||
- **CSS预处理器**:Less
|
||||
- **构建工具**:Vite
|
||||
- **WebSocket**:用于实时通讯
|
||||
- **编辑器**:
|
||||
- Markdown编辑器:@kangc/v-md-editor
|
||||
- 富文本编辑器:Quill
|
||||
|
||||
### 项目预览
|
||||
## 快速开始
|
||||
|
||||
- 地址: [http://im.gzydong.com](http://im.gzydong.com)
|
||||
### 环境要求
|
||||
|
||||
### 项目安装
|
||||
- Node.js >= 14.0.0
|
||||
- pnpm >= 6.0.0
|
||||
|
||||
###### 下载安装
|
||||
### 安装依赖
|
||||
|
||||
```bash
|
||||
## 克隆项目源码包
|
||||
git clone https://gitee.com/gzydong/LumenIM.git
|
||||
或
|
||||
git clone https://github.com/gzydong/LumenIM.git
|
||||
|
||||
## 安装项目依赖扩展组件
|
||||
yarn install
|
||||
|
||||
# 启动本地开发环境
|
||||
yarn dev
|
||||
# 启动本地开发环境桌面客户端
|
||||
yarn electron:dev
|
||||
|
||||
## 生产环境构建项目
|
||||
yarn build
|
||||
|
||||
## 生产环境桌面客户端打包
|
||||
yarn electron:build
|
||||
pnpm install
|
||||
```
|
||||
|
||||
###### 修改 .env 配置信息
|
||||
### 开发环境运行
|
||||
|
||||
```env
|
||||
VITE_BASE_API=http://127.0.0.1:8503
|
||||
VITE_SOCKET_API=ws://127.0.0.1:8504
|
||||
```bash
|
||||
# 测试环境
|
||||
pnpm dev:test
|
||||
|
||||
# 生产环境
|
||||
pnpm dev:prod
|
||||
```
|
||||
|
||||
###### 关于 Nginx 的一些配置
|
||||
### 打包构建
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name www.yourdomain.com;
|
||||
```bash
|
||||
# 测试环境构建
|
||||
pnpm build:test
|
||||
|
||||
root /project-path/dist;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|ico)$ {
|
||||
expires 7d;
|
||||
}
|
||||
|
||||
location ~ .*\.(js|css)?$ {
|
||||
expires 7d;
|
||||
}
|
||||
}
|
||||
# 生产环境构建
|
||||
pnpm build:prod
|
||||
```
|
||||
|
||||
### 项目源码
|
||||
### 预览构建后的项目
|
||||
|
||||
| 代码仓库 | 前端源码 | 后端源码 |
|
||||
| -------- | ---------------------------------- | ---------------------------------- |
|
||||
| Github | https://github.com/gzydong/LumenIM | https://github.com/gzydong/go-chat |
|
||||
| 码云 | https://gitee.com/gzydong/LumenIM | https://gitee.com/gzydong/go-chat |
|
||||
```bash
|
||||
pnpm preview
|
||||
```
|
||||
|
||||
#### 联系方式
|
||||
## 项目结构
|
||||
|
||||
QQ作者 : 837215079
|
||||
```
|
||||
src/
|
||||
├── api/ # API请求
|
||||
├── assets/ # 静态资源
|
||||
├── components/ # 公共组件
|
||||
├── connect.ts # WebSocket连接管理
|
||||
├── constant/ # 常量定义
|
||||
├── directive/ # 自定义指令
|
||||
├── event/ # 事件管理
|
||||
├── hooks/ # 自定义钩子
|
||||
├── layout/ # 布局组件
|
||||
├── main.ts # 入口文件
|
||||
├── plugins/ # 插件配置
|
||||
├── router/ # 路由配置
|
||||
├── store/ # 状态管理
|
||||
├── types/ # 类型定义
|
||||
├── utils/ # 工具函数
|
||||
└── views/ # 页面视图
|
||||
```
|
||||
|
||||
### 如果你觉得还不错,请 Star , Fork 给作者鼓励一下。
|
||||
## 环境变量配置
|
||||
|
||||
项目支持不同环境配置,环境变量文件位于`env/`目录下。
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
支持现代浏览器,如Chrome、Firefox、Safari、Edge等。
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [Vue 3](https://v3.vuejs.org/)
|
||||
- [Vite](https://vitejs.dev/)
|
||||
- [Naive UI](https://www.naiveui.com/)
|
||||
- [Pinia](https://pinia.vuejs.org/)
|
||||
|
||||
## 许可证
|
||||
|
||||
Copyright © 2023 LumenIM
|
||||
|
@ -1,92 +0,0 @@
|
||||
// 控制应用生命周期和创建原生浏览器窗口的模组
|
||||
const { app, BrowserWindow, ipcMain, Menu, MenuItem } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
const { shell } = require('electron')
|
||||
|
||||
const NODE_ENV = process.env.NODE_ENV
|
||||
|
||||
function loadHtmlUrl() {
|
||||
return NODE_ENV === 'development'
|
||||
? `http://localhost:${process.env.PROT}`
|
||||
: `file://${path.join(__dirname, '../dist/index.html')}`
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
// 创建浏览器窗口
|
||||
const win = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
minWidth: 900,
|
||||
minHeight: 600,
|
||||
frame: false,
|
||||
titleBarStyle: 'hidden',
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
contextIsolation: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 加载 index.html
|
||||
win.loadURL(loadHtmlUrl())
|
||||
|
||||
// 打开开发工具
|
||||
if (NODE_ENV === 'development') {
|
||||
win.webContents.openDevTools()
|
||||
}
|
||||
|
||||
// 进入全屏模式
|
||||
win.on('enter-full-screen', function () {
|
||||
win.webContents.send('full-screen', 'enter')
|
||||
})
|
||||
|
||||
// 退出全屏模式
|
||||
win.on('leave-full-screen', function () {
|
||||
win.webContents.send('full-screen', 'leave')
|
||||
})
|
||||
|
||||
ipcMain.on('get-full-screen', (e, data) => {
|
||||
e.returnValue = win.isFullScreen()
|
||||
})
|
||||
|
||||
ipcMain.on('app-info', (e, data) => {
|
||||
e.returnValue = {
|
||||
platform: process.platform,
|
||||
version: app.getVersion(),
|
||||
appPath: app.getAppPath(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 这段程序将会在 Electron 结束初始化
|
||||
// 和创建浏览器窗口的时候调用
|
||||
// 部分 API 在 ready 事件触发后才能使用。
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
app.on('activate', function () {
|
||||
// 通常在 macOS 上,当点击 dock 中的应用程序图标时,如果没有其他
|
||||
// 打开的窗口,那么程序会重新创建一个窗口。
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
|
||||
// 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 因此,通常对程序和它们在
|
||||
// 任务栏上的图标来说,应当保持活跃状态,直到用户使用 Cmd + Q 退出。
|
||||
app.on('window-all-closed', function () {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
||||
|
||||
// 在这个文件中,你可以包含应用程序剩余的所有部分的代码,
|
||||
// 也可以拆分成几个文件,然后用 require 导入。
|
||||
|
||||
ipcMain.on('ipc:set-badge', async (event, num) => {
|
||||
if (process.platform === 'darwin') {
|
||||
app.dock.setBadge(num > 99 ? '99+' : num)
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('ipc:open-link', async (event, link) => {
|
||||
// Open a link in the default browser
|
||||
shell.openExternal(link)
|
||||
})
|
@ -1,46 +0,0 @@
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
// 暴露方法给渲染进程调用
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
// 设置消息未读数
|
||||
setBadge: num => {
|
||||
ipcRenderer.send('ipc:set-badge', num == 0 ? '' : `${num}`)
|
||||
},
|
||||
// 获取窗口全屏状态
|
||||
getFullScreenStatus: () => {
|
||||
return ipcRenderer.sendSync('get-full-screen', '')
|
||||
},
|
||||
// 系统信息
|
||||
getAppPlatform: () => {
|
||||
return ipcRenderer.sendSync('app-info', '')
|
||||
},
|
||||
|
||||
openLink: link => {
|
||||
ipcRenderer.send('ipc:open-link', link)
|
||||
},
|
||||
})
|
||||
|
||||
// 窗口变化事件
|
||||
ipcRenderer.on('full-screen', function (event, value) {
|
||||
// isFullScreenStatus = value == 'enter'
|
||||
|
||||
document.dispatchEvent(
|
||||
new CustomEvent('full-screen-event', { detail: value })
|
||||
)
|
||||
})
|
||||
|
||||
// 触发自定义事件
|
||||
// document.dispatchEvent(new CustomEvent('myTestEvent', {num: i}))
|
||||
// document.addEventListener('myTestEvent', e => {console.log(e)})
|
||||
// 所有Node.js API都可以在预加载过程中使用。
|
||||
// 它拥有与Chrome扩展一样的沙盒。
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const replaceText = (selector, text) => {
|
||||
const element = document.getElementById(selector)
|
||||
if (element) element.innerText = text
|
||||
}
|
||||
|
||||
for (const dependency of ['chrome', 'node', 'electron']) {
|
||||
replaceText(`${dependency}-version`, process.versions[dependency])
|
||||
}
|
||||
})
|
0
.env.production → env/.env.prod
vendored
0
.env.production → env/.env.prod
vendored
0
.env → env/.env.test
vendored
0
.env → env/.env.test
vendored
@ -477,17 +477,12 @@ packages:
|
||||
resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
'@nodelib/fs.scandir@2.1.5':
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
'@nodelib/fs.stat@1.1.3':
|
||||
resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
'@nodelib/fs.stat@2.0.5':
|
||||
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
|
||||
engines: {node: '>= 8'}
|
||||
'@polka/url@1.0.0-next.29':
|
||||
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||
|
||||
'@nodelib/fs.walk@1.2.8':
|
||||
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
||||
@ -2112,10 +2107,6 @@ packages:
|
||||
resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
micromatch@4.0.8:
|
||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@ -2434,9 +2425,6 @@ packages:
|
||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
run-parallel@1.2.0:
|
||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||
|
||||
rw@1.3.3:
|
||||
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
|
||||
|
||||
@ -3290,16 +3278,11 @@ snapshots:
|
||||
call-me-maybe: 1.0.2
|
||||
glob-to-regexp: 0.3.0
|
||||
|
||||
'@nodelib/fs.scandir@2.1.5':
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
run-parallel: 1.2.0
|
||||
|
||||
'@nodelib/fs.stat@1.1.3': {}
|
||||
|
||||
'@nodelib/fs.stat@2.0.5': {}
|
||||
'@polka/url@1.0.0-next.29': {}
|
||||
|
||||
'@nodelib/fs.walk@1.2.8':
|
||||
'@quansync/fs@0.1.2':
|
||||
dependencies:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.19.1
|
||||
@ -5251,11 +5234,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
micromatch@4.0.8:
|
||||
dependencies:
|
||||
braces: 3.0.3
|
||||
picomatch: 2.3.1
|
||||
|
||||
mime-db@1.52.0: {}
|
||||
|
||||
mime-types@2.1.35:
|
||||
@ -5567,10 +5545,6 @@ snapshots:
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
run-parallel@1.2.0:
|
||||
dependencies:
|
||||
queue-microtask: 1.2.3
|
||||
|
||||
rw@1.3.3: {}
|
||||
|
||||
rxjs@7.8.2:
|
||||
|
@ -31,8 +31,7 @@ const settingsStore = useSettingsStore()
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
|
||||
background: url(@/assets/image/background.jpeg);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
@ -40,7 +39,7 @@ const settingsStore = useSettingsStore()
|
||||
background-size: cover;
|
||||
|
||||
.im-container {
|
||||
height: 100vh;
|
||||
height: 80vh;
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
|
@ -18,7 +18,7 @@ export function isLoggedIn() {
|
||||
*/
|
||||
export function getAccessToken() {
|
||||
// return storage.get(AccessToken) || ''
|
||||
return '79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941caaef1334d640773710f8cd96473bacfb190cba595a5d6a9c87d70f0999a3ebb41147213b31b4bdccffca66a56acf3baab5af0154f0dce360079f37709f78e13711036899344bddb0fb4cf0f2890287cb62c3fcbe33368caa5e213624577be8b8420ab75b1f50775ee16142a4321c5d56995f37354a66a969da98d95ba6e65d142ed097e04b411c1ebad2f62866d0ec7e1838420530a9941dbbcd00490199f8b892000b1d18303354ea8a7c57f91ffb617f5d82513d2af46e6ce5848a80c59c75b9ddf4a552092d70ecda72c97d99cb5d0f114a50ddfd9674f22576675e3390d2367951eb502aa1dd94e8823d528a503fb'
|
||||
return JSON.parse(localStorage.getItem('token'))||'79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941caaef1334d640773710f8cd96473bacfb190cba595a5d6a9c87d70f0999a3ebb41147213b31b4bdccffca66a56acf3baab5af0154f0dce360079f37709f78e13711036899344bddb0fb4cf0f2890287cb62c3fcbe33368caa5e213624577be8b8420ab75b1f50775ee16142a4321c5d56995f37354a66a969da98d95ba6e65d142ed097e04b411c1ebad2f62866d0ec7e1838420530a9941dbbcd00490199f8b892000b1d18303354ea8a7c57f91ffb617f5d82513d2af46e6ce5848a80c59c75b9ddf4a552092d70ecda72c97d99cb5d0f114a50ddfd9674f22576675e3390d2367951eb502aa1dd94e8823d528a503fb'
|
||||
}
|
||||
|
||||
/**
|
||||
|
16
uno.config.ts
Normal file
16
uno.config.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { defineConfig } from 'unocss'
|
||||
import { presetAttributify, presetIcons } from 'unocss'
|
||||
export default defineConfig({
|
||||
// 预设
|
||||
presets: [
|
||||
presetAttributify(), // 启用属性模式
|
||||
presetIcons(), // 启用图标
|
||||
],
|
||||
// 自定义规则
|
||||
rules: [
|
||||
],
|
||||
// 快捷方式
|
||||
shortcuts: {
|
||||
'btn': 'px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600',
|
||||
},
|
||||
})
|
@ -3,7 +3,7 @@ import { fileURLToPath, URL } from 'node:url'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import compressPlugin from 'vite-plugin-compression'
|
||||
|
||||
import UnoCSS from 'unocss/vite'
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ mode }) => {
|
||||
// 根据当前工作目录中的 `mode` 加载 .env 文件
|
||||
@ -12,6 +12,7 @@ export default defineConfig(({ mode }) => {
|
||||
|
||||
return {
|
||||
base: env.VITE_BASE,
|
||||
envDir: './env',
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
@ -20,7 +21,7 @@ export default defineConfig(({ mode }) => {
|
||||
},
|
||||
root: process.cwd(),
|
||||
assetsInclude: ['./src/assets'],
|
||||
plugins: [vue(), vueJsx({}), compressPlugin()],
|
||||
plugins: [vue(), vueJsx({}), compressPlugin(),UnoCSS()],
|
||||
define: {
|
||||
__APP_ENV__: env.APP_ENV
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user