Compare commits

..

16 Commits

Author SHA1 Message Date
ChenZhaoYu
e9db25a970 chore: version 2.3.2 2023-02-16 12:31:08 +08:00
ChenZhaoYu
63f4d7d77c chore: update deps 2023-02-16 12:29:47 +08:00
ChenZhaoYu
20255ddce4 chore: gitignore file 2023-02-16 12:00:03 +08:00
wang ha ha
bbd8ff773b 添加 docker 镜像打包部署脚本 (#27)
* 删除env

* 修改生产依赖安装缺失。

* 添加docker镜像构建

* no message

* 修改超时时间。

* 修复镜像构建错误。

* 修改环境变量获取baseapi

* 修改前端链接获取位置。

* 删除默认env

* 添加会 .env 文件,但是注释掉。

* 使用默认 api。

* 添加前端调试和部署路由兼容。

* 删除key

* Update .env

* Delete build_docker.yml

暂时不做 `git hooks` 处理

* Delete .gitignore

* Delete Dockerfile

工作路径好像有点错误,先不合并

* Delete build.sh

工作路径好像有点错误,先不合并

---------

Co-authored-by: 王金海(haha.wang) <wanghaha@huolala.cn>
Co-authored-by: haha.wang <haha.wang@huolala.cn>
Co-authored-by: Redon <790348264@qq.com>
2023-02-16 11:58:29 +08:00
Redon
c8518b7789 chore: 删除未使用代码 (#37) 2023-02-16 11:38:18 +08:00
ChenZhaoYu
bf015d35f7 chore: 添加 node>=14 说明 2023-02-16 11:15:00 +08:00
ChenZhaoYu
eab39b7f88 chore: update doc 2023-02-16 08:24:42 +08:00
ChenZhaoYu
981c036542 fix: type error 2023-02-16 08:23:31 +08:00
Redon
91f51b6338 pull (#34) (#35)
* fix: 修复部分多会话逻辑

* chore: version 2.3.1
2023-02-15 22:44:32 +08:00
ChenZhaoYu
26de5359ef chore: version 2.3.1 2023-02-15 22:34:44 +08:00
ChenZhaoYu
0423b87530 fix: 修复部分多会话逻辑 2023-02-15 22:31:55 +08:00
ChenZhaoYu
58464b2cee chore: 推送错误,应该在 dev 分支上 2023-02-15 16:55:21 +08:00
ChenZhaoYu
e23e1df3ce chore: 变量名错误 2023-02-15 16:47:32 +08:00
ChenZhaoYu
2c3bc77eb2 chore: 添加贡献值栏 2023-02-15 16:45:34 +08:00
ChenZhaoYu
52b43868eb chore: # CONTRIBUTING 2023-02-15 16:18:20 +08:00
ChenZhaoYu
7930ec5dab feat: 添加 ts 类型 2023-02-15 16:07:42 +08:00
22 changed files with 174 additions and 136 deletions

3
.env
View File

@@ -1,3 +1,4 @@
# Glob API URL
VITE_GLOB_API_URL=/api
VITE_APP_API_BASE_URL = http://localhost:3002/
VITE_APP_API_BASE_URL=http://localhost:3002/

View File

@@ -37,6 +37,7 @@
"Typecheck",
"unplugin",
"VITE",
"vueuse"
"vueuse",
"Zhao"
]
}

View File

@@ -1,3 +1,18 @@
## v2.3.2
`2023-02-16`
### Enhancement
- 更新依赖至最新
- 优化部份内容
## v2.3.1
`2023-02-15`
### BugFix
- 修复多会话状态下一些意想不到的问题
## v2.3.0
`2023-02-15`

View File

@@ -1,4 +1,22 @@
# 指南
# 贡献指南
感谢你的宝贵时间。你的贡献将使这个项目变得更好!在提交贡献之前,请务必花点时间阅读下面的入门指南。
## 语义化版本
该项目遵循语义化版本。我们对重要的漏洞修复发布修订号,对新特性或不重要的变更发布次版本号,对重大且不兼容的变更发布主版本号。
每个重大更改都将记录在 `changelog` 中。
## 提交 Pull Request
1. Fork [此仓库](https://github.com/Chanzhaoyu/chatgpt-web),从 `main` 创建分支。新功能实现请发 pull request 到 `feature` 分支。其他更改发到 `main` 分支。
2. 使用 `npm install pnpm -g` 安装 `pnpm` 工具。
3. `vscode` 安装了 `Eslint` 插件,其它编辑器如 `webStorm` 打开了 `eslint` 功能。
4. 根目录下执行 `pnpm bootstrap`
5. `/service/` 目录下执行 `pnpm install`
6. 对代码库进行更改。如果适用的话,请确保进行了相应的测试。
7. 请在根目录下执行 `pnpm lint:fix` 进行代码格式检查。
8. 请在根目录下执行 `pnpm type-check` 进行类型检查。
9. 提交 git commit, 请同时遵守 [Commit 规范](#commit-指南)
10. 提交 `pull request` 如果有对应的 `issue`,请进行[关联](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)。
## Commit 指南
@@ -24,3 +42,8 @@ Commit messages 请遵循[conventional-changelog 标准](https://www.conventiona
- perf: 性能优化
- test: 单元测试
- chore: 其他不修改 src 或测试文件的提交
## License
[MIT](./license)

View File

@@ -23,7 +23,7 @@
### Node
`node` 版本需要 >= 18,使用 [nvm](https://github.com/nvm-sh/nvm) 可管理本地多个 `node` 版本
`node` 需要 `^16 || ^18` 版本(或者 `node >= 14` 需要安装 [fetch polyfill](https://github.com/developit/unfetch#usage-as-a-polyfill),使用 [nvm](https://github.com/nvm-sh/nvm) 可管理本地多个 `node` 版本
```shell
node -v
@@ -36,7 +36,7 @@ npm install pnpm -g
```
### OpenAI API Key
获取 [OpenAI API key](https://platform.openai.com/overview) 并填写到本地环境变量
注册并获取 [OpenAI API key](https://platform.openai.com/overview) 并填写到本地环境变量
```
# service/.env 文件

View File

@@ -1,6 +1,6 @@
{
"name": "chatgpt-web",
"version": "2.3.0",
"version": "2.3.2",
"private": false,
"description": "ChatGPT Web",
"author": "ChenZhaoYu <chenzhaoyu1994@gmail.com>",
@@ -37,18 +37,18 @@
"@types/node": "^18.13.0",
"@vitejs/plugin-vue": "^4.0.0",
"autoprefixer": "^10.4.13",
"axios": "^1.3.2",
"axios": "^1.3.3",
"crypto-js": "^4.1.1",
"eslint": "^8.34.0",
"husky": "^8.0.3",
"lint-staged": "^13.1.1",
"lint-staged": "^13.1.2",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.21",
"rimraf": "^4.1.2",
"tailwindcss": "^3.2.6",
"typescript": "~4.9.5",
"vite": "^4.1.1",
"vue-tsc": "^1.0.24"
"vue-tsc": "^1.1.0"
},
"lint-staged": {
"*.{ts,tsx,vue}": [

78
pnpm-lock.yaml generated
View File

@@ -9,12 +9,12 @@ specifiers:
'@types/node': ^18.13.0
'@vitejs/plugin-vue': ^4.0.0
autoprefixer: ^10.4.13
axios: ^1.3.2
axios: ^1.3.3
crypto-js: ^4.1.1
eslint: ^8.34.0
highlight.js: ^11.7.0
husky: ^8.0.3
lint-staged: ^13.1.1
lint-staged: ^13.1.2
naive-ui: ^2.34.3
npm-run-all: ^4.1.5
pinia: ^2.0.30
@@ -25,7 +25,7 @@ specifiers:
vite: ^4.1.1
vue: ^3.2.47
vue-router: ^4.1.6
vue-tsc: ^1.0.24
vue-tsc: ^1.1.0
dependencies:
highlight.js: 11.7.0
@@ -54,7 +54,7 @@ devDependencies:
tailwindcss: 3.2.6_postcss@8.4.21
typescript: 4.9.5
vite: 4.1.1_@types+node@18.13.0
vue-tsc: 1.0.24_typescript@4.9.5
vue-tsc: 1.1.0_typescript@4.9.5
packages:
@@ -896,43 +896,43 @@ packages:
vue: 3.2.47
dev: true
/@volar/language-core/1.0.24:
resolution: {integrity: sha512-vTN+alJiWwK0Pax6POqrmevbtFW2dXhjwWiW/MW4f48eDYPLdyURWcr8TixO7EN/nHsUBj2udT7igFKPtjyAKg==}
/@volar/language-core/1.2.0-alpha.11:
resolution: {integrity: sha512-OfbPmmFa4LUA8kJCg77V9ud4NASjJ3VKJ79QCQSfHa5SwXeZ5w7lvQe2yILFBjZ3JDB5EfFnHZUSct6ziK3x5Q==}
dependencies:
'@volar/source-map': 1.0.24
muggle-string: 0.1.0
'@volar/source-map': 1.2.0-alpha.11
dev: true
/@volar/source-map/1.0.24:
resolution: {integrity: sha512-Qsv/tkplx18pgBr8lKAbM1vcDqgkGKQzbChg6NW+v0CZc3G7FLmK+WrqEPzKlN7Cwdc6XVL559Nod8WKAfKr4A==}
/@volar/source-map/1.2.0-alpha.11:
resolution: {integrity: sha512-GCRqcq2bn8Gf9N/qbdl8GgfGbmYuuSIB8arhl+gRZfCIWvT5NhIRVlG5GX0lkgpp02lA8ZYWZ0GLGOkwz7+DMQ==}
dependencies:
muggle-string: 0.1.0
muggle-string: 0.2.2
dev: true
/@volar/typescript/1.0.24:
resolution: {integrity: sha512-f8hCSk+PfKR1/RQHxZ79V1NpDImHoivqoizK+mstphm25tn/YJ/JnKNjZHB+o21fuW0yKlI26NV3jkVb2Cc/7A==}
/@volar/typescript/1.2.0-alpha.11:
resolution: {integrity: sha512-tJ20326E/Xi1lvvuWX57boVJtzhStNF3HjBu4orjl9PqCXUbhqWwP+jRYzyb+nLbHqGPmEBvHKYjAO3GsJ/YXg==}
dependencies:
'@volar/language-core': 1.0.24
'@volar/language-core': 1.2.0-alpha.11
dev: true
/@volar/vue-language-core/1.0.24:
resolution: {integrity: sha512-2NTJzSgrwKu6uYwPqLiTMuAzi7fAY3yFy5PJ255bGJc82If0Xr+cW8pC80vpjG0D/aVLmlwAdO4+Ya2BI8GdDg==}
/@volar/vue-language-core/1.1.0:
resolution: {integrity: sha512-1zTAyeGiyNKYE9s+i3dUpmuvY/Cz1U7LjIh9d5FX3p0NWpaBrzYvSh0gQY+nRaz67or7Y9qYSUCaHLKOmeolzg==}
dependencies:
'@volar/language-core': 1.0.24
'@volar/source-map': 1.0.24
'@volar/language-core': 1.2.0-alpha.11
'@volar/source-map': 1.2.0-alpha.11
'@vue/compiler-dom': 3.2.47
'@vue/compiler-sfc': 3.2.47
'@vue/reactivity': 3.2.47
'@vue/shared': 3.2.47
minimatch: 5.1.6
minimatch: 6.2.0
muggle-string: 0.2.2
vue-template-compiler: 2.7.14
dev: true
/@volar/vue-typescript/1.0.24:
resolution: {integrity: sha512-9a25oHDvGaNC0okRS47uqJI6FxY4hUQZUsxeOUFHcqVxZEv8s17LPuP/pMMXyz7jPygrZubB/qXqHY5jEu/akA==}
/@volar/vue-typescript/1.1.0:
resolution: {integrity: sha512-smtfaePuNpVzXEypJayORtl8muvBdtV1FDWjces1WLYbbtcnmfWtdACW9xY0dkVk0LoE/LZTEmLBCQrRJ6hS1w==}
dependencies:
'@volar/typescript': 1.0.24
'@volar/vue-language-core': 1.0.24
'@volar/typescript': 1.2.0-alpha.11
'@volar/vue-language-core': 1.1.0
dev: true
/@vue/compiler-core/3.2.47:
@@ -1268,7 +1268,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001452
electron-to-chromium: 1.4.296
electron-to-chromium: 1.4.298
node-releases: 2.0.10
update-browserslist-db: 1.0.10_browserslist@4.21.5
dev: true
@@ -1724,8 +1724,8 @@ packages:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
dev: true
/electron-to-chromium/1.4.296:
resolution: {integrity: sha512-i/6Q+Y9bluDa2a0NbMvdtG5TuS/1Fr3TKK8L+7UUL9QjRS5iFJzCC3r70xjyOnLiYG8qGV4/mMpe6HuAbdJW4w==}
/electron-to-chromium/1.4.298:
resolution: {integrity: sha512-dJZurgxDeaqn90VmS23Xz+QPQQl84BxnlAfwCDFNjfEhqO2yLMDkeaDoJ1yPXAbmiqTi+hd5TpB5zi1N4hwBuQ==}
dev: true
/emoji-regex/8.0.0:
@@ -2052,7 +2052,7 @@ packages:
ci-info: 3.8.0
clean-regexp: 1.0.0
eslint: 8.34.0
esquery: 1.4.0
esquery: 1.4.1
indent-string: 4.0.0
is-builtin-module: 3.2.1
jsesc: 3.0.2
@@ -2186,7 +2186,7 @@ packages:
eslint-utils: 3.0.0_eslint@8.34.0
eslint-visitor-keys: 3.3.0
espree: 9.4.1
esquery: 1.4.0
esquery: 1.4.1
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 6.0.1
@@ -2224,8 +2224,8 @@ packages:
eslint-visitor-keys: 3.3.0
dev: true
/esquery/1.4.0:
resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
/esquery/1.4.1:
resolution: {integrity: sha512-3ZggxvMv5EEY1ssUVyHSVt0oPreyBfbUi1XikJVfjFiBeBDLdrb0IWoDiEwqT/2sUQi0TGaWtFhOGDD8RTpXgQ==}
engines: {node: '>=0.10'}
dependencies:
estraverse: 5.3.0
@@ -3227,8 +3227,8 @@ packages:
brace-expansion: 1.1.11
dev: true
/minimatch/5.1.6:
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
/minimatch/6.2.0:
resolution: {integrity: sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==}
engines: {node: '>=10'}
dependencies:
brace-expansion: 2.0.1
@@ -3255,8 +3255,8 @@ packages:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
dev: true
/muggle-string/0.1.0:
resolution: {integrity: sha512-Tr1knR3d2mKvvWthlk7202rywKbiOm4rVFLsfAaSIhJ6dt9o47W4S+JMtWhd/PW9Wrdew2/S2fSvhz3E2gkfEg==}
/muggle-string/0.2.2:
resolution: {integrity: sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==}
dev: true
/naive-ui/2.34.3_vue@3.2.47:
@@ -4449,7 +4449,7 @@ packages:
eslint-scope: 7.1.1
eslint-visitor-keys: 3.3.0
espree: 9.4.1
esquery: 1.4.0
esquery: 1.4.1
lodash: 4.17.21
semver: 7.3.8
transitivePeerDependencies:
@@ -4472,14 +4472,14 @@ packages:
he: 1.2.0
dev: true
/vue-tsc/1.0.24_typescript@4.9.5:
resolution: {integrity: sha512-mmU1s5SAqE1nByQAiQnao9oU4vX+mSdsgI8H57SfKH6UVzq/jP9+Dbi2GaV+0b4Cn361d2ln8m6xeU60ApiEXg==}
/vue-tsc/1.1.0_typescript@4.9.5:
resolution: {integrity: sha512-+JqTcuScA6OfyaVH3ezeCh2i2wRgzUScZ6EdTZ3AW69Nb+rmRyOAxmAjL6MPam8YCdwmmdfAUhmN/BNGVp5vQg==}
hasBin: true
peerDependencies:
typescript: '*'
dependencies:
'@volar/vue-language-core': 1.0.24
'@volar/vue-typescript': 1.0.24
'@volar/vue-language-core': 1.1.0
'@volar/vue-typescript': 1.1.0
typescript: 4.9.5
dev: true

View File

@@ -23,7 +23,9 @@
"common:cleanup": "rimraf node_modules && rimraf pnpm-lock.yaml"
},
"dependencies": {
"chatgpt": "^4.3.2",
"chatgpt": "^4.4.1",
"dotenv": "^16.0.3",
"esno": "^0.16.3",
"express": "^4.18.2",
"isomorphic-fetch": "^3.0.0"
},
@@ -31,11 +33,9 @@
"@antfu/eslint-config": "^0.35.2",
"@types/express": "^4.17.17",
"@types/node": "^18.13.0",
"dotenv": "^16.0.3",
"eslint": "^8.34.0",
"esno": "^0.16.3",
"rimraf": "^4.1.2",
"tsup": "^6.6.2",
"tsup": "^6.6.3",
"typescript": "^4.9.5"
}
}

68
service/pnpm-lock.yaml generated
View File

@@ -4,18 +4,20 @@ specifiers:
'@antfu/eslint-config': ^0.35.2
'@types/express': ^4.17.17
'@types/node': ^18.13.0
chatgpt: ^4.3.2
chatgpt: ^4.4.1
dotenv: ^16.0.3
eslint: ^8.34.0
esno: ^0.16.3
express: ^4.18.2
isomorphic-fetch: ^3.0.0
rimraf: ^4.1.2
tsup: ^6.6.2
tsup: ^6.6.3
typescript: ^4.9.5
dependencies:
chatgpt: 4.4.0
chatgpt: 4.4.1
dotenv: 16.0.3
esno: 0.16.3
express: 4.18.2
isomorphic-fetch: 3.0.0
@@ -23,9 +25,7 @@ devDependencies:
'@antfu/eslint-config': 0.35.2_7kw3g6rralp5ps6mg3uyzz6azm
'@types/express': 4.17.17
'@types/node': 18.13.0
dotenv: 16.0.3
eslint: 8.34.0
esno: 0.16.3
rimraf: 4.1.2
tsup: 6.6.3_typescript@4.9.5
typescript: 4.9.5
@@ -154,21 +154,21 @@ packages:
dependencies:
'@esbuild-kit/core-utils': 3.1.0
get-tsconfig: 4.4.0
dev: true
dev: false
/@esbuild-kit/core-utils/3.1.0:
resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==}
dependencies:
esbuild: 0.17.8
source-map-support: 0.5.21
dev: true
dev: false
/@esbuild-kit/esm-loader/2.5.5:
resolution: {integrity: sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==}
dependencies:
'@esbuild-kit/core-utils': 3.1.0
get-tsconfig: 4.4.0
dev: true
dev: false
/@esbuild/android-arm/0.17.8:
resolution: {integrity: sha512-0/rb91GYKhrtbeglJXOhAv9RuYimgI8h623TplY2X+vA4EXnk3Zj1fXZreJ0J3OJJu1bwmb0W7g+2cT/d8/l/w==}
@@ -176,7 +176,6 @@ packages:
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-arm64/0.17.8:
@@ -185,7 +184,6 @@ packages:
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-x64/0.17.8:
@@ -194,7 +192,6 @@ packages:
cpu: [x64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-arm64/0.17.8:
@@ -203,7 +200,6 @@ packages:
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-x64/0.17.8:
@@ -212,7 +208,6 @@ packages:
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-arm64/0.17.8:
@@ -221,7 +216,6 @@ packages:
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-x64/0.17.8:
@@ -230,7 +224,6 @@ packages:
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm/0.17.8:
@@ -239,7 +232,6 @@ packages:
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm64/0.17.8:
@@ -248,7 +240,6 @@ packages:
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ia32/0.17.8:
@@ -257,7 +248,6 @@ packages:
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-loong64/0.17.8:
@@ -266,7 +256,6 @@ packages:
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-mips64el/0.17.8:
@@ -275,7 +264,6 @@ packages:
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ppc64/0.17.8:
@@ -284,7 +272,6 @@ packages:
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-riscv64/0.17.8:
@@ -293,7 +280,6 @@ packages:
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-s390x/0.17.8:
@@ -302,7 +288,6 @@ packages:
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-x64/0.17.8:
@@ -311,7 +296,6 @@ packages:
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/netbsd-x64/0.17.8:
@@ -320,7 +304,6 @@ packages:
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/openbsd-x64/0.17.8:
@@ -329,7 +312,6 @@ packages:
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/sunos-x64/0.17.8:
@@ -338,7 +320,6 @@ packages:
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-arm64/0.17.8:
@@ -347,7 +328,6 @@ packages:
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-ia32/0.17.8:
@@ -356,7 +336,6 @@ packages:
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-x64/0.17.8:
@@ -365,7 +344,6 @@ packages:
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@eslint-community/eslint-utils/4.1.2_eslint@8.34.0:
@@ -805,7 +783,7 @@ packages:
/buffer-from/1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
dev: false
/builtin-modules/3.3.0:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
@@ -878,8 +856,8 @@ packages:
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
dev: true
/chatgpt/4.4.0:
resolution: {integrity: sha512-rS1F423hR5marIB7hvZ4KyczK9oFloWY+AR4WKIt+HLyiRgOOWv6V4olu1HvaoOayc5+A/N2WwX0SzuU1rI9Rg==}
/chatgpt/4.4.1:
resolution: {integrity: sha512-rccShNzq/aE4LMmwTW4IOHIAZgNRbX0KetVKRCdR4SkRXz63FWzOfu8pNbaN65gsvvXwXyRzD7W4LLDyXe4TYg==}
engines: {node: '>=18'}
dependencies:
eventsource-parser: 0.0.5
@@ -1090,7 +1068,7 @@ packages:
/dotenv/16.0.3:
resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
engines: {node: '>=12'}
dev: true
dev: false
/ee-first/1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@@ -1203,7 +1181,6 @@ packages:
'@esbuild/win32-arm64': 0.17.8
'@esbuild/win32-ia32': 0.17.8
'@esbuild/win32-x64': 0.17.8
dev: true
/escape-html/1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@@ -1416,7 +1393,7 @@ packages:
ci-info: 3.8.0
clean-regexp: 1.0.0
eslint: 8.34.0
esquery: 1.4.0
esquery: 1.4.1
indent-string: 4.0.0
is-builtin-module: 3.2.1
jsesc: 3.0.2
@@ -1550,7 +1527,7 @@ packages:
eslint-utils: 3.0.0_eslint@8.34.0
eslint-visitor-keys: 3.3.0
espree: 9.4.1
esquery: 1.4.0
esquery: 1.4.1
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 6.0.1
@@ -1584,7 +1561,7 @@ packages:
hasBin: true
dependencies:
tsx: 3.12.3
dev: true
dev: false
/espree/9.4.1:
resolution: {integrity: sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==}
@@ -1595,8 +1572,8 @@ packages:
eslint-visitor-keys: 3.3.0
dev: true
/esquery/1.4.0:
resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
/esquery/1.4.1:
resolution: {integrity: sha512-3ZggxvMv5EEY1ssUVyHSVt0oPreyBfbUi1XikJVfjFiBeBDLdrb0IWoDiEwqT/2sUQi0TGaWtFhOGDD8RTpXgQ==}
engines: {node: '>=0.10'}
dependencies:
estraverse: 5.3.0
@@ -1799,7 +1776,6 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
dev: true
optional: true
/function-bind/1.1.1:
@@ -1841,7 +1817,7 @@ packages:
/get-tsconfig/4.4.0:
resolution: {integrity: sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ==}
dev: true
dev: false
/glob-parent/5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
@@ -2977,12 +2953,12 @@ packages:
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
dev: true
dev: false
/source-map/0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
dev: true
dev: false
/source-map/0.8.0-beta.0:
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
@@ -3211,7 +3187,7 @@ packages:
'@esbuild-kit/esm-loader': 2.5.5
optionalDependencies:
fsevents: 2.3.2
dev: true
dev: false
/type-check/0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
@@ -3320,7 +3296,7 @@ packages:
eslint-scope: 7.1.1
eslint-visitor-keys: 3.3.0
espree: 9.4.1
esquery: 1.4.0
esquery: 1.4.1
lodash: 4.17.21
semver: 7.3.8
transitivePeerDependencies:

View File

@@ -3,6 +3,11 @@ import 'isomorphic-fetch'
import type { ChatGPTAPI, SendMessageOptions } from 'chatgpt'
import { sendResponse } from './utils'
export interface ChatContext {
conversationId?: string
parentMessageId?: string
}
dotenv.config()
const apiKey = process.env.OPENAI_API_KEY

View File

@@ -3,7 +3,9 @@ import type { ChatContext } from './chatgpt'
import { chatReply } from './chatgpt'
const app = express()
const router = express.Router()
app.use(express.static('public'))
app.use(express.json())
app.all('*', (_, res, next) => {
@@ -13,7 +15,7 @@ app.all('*', (_, res, next) => {
next()
})
app.post('/chat', async (req, res) => {
router.post('/chat', async (req, res) => {
try {
const { prompt, options = {} } = req.body as { prompt: string; options?: ChatContext }
const response = await chatReply(prompt, options)
@@ -24,4 +26,7 @@ app.post('/chat', async (req, res) => {
}
})
app.use('', router)
app.use('/api', router)
app.listen(3002, () => globalThis.console.log('Server is running on port 3002'))

View File

@@ -1,8 +1,6 @@
import type { GenericAbortSignal } from 'axios'
import { post } from '@/utils/request'
export const controller = new AbortController()
export function fetchChatAPI<T = any>(
prompt: string,
options?: { conversationId?: string; parentMessageId?: string },

View File

@@ -6,7 +6,6 @@ export function useChat() {
function addChat(
message: string,
args?: { reversal?: boolean; error?: boolean; options?: Chat.ChatOptions },
uuid?: number | null,
) {
historyStore.addChat(
{
@@ -16,7 +15,6 @@ export function useChat() {
error: args?.error ?? false,
options: args?.options ?? undefined,
},
uuid,
)
}

View File

@@ -7,7 +7,6 @@ import { useChat } from './hooks/useChat'
import { fetchChatAPI } from '@/api'
import { HoverButton, SvgIcon } from '@/components/common'
import { useHistoryStore } from '@/store'
import { isNumber } from '@/utils/is'
let controller = new AbortController()
@@ -23,6 +22,7 @@ const prompt = ref('')
const loading = ref(false)
const currentActive = computed(() => historyStore.active)
const heartbeat = computed(() => historyStore.heartbeat)
const list = computed<Chat.Chat[]>(() => historyStore.getCurrentChat)
const chatList = computed<Chat.Chat[]>(() => list.value.filter(item => (!item.reversal && !item.error)))
@@ -71,9 +71,8 @@ function handleEnter(event: KeyboardEvent) {
function addMessage(
message: string,
args?: { reversal?: boolean; error?: boolean; options?: Chat.ChatOptions },
uuid?: number | null,
) {
addChat(message, args, uuid)
addChat(message, args)
scrollToBottom()
}
@@ -96,10 +95,18 @@ onMounted(() => {
scrollToBottom()
})
watch(
heartbeat,
() => {
handleCancel()
scrollToBottom()
},
)
watch(
currentActive,
(active) => {
if (isNumber(active)) {
(_, oldActive) => {
if (oldActive !== null) {
handleCancel()
scrollToBottom()
}

View File

@@ -12,17 +12,21 @@ function handleSelect(index: number) {
historyStore.chooseHistory(index)
}
function handleEdit(index: number, isEdit: boolean) {
function handleEdit(index: number, isEdit: boolean, event?: MouseEvent) {
historyStore.editHistory(index, isEdit)
event?.stopPropagation()
}
function handleRemove(index: number) {
function handleRemove(index: number, event?: MouseEvent) {
historyStore.removeHistory(index)
event?.stopPropagation()
}
function handleEnter(index: number, isEdit: boolean, event: KeyboardEvent) {
if (event.key === 'Enter')
if (event.key === 'Enter') {
handleEdit(index, isEdit)
event.stopPropagation()
}
}
</script>
@@ -31,8 +35,8 @@ function handleEnter(index: number, isEdit: boolean, event: KeyboardEvent) {
<div class="flex flex-col gap-2 text-sm">
<div v-for="(item, index) of dataSources" :key="index">
<a
class="relative flex items-center gap-3 px-3 py-3 break-all border rounded-md cursor-pointer pr-14 hover:bg-neutral-100 group"
:class="historyStore.active === index && ['border-[#4b9e5f]', 'bg-neutral-100', 'text-[#4b9e5f]']"
class="relative flex items-center gap-3 px-3 py-3 break-all border rounded-md cursor-pointer hover:bg-neutral-100 group"
:class="historyStore.active === index && ['border-[#4b9e5f]', 'bg-neutral-100', 'text-[#4b9e5f]', 'pr-14']"
@click="handleSelect(index)"
>
<span>
@@ -45,17 +49,17 @@ function handleEnter(index: number, isEdit: boolean, event: KeyboardEvent) {
/>
<span v-else>{{ item.title }}</span>
</div>
<div class="absolute z-10 flex visible right-1">
<div v-if="historyStore.active === index" class="absolute z-10 flex visible right-1">
<template v-if="item.isEdit">
<button class="p-1" @click="handleEdit(index, false)">
<button class="p-1" @click="handleEdit(index, false, $event)">
<SvgIcon icon="ri:save-line" />
</button>
</template>
<template v-else>
<button class="p-1">
<SvgIcon icon="ri:edit-line" @click="handleEdit(index, true)" />
<SvgIcon icon="ri:edit-line" @click="handleEdit(index, true, $event)" />
</button>
<button class="p-1" @click="handleRemove(index)">
<button class="p-1" @click="handleRemove(index, $event)">
<SvgIcon icon="ri:delete-bin-line" />
</button>
</template>

View File

@@ -9,8 +9,5 @@ export const useAppStore = defineStore('app-store', {
this.siderCollapsed = collapsed
setLocalSetting(this.$state)
},
toggleSiderCollapse() {
this.setSiderCollapsed(!this.siderCollapsed)
},
},
})

View File

@@ -5,10 +5,11 @@ const LOCAL_NAME = 'historyChat'
export interface HistoryState {
historyChat: Chat.HistoryChat[]
active: number | null
heartbeat: boolean
}
export function defaultSetting() {
return { historyChat: [], active: null }
return { historyChat: [], active: null, heartbeat: false }
}
export function getLocalHistory() {

View File

@@ -1,6 +1,7 @@
import { defineStore } from 'pinia'
import type { HistoryState } from './helper'
import { getLocalHistory, setLocalHistory } from './helper'
export const useHistoryStore = defineStore('history-store', {
state: (): HistoryState => getLocalHistory(),
getters: {
@@ -18,16 +19,16 @@ export const useHistoryStore = defineStore('history-store', {
},
},
actions: {
addChat(data: Chat.Chat, uuid: number | null = null) {
addChat(data: Chat.Chat) {
if (this.active === null) {
this.historyChat.push({ title: data.message, isEdit: false, data: [data] })
this.active = this.historyChat.length - 1
}
else {
const active = uuid !== null ? uuid : this.active
if (this.historyChat[active].title === 'New Chat')
this.historyChat[active].title = data.message
this.historyChat[active].data.push(data)
if (this.historyChat[this.active].title === 'New Chat')
this.historyChat[this.active].title = data.message
this.historyChat[this.active].data.push(data)
}
setLocalHistory(this.$state)
},
@@ -52,14 +53,19 @@ export const useHistoryStore = defineStore('history-store', {
removeHistory(index: number) {
this.historyChat.splice(index, 1)
if (this.active === index) {
if (this.historyChat.length === 0)
this.active = null
else if (this.active === this.historyChat.length)
this.active--
else
this.active = 0
this.active = this.historyChat.length - 1
}
if (this.historyChat.length === 0)
this.active = null
this.toggleHeartbeat()
setLocalHistory(this.$state)
},
@@ -69,5 +75,9 @@ export const useHistoryStore = defineStore('history-store', {
this.active = index
setLocalHistory(this.$state)
},
toggleHeartbeat() {
this.heartbeat = !this.heartbeat
},
},
})

View File

@@ -1,6 +1,6 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
/** api url */
readonly VITE_GLOB_API_URL: string;
readonly VITE_APP_API_BASE_URL: string;
}

View File

@@ -14,7 +14,7 @@ export function isNull<T extends null>(value: T | unknown): value is null {
return Object.prototype.toString.call(value) === '[object Null]'
}
export function isUndefine<T extends undefined>(value: T | unknown): value is undefined {
export function isUndefined<T extends undefined>(value: T | unknown): value is undefined {
return Object.prototype.toString.call(value) === '[object Undefined]'
}

View File

@@ -11,10 +11,6 @@ export interface HttpOption {
afterRequest?: () => void
}
export interface ExtraOption {
notification?: boolean
}
export interface Response<T = any> {
data: T
message: string | null

View File

@@ -3,7 +3,8 @@ import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig((env) => {
const viteEnv = loadEnv(env.mode, process.cwd())
const viteEnv = loadEnv(env.mode, process.cwd()) as unknown as ImportMetaEnv
return {
resolve: {
alias: {