├── .browserslistrc ├── .dockerignore ├── .env.serve ├── .github ├── FUNDING.yml └── workflows │ └── docker.yaml ├── .gitignore ├── .npmrc ├── Dockerfile ├── LICENSE ├── README.md ├── babel.config.js ├── docker-compose.yml ├── index.html ├── jsconfig.json ├── package-lock.json ├── package.json ├── public ├── favicon.icns ├── favicon.ico ├── index.ejs └── user_custom.json ├── src ├── App.vue ├── api │ ├── getData.js │ └── index.js ├── assets │ ├── css │ │ ├── style.css │ │ ├── style.css.map │ │ └── style.scss │ ├── font │ │ ├── demo.css │ │ ├── font.css │ │ ├── iconfont.css │ │ ├── iconfont.js │ │ ├── iconfont.json │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ ├── iconfont.woff2 │ │ └── 阿里妈妈东方大楷_Regular.ttf │ ├── img │ │ ├── ai.png │ │ ├── bj.png │ │ ├── emoji │ │ │ ├── clown-face.png │ │ │ ├── face-screaming-in-fear.png │ │ │ ├── face-vomiting.png │ │ │ ├── face-with-tongue.png │ │ │ ├── face-without-mouth.png │ │ │ ├── ghost.png │ │ │ ├── hibiscus.png │ │ │ ├── jack-o-lantern.png │ │ │ ├── lips.png │ │ │ ├── loudly-crying-face.png │ │ │ ├── money-bag.png │ │ │ ├── money-mouth-face.png │ │ │ ├── new-moon-face.png │ │ │ ├── ok-hand-yellow.png │ │ │ ├── pile-of-poo.png │ │ │ ├── pouting-face.png │ │ │ ├── rainbow.png │ │ │ ├── rocket.png │ │ │ ├── shamrock.png │ │ │ ├── slightly-smiling-face.png │ │ │ ├── smiling-face-with-heart-eyes.png │ │ │ ├── smiling-face-with-horns.png │ │ │ ├── smiling-face-with-sunglasses.png │ │ │ ├── smiling-face.png │ │ │ ├── sparkles.png │ │ │ ├── star.png │ │ │ ├── thinking-face.png │ │ │ ├── thought-balloon.png │ │ │ ├── thumbs-up-yellow.png │ │ │ ├── tired-face.png │ │ │ ├── two-hearts.png │ │ │ └── victory-hand-yellow.png │ │ ├── fileImg │ │ │ ├── excel.png │ │ │ ├── pdf.png │ │ │ ├── ppt.png │ │ │ ├── txt.png │ │ │ ├── unknowfile.png │ │ │ ├── word.png │ │ │ └── zpi.png │ │ ├── head.jpg │ │ ├── img1.png │ │ ├── img2.png │ │ ├── shuaxin.png │ │ └── snapchat.png │ └── logo.png ├── background.js ├── components │ ├── Emoji.vue │ ├── File.vue │ ├── FileCard.vue │ ├── HeadImg.vue │ ├── HeadPortrait.vue │ ├── Nav.vue │ ├── PersonCard.vue │ ├── RoleCard.vue │ └── Session.vue ├── config │ └── i18n.js ├── lang │ ├── en.js │ └── zh-CN.js ├── main.js ├── router │ └── index.js ├── store │ └── mutation-types.js ├── util │ └── util.js └── view │ ├── home.vue │ └── pages │ ├── chatHome │ ├── chatwindow.vue │ └── index.vue │ ├── setting.vue │ └── user │ └── userInfo.vue └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .github 2 | node_modules 3 | README.md 4 | -------------------------------------------------------------------------------- /.env.serve: -------------------------------------------------------------------------------- 1 | #设置openai的key,防止页面刷新重新输入 2 | VUE_APP_OPENAI_API_KEY="" 3 | #设置 OpenAI Url 4 | VUE_APP_OPENAI_API_URL="" -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/workflows/docker.yaml: -------------------------------------------------------------------------------- 1 | name: docker 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Check Out 14 | uses: actions/checkout@v3 15 | 16 | - name: Build docker image 17 | id: docker_build 18 | uses: docker/build-push-action@v2 19 | with: 20 | context: ./ 21 | file: ./Dockerfile 22 | push: false 23 | tags: chat-gpt:latest 24 | 25 | - name: Image digest 26 | run: echo ${{ steps.docker_build.outputs.digest }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | .env 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | pnpm-debug.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | #Electron-builder output 27 | /dist_electron -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry="https://registry.npmmirror.com/" 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16-alpine AS builder 2 | WORKDIR /app 3 | 4 | # install and cache app dependencies 5 | COPY package.json . 6 | RUN npm install 7 | 8 | ARG OPENAI_API_KEY="" 9 | ARG OPENAI_API_URL="" 10 | ENV VUE_APP_OPENAI_API_URL="${OPENAI_API_URL}" 11 | 12 | COPY . . 13 | RUN npm run build 14 | 15 | FROM nginx:alpine 16 | 17 | COPY --from=builder /app/dist /usr/share/nginx/html -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2023, 吕世昊 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |

OpenAI Manager

6 |
7 |

8 |

基于Vue2+ElementUI构建的OpenAI管理系统

9 |

10 | 11 | 12 | 13 |

14 | 15 |
16 | 声明:免费且作为开源学习使用。 17 | 项目使用Vue2进行开发,给大家提供一个方便使用的OpenAI Web 管理界面,有好的建议和bug欢迎大家提出来,项目会一直开源和代码优化,方便对OpenAI API进行入门了解使用,后期会接入后端,实现更丰富的功能。 18 |
19 |
20 | 21 | > 🤭记得点个小星星Starred 22 | 23 | > gitcode:https://gitcode.com/2022521971/ChatGPT_JCM 24 | > github:https://github.com/202252197/ChatGPT_JCM 25 | 26 | 27 | 28 | ## 会话 29 | ![webui4.5](https://www.freeimg.cn/i/2023/12/26/658a737bec9c4.jpeg) 30 | ## 模型 31 | ![webui4.5](https://www.freeimg.cn/i/2023/12/26/658a7358e83b7.jpeg) 32 | ## 微调模型 33 | ![webui4.5](https://www.freeimg.cn/i/2023/12/26/658a74002da34.jpeg) 34 | ## 文件 35 | ![webui4.5](https://www.freeimg.cn/i/2023/12/26/658a73b451da1.jpeg) 36 | ## 中英文切换 37 | ![webui4.5](https://www.freeimg.cn/i/2023/12/26/658a73e2c8945.jpeg) 38 | ## 适配手机 39 |
40 | drawing 41 | drawing 42 | drawing 43 |
44 | 45 | ## 参考视频 46 | https://www.bilibili.com/video/BV1BM4y187bp 使用API调用StableDiffusion生成图片简单案例 47 | https://www.bilibili.com/video/BV1iL411k7pC 本地+云服务器 部署此项目视频 48 | https://www.bilibili.com/video/BV1ss4y1d72g 此项目微调使用的简单案例 49 | 关注我的B站,持续输出简单的入门案例 50 | 51 | # 部署步骤 52 | ## 本地部署 53 | 54 | ```sh 55 | npm install 安装依赖 56 | npm run serve 运行项目 57 | npm run build 构建项目 58 | ``` 59 | 60 | # 在线体验地址 (需要使用OpenAI KEY) 61 | 62 | > https://huggingface.co/spaces/junchenmo/OpenAI-Manager 63 | 64 | ## OpenAI-Key设置以及自定义设置 65 | #### 只需要在界面输入openai官方key即可 66 | 注意:如果是错误的key或者是没有额度的key不会输出任何内容 67 | 68 | #### 在/src/store/mutation-types.js 69 | 70 | 可以在此文件中设置AI头像+用户头像+用户名称 71 | 72 | # 技术栈 73 | 74 | | 名称 | 版本 | 75 | | ---- | ---- | 76 | | vue | 2.6.14 | 77 | | element-ui | 2.15.12 | 78 | | NodeJS | 14+ | 79 | 80 | # 项目进度(对标OpenAI官方接口文档) 81 | 82 | | 接口 | 描述 | 83 | | ---- | ---- | 84 | | List Models | 获取模型列表 | 85 | | Completion | text-davinci-003, text-davinci-002, text-curie-001, text-babbage-001, text-ada-001, davinci, curie, babbage, ada等模型 | 86 | | Chat Completion | gpt-4, gpt-4-0314, gpt-4-32k, gpt-4-32k-0314, gpt-3.5-turbo, gpt-3.5-turbo-0301等最新模型 | 87 | | Create edit | 创建编辑(待..) | 88 | | Create Image | 根据描述生成图片 | 89 | | Create image edit | 根据上传的图片结合输入的描述生成图片 | 90 | | Create Image Variation | 根据上传的图片生成变体图片 | 91 | | Create embeddings | 创建向量查询(可以实现PDF对话)(待..) | 92 | | Create transcription | 语音转换为文字 | 93 | | Create translation | 一个或多个来源语言的语音或音频文件翻译成目标语言 | 94 | | List files | 文件列表 | 95 | | Upload file | 上传文件 | 96 | | Delete file | 删除文件 | 97 | | Retrieve file | 检索文件信息 | 98 | | Retrieve file content | 检索文件内容(OpenAI为了防止滥用,只要plus用户才可以使用) | 99 | | Create fine-tune | 创建微调 | 100 | | List fine-tunes | 微调列表 | 101 | | Retrieve fine-tune | 检索微调信息 | 102 | | Cancel fine-tune | 取消微调 | 103 | | List fine-tune events | 微调事件列表(待..) | 104 | | Delete fine-tune model | 删除微调模型 | 105 | | Create moderation | 创建审核 | 106 | | List engines | 引擎列表(已弃用) | 107 | | Retrieve engine | 检索引擎信息(已弃用) | 108 | | 多会话储存和上下文逻辑 | GPT3.5模型支持上下文逻辑,多窗口上下文对话 | 109 | | 导出导入数据 | 支持导出当前会话,导出全部会话,导入当前会话,导出当前会话,清除当前会话,清除全部会话 |x 110 | | 角色扮演 | 内置多角色prompt | 111 | | 界面多语言 | 支持中英文语言 | 112 | 113 | # 贡献者 114 |
115 | 116 | 117 | 118 |
119 | 120 | 121 | 122 | # 免责声明 123 | 这不是官方的OpenAI产品。这是一个个人项目,与OpenAI没有任何关系。不要起诉我。 124 | 125 | 126 | ![Visitor Count](https://profile-counter.glitch.me/202252197/count.svg) 127 | 128 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.6" 2 | 3 | services: 4 | chatgpt: 5 | container_name: chatgpt 6 | build: 7 | context: . 8 | dockerfile: ./Dockerfile 9 | args: 10 | # - OPENAI_API_URL=http://baidu.com 11 | ports: 12 | - 8090:80 13 | restart: unless-stopped 14 | logging: 15 | driver: "json-file" 16 | options: 17 | max-size: "100m" 18 | max-file: "1" -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OpenAI Manager JCM 6 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "baseUrl": "./", 6 | "moduleResolution": "node", 7 | "paths": { 8 | "@/*": [ 9 | "src/*" 10 | ] 11 | }, 12 | "lib": [ 13 | "esnext", 14 | "dom", 15 | "dom.iterable", 16 | "scripthost" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OpenAI-Manager-JCM", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --mode serve", 7 | "build": "vue-cli-service build --mode serve", 8 | "electron:build": "vue-cli-service electron:build --mode serve", 9 | "electron:serve": "vue-cli-service electron:serve --mode serve", 10 | "postinstall": "electron-builder install-app-deps", 11 | "postuninstall": "electron-builder install-app-deps" 12 | }, 13 | "main": "background.js", 14 | "dependencies": { 15 | "axios": "^1.3.4", 16 | "core-js": "^3.29.1", 17 | "element-ui": "^2.15.13", 18 | "file-saver": "^2.0.5", 19 | "html-webpack-plugin": "^5.5.0", 20 | "html2canvas": "^1.4.1", 21 | "markdown-it-vue": "^1.1.7", 22 | "node-polyfill-webpack-plugin": "^2.0.1", 23 | "openai": "^3.2.1", 24 | "sass": "^1.60.0", 25 | "sass-loader": "^13.2.1", 26 | "vue": "^2.6.14", 27 | "vue-i18n": "^8.28.2", 28 | "vue-router": "^3.6.5" 29 | }, 30 | "devDependencies": { 31 | "@vue/cli-plugin-babel": "~5.0.0", 32 | "@vue/cli-service": "~5.0.0", 33 | "babel-plugin-component": "^1.1.1", 34 | "electron": "^11.5.0", 35 | "electron-devtools-installer": "^3.1.0", 36 | "vue-cli-plugin-electron-builder": "~2.1.1", 37 | "vue-template-compiler": "^2.6.14", 38 | "wasm-loader": "^1.3.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /public/favicon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/public/favicon.icns -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/public/favicon.ico -------------------------------------------------------------------------------- /public/index.ejs: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 28 |
29 | 30 | <% if (!htmlWebpackPlugin.options.process.browser) { %> 31 | 34 | <% } %> 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 28 | 29 | -------------------------------------------------------------------------------- /src/api/getData.js: -------------------------------------------------------------------------------- 1 | import base from './index' 2 | import { AI_HEAD_IMG_URL } from '../store/mutation-types' 3 | import { generateUUID } from "@/util/util"; 4 | 5 | let axios = base.axios 6 | let baseUrl = base.baseUrl 7 | 8 | // 根据name查找元素的索引 9 | function findIndexByName(arr, name) { 10 | for (let i = 0; i < arr.length; i++) { 11 | if (arr[i].name === name || arr[i] === name) { 12 | return i; 13 | } 14 | } 15 | return -1; // 没有找到对应的元素 16 | } 17 | 18 | const desp_model = { 19 | "gpt-3.5-turbo": "chatgpt v3.5 所基于的模型", 20 | "ada": "自然语言模型,OpenAI提供的最快,最便宜的模型,但性能也最差,含有ada字眼的模型都是基于ada训练而来", 21 | "babbage": "自然语言模型,性能比ada强,价格比ada贵,规模比ada大,含有babbage字眼的模型都是基于babbage训练而来", 22 | "curie": "自然语言模型,性能优于ada,babbage,价钱也更贵,规模更大,含有curie字眼的模型都是基于curie训练而来", 23 | "davinci": "自然语言模型,在ada,babbage,curie和davinci中性能最优,规模最大,速度最慢,价钱最贵,含有davinci字眼的模型都是基于davinci训练而来,目前chatgpt基于davinci微调而来", 24 | "whisper-1": "强大的语音转换文本的模型" 25 | } 26 | const other_desps = { 27 | "code": "的AI代码处理模型", 28 | "similarity": "的AI文本相似度计算模型", 29 | "document": "的大文档处理模型", 30 | "text": "的文本处理模型", 31 | "instruct": "的人工指令微调模型", 32 | "if": "一个分支" 33 | } 34 | const desp_keys = Object.keys(desp_model) 35 | const other_desp_keys = Object.keys(other_desps) 36 | 37 | function produceModelDesc(model) { 38 | const idx = findIndexByName(desp_keys, model) 39 | if (idx !== -1) { 40 | return desp_model[model] 41 | } 42 | else { 43 | let desc = ''; 44 | for (let i = 0; i < desp_keys.length; i++) { 45 | const key = desp_keys[i]; 46 | if (model.includes(key)) { 47 | desc += `基于语言模型${key}`; 48 | break; 49 | } 50 | } 51 | for (let i = 0; i < other_desp_keys.length; i++) { 52 | const key = other_desp_keys[i]; 53 | if (model.includes(key)) { 54 | desc += other_desps[key]; 55 | break; 56 | } 57 | } 58 | if (desc == "") { 59 | desc = model + "模型" 60 | } 61 | return desc 62 | } 63 | } 64 | 65 | 66 | // 获取模型列表 67 | export const getModels = token => { 68 | return axios({ 69 | method: 'get', 70 | baseURL: `${baseUrl}/v1/models`, 71 | headers: { 72 | 'Authorization': 'Bearer ' + token, 73 | 'Content-Type': 'application/json' 74 | } 75 | }).then(res => { 76 | const modelsObj = [] 77 | //获取所有的模型 78 | const models = [...new Set(res.data.data.map(model => model.id))].sort(); 79 | models.forEach(model => { 80 | let modelObj = { 81 | img: "", 82 | name: model, 83 | detail: produceModelDesc(model), 84 | lastMsg: produceModelDesc(model), 85 | id: model, 86 | headImg: AI_HEAD_IMG_URL, 87 | showHeadImg: true 88 | } 89 | modelsObj.push(modelObj) 90 | }); 91 | // 将gpt-3.5-turbo置顶 92 | const idx = findIndexByName(modelsObj, "gpt-3.5-turbo") 93 | if (idx !== -1) { 94 | const element = modelsObj.splice(idx, 1)[0]; // 将idx元素删除 95 | modelsObj.unshift(element); // 将idx出的元素至于列表头 96 | } 97 | return modelsObj; 98 | }) 99 | } 100 | // 获取角色列表 101 | export const getRoles = () => { 102 | return axios({ 103 | method: 'get', 104 | baseURL: `user_custom.json`, 105 | headers: { 106 | 'Content-Type': 'application/json' 107 | } 108 | }) 109 | } 110 | 111 | // 根据提示创建图像 112 | export const createImage = (params, token) => { 113 | console.log(params) 114 | return axios({ 115 | method: 'post', 116 | baseURL: `${baseUrl}/v1/images/generations`, 117 | headers: { 118 | 'Authorization': 'Bearer ' + token, 119 | 'Content-Type': 'application/json' 120 | }, 121 | data: params 122 | }).then(res => { 123 | return res.data.data; 124 | }) 125 | } 126 | 127 | // 根据提示词编辑图像 128 | export const createImageEdit = (formData, token) => { 129 | return axios({ 130 | method: 'post', 131 | baseURL: `${baseUrl}/v1/images/edits`, 132 | headers: { 133 | 'Authorization': 'Bearer ' + token, 134 | 'Content-Type': 'multipart/form-data' 135 | }, 136 | data: formData 137 | }).then(res => { 138 | return res.data.data; 139 | }) 140 | } 141 | 142 | // 根据创建图像变体 143 | export const createImageVariations = (formData, token) => { 144 | return axios({ 145 | method: 'post', 146 | baseURL: `${baseUrl}/v1/images/variations`, 147 | headers: { 148 | 'Authorization': 'Bearer ' + token, 149 | 'Content-Type': 'multipart/form-data' 150 | }, 151 | data: formData 152 | }).then(res => { 153 | return res.data.data; 154 | }) 155 | } 156 | 157 | // 将音频转换为文字 158 | export const createTranscription = (formData, token) => { 159 | return axios({ 160 | method: 'post', 161 | baseURL: `${baseUrl}/v1/audio/transcriptions`, 162 | headers: { 163 | 'Authorization': 'Bearer ' + token, 164 | 'Content-Type': 'multipart/form-data' 165 | }, 166 | data: formData 167 | }).then(res => { 168 | return res.data; 169 | }) 170 | } 171 | 172 | // 将音频翻译成英语 173 | export const createTranslation = (formData, token) => { 174 | return axios({ 175 | method: 'post', 176 | baseURL: `${baseUrl}/v1/audio/translations`, 177 | headers: { 178 | 'Authorization': 'Bearer ' + token, 179 | 'Content-Type': 'multipart/form-data' 180 | }, 181 | data: formData 182 | }).then(res => { 183 | return res.data; 184 | }) 185 | } 186 | 187 | // 创建微调 188 | export const createFineTune = (formData, token) => { 189 | return axios({ 190 | method: 'post', 191 | baseURL: `${baseUrl}/v1/fine_tuning/jobs/`, 192 | headers: { 193 | 'Authorization': 'Bearer ' + token, 194 | 'Content-Type': 'application/json' 195 | }, 196 | data: formData 197 | }).then(res => { 198 | return res.data; 199 | }).catch(e => { 200 | console.log(e) 201 | }) 202 | } 203 | 204 | 205 | // 列出微调 206 | export const getFineTunesList = token => { 207 | return axios({ 208 | method: 'get', 209 | baseURL: `${baseUrl}/v1/fine_tuning/jobs/`, 210 | headers: { 211 | 'Authorization': 'Bearer ' + token, 212 | 'Content-Type': 'application/json' 213 | } 214 | }).then(res => { 215 | console.log(res) 216 | const fineTunesObjs = [] 217 | res.data.data.forEach(fineTunes => { 218 | let fineTunesObj = { 219 | img: "", 220 | name: fineTunes.fine_tuned_model, 221 | detail: "基于"+fineTunes.model+"微调创建的模型", 222 | lastMsg: "基于"+fineTunes.model+"微调创建的模型", 223 | id: fineTunes.fine_tuned_model?fineTunes.fine_tuned_model:generateUUID(), 224 | headImg: AI_HEAD_IMG_URL, 225 | showHeadImg: true, 226 | createTime: fineTunes.created_at, 227 | fineTunesId:fineTunes.id, 228 | fineTunesStatus:fineTunes.status 229 | } 230 | fineTunesObjs.push(fineTunesObj) 231 | }); 232 | return fineTunesObjs.sort((a, b) => b.createTime - a.createTime); 233 | }) 234 | } 235 | 236 | 237 | // 检索微调信息 238 | export const retrieveFineTune = (fineTuneId, token) => { 239 | return axios({ 240 | method: 'get', 241 | baseURL: `${baseUrl}/v1/fine_tuning/jobs/` + fineTuneId, 242 | headers: { 243 | 'Authorization': 'Bearer ' + token, 244 | 'Content-Type': 'application/json' 245 | } 246 | }).then(res => { 247 | return res.data; 248 | }) 249 | } 250 | 251 | 252 | 253 | // 取消微调 254 | export const cancelFineTune = (fineTuneId, token) => { 255 | return axios({ 256 | method: 'post', 257 | baseURL: `${baseUrl}/v1/fine_tuning/jobs/` + fineTuneId + '/cancel', 258 | headers: { 259 | 'Authorization': 'Bearer ' + token, 260 | 'Content-Type': 'application/json' 261 | } 262 | }).then(res => { 263 | return res.data; 264 | }) 265 | } 266 | 267 | // 获取微调事件列表 268 | export const getFineTuneEventsList = (fineTuneId, token) => { 269 | return axios({ 270 | method: 'get', 271 | baseURL: `${baseUrl}/v1/fine_tuning/jobs/` + fineTuneId + '/events', 272 | headers: { 273 | 'Authorization': 'Bearer ' + token, 274 | 'Content-Type': 'multipart/form-data' 275 | }, 276 | data: fineTuneId 277 | }).then(res => { 278 | return res.data; 279 | }) 280 | } 281 | 282 | // 删除微调模型 283 | export const deleteFineTuneModel = (model, token) => { 284 | return axios({ 285 | method: 'delete', 286 | baseURL: `${baseUrl}/v1/models/` + model, 287 | headers: { 288 | 'Authorization': 'Bearer ' + token, 289 | 'Content-Type': 'application/json' 290 | } 291 | }).then(res => { 292 | return res.data; 293 | }) 294 | } 295 | 296 | 297 | //获取文件列表 298 | export const getFilesList = token => { 299 | return axios({ 300 | method: 'get', 301 | baseURL: `${baseUrl}/v1/files`, 302 | headers: { 303 | 'Authorization': 'Bearer ' + token, 304 | 'Content-Type': 'application/json' 305 | } 306 | }).then(res => { 307 | console.log(res) 308 | const fileObjs = [] 309 | res.data.data.forEach(file => { 310 | let fileObj = { 311 | img: "", 312 | name: file.filename, 313 | detail: "文件ID是:"+file.id+",文件大小是:"+(file.bytes/1024/1024).toFixed(2)+"MB", 314 | lastMsg: "文件ID是:"+file.id+",文件大小是:"+(file.bytes/1024/1024).toFixed(2)+"MB", 315 | id: file.filename, 316 | createTime: file.created_at, 317 | fileId:file.id 318 | } 319 | fileObjs.push(fileObj) 320 | }); 321 | return fileObjs.sort((a, b) => b.createTime - a.createTime); 322 | }) 323 | } 324 | 325 | // 删除文件 326 | export const deleteFile = (file, token) => { 327 | return axios({ 328 | method: 'delete', 329 | baseURL: `${baseUrl}/v1/files/` + file, 330 | headers: { 331 | 'Authorization': 'Bearer ' + token, 332 | 'Content-Type': 'application/json' 333 | } 334 | }).then(res => { 335 | return res.data; 336 | }) 337 | } 338 | 339 | // 上传JSONL文件 340 | export const uploadFile = (formData, token) => { 341 | return axios({ 342 | method: 'post', 343 | baseURL: `${baseUrl}/v1/files`, 344 | headers: { 345 | 'Authorization': 'Bearer ' + token, 346 | 'Content-Type': 'multipart/form-data' 347 | }, 348 | data: formData 349 | }).then(res => { 350 | console.log("文件上传成功") 351 | console.log(res) 352 | return res.data; 353 | }) 354 | } 355 | 356 | 357 | // 检索文件 358 | export const retrieveFile = (file, token) => { 359 | return axios({ 360 | method: 'get', 361 | baseURL: `${baseUrl}/v1/files/` + file, 362 | headers: { 363 | 'Authorization': 'Bearer ' + token, 364 | 'Content-Type': 'application/json' 365 | } 366 | }).then(res => { 367 | return res.data; 368 | }) 369 | } 370 | 371 | // 检索文件内容 372 | export const retrieveFileContent = (file, token) => { 373 | 374 | // return axios({ 375 | // method: 'get', 376 | // baseURL: `${baseUrl}v1/files/`+file+`/content`, 377 | // headers: { 378 | // 'Authorization': 'Bearer ' + token 379 | // } 380 | // }).then(response => { 381 | // const writer = fs.createWriteStream('./file.txt') 382 | // response.data.pipe(writer) 383 | // }) 384 | } 385 | 386 | 387 | 388 | // 检索文件内容 389 | export const createEmbeddings = (params, token) => { 390 | return axios({ 391 | method: 'post', 392 | baseURL: `${baseUrl}/v1/embeddings`, 393 | headers: { 394 | 'Authorization': 'Bearer ' + token, 395 | 'Content-Type': 'application/json' 396 | }, 397 | data:params 398 | }).then(response => { 399 | console.log(response) 400 | return response.data 401 | }) 402 | } 403 | 404 | 405 | // 获取账号余额信息 406 | export const getMoneyInfo = token => { 407 | return axios({ 408 | method: 'get', 409 | baseURL: `${baseUrl}/dashboard/billing/credit_grants`, 410 | headers: { 411 | 'Authorization': 'Bearer ' + token, 412 | 'Content-Type': 'application/json' 413 | } 414 | }).then(res => { 415 | return res.data; 416 | }) 417 | } 418 | 419 | 420 | // 获取聊天信息 421 | export const getChatMsg = params => { 422 | return axios({ 423 | method: 'post', 424 | baseURL: `${baseUrl}/friend/chatMsg`, 425 | data: params 426 | }).then(res => res.data) 427 | } 428 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | //全局参数,自定义参数可在发送请求时设置 4 | axios.defaults.timeout = 300000000 //超时时间ms 5 | axios.defaults.withCredentials = false 6 | // 请求时的拦截 7 | //回调里面不能获取错误信息 8 | axios.interceptors.request.use( 9 | function (config) { 10 | 11 | return config; 12 | }, 13 | function (error) { 14 | // 当请求异常时做一些处理 15 | console.log('请求异常:' + JSON.stringify(error)); 16 | return Promise.reject(error); 17 | } 18 | ); 19 | 20 | axios.interceptors.response.use(function (response) { 21 | // Do something with response data 22 | 23 | return response 24 | }, function (error) { 25 | // Do something with response error 26 | console.log('响应出错:' + error) 27 | return Promise.reject(error) 28 | }) 29 | 30 | 31 | const base = { 32 | axios: axios, 33 | baseUrl: process.env.VUE_APP_OPENAI_API_URL || 'https://api.openai.com' 34 | } 35 | 36 | export default base -------------------------------------------------------------------------------- /src/assets/css/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-size: 15px; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | min-height: 100vh; 8 | background-color: #abc6f8; 9 | background-image: radial-gradient(closest-side, rgb(255, 255, 255), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgb(250, 203, 203), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgb(237, 252, 202), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgb(197, 248, 241), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgb(206, 200, 243), rgba(248, 192, 147, 0)); 10 | background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax; 11 | background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax; 12 | background-repeat: no-repeat; 13 | animation: 10s movement linear infinite; 14 | } 15 | 16 | body::after { 17 | /* content: ""; 18 | display: block; 19 | position: fixed; */ 20 | width: 100%; 21 | height: 100%; 22 | top: 0; 23 | left: 0; 24 | backdrop-filter: blur(10px); 25 | -webkit-backdrop-filter: blur(10px); 26 | } 27 | 28 | .content { 29 | width: 90vw; 30 | height: 90vh; 31 | position: absolute; 32 | left: 50%; 33 | top: 50%; 34 | transform: translate(-50%, -50%); 35 | z-index: 1; 36 | border-radius: 30px; 37 | background: #000; 38 | border: 1px solid rgba(255, 255, 255, 0.18); 39 | display: flex; 40 | } 41 | .content .left { 42 | flex: 1; 43 | position: relative; 44 | } 45 | .content .left .sphere { 46 | position: absolute; 47 | left: 30%; 48 | width: 90%; 49 | z-index: 1; 50 | animation: sphereAnimation 2s; 51 | animation-fill-mode: forwards; 52 | animation-timing-function: ease; 53 | } 54 | .content .left .people { 55 | position: absolute; 56 | left: -50%; 57 | top: 20%; 58 | width: 70%; 59 | z-index: 2; 60 | } 61 | .content .left .p-animtion { 62 | animation: peopleAnimation 2s; 63 | animation-fill-mode: forwards; 64 | animation-timing-function: ease; 65 | } 66 | .content .left .p-other-animtion { 67 | animation-name: pOtherAnimation; 68 | animation-direction: alternate; 69 | animation-timing-function: linear; 70 | animation-iteration-count: infinite; 71 | animation-duration: 3s; 72 | } 73 | .content .left .s-animtion { 74 | animation: sphereAnimation 2s; 75 | animation-fill-mode: forwards; 76 | animation-timing-function: ease; 77 | } 78 | .content .left .s-other-animtion { 79 | animation-name: sOtherAnimation; 80 | animation-direction: alternate; 81 | animation-timing-function: linear; 82 | animation-iteration-count: infinite; 83 | animation-duration: 3s; 84 | } 85 | .content .right { 86 | flex: 1; 87 | position: relative; 88 | z-index: 12; 89 | } 90 | .content .right .top { 91 | width: 80%; 92 | margin-left: 38px; 93 | color: rgb(51, 52, 124); 94 | font-family: "iconfont" !important; 95 | font-style: normal; 96 | font-size: 25px; 97 | vertical-align: middle; 98 | transition: .3s; 99 | -webkit-font-smoothing: antialiased; 100 | -moz-osx-font-smoothing: grayscale; 101 | 102 | position: absolute; 103 | left: 50%; 104 | top: 5%; 105 | transform: translate(-50%, 0); 106 | } 107 | .content .right .top .top-item { 108 | float: left; 109 | width: 150px; 110 | height: 40px; 111 | line-height: 40px; 112 | text-align: center; 113 | margin-right: 10px; 114 | transition: 0.5s; 115 | } 116 | .content .right .top .top-item:hover { 117 | border: 0; 118 | background-color: #fff; 119 | border-radius: 50px; 120 | cursor: pointer; 121 | box-shadow: -20px 10px 32px 1px rgba(182, 183, 185, 0.37); 122 | } 123 | .content .right .form-wrappepr { 124 | width: 60%; 125 | position: absolute; 126 | left: 50%; 127 | top: 50%; 128 | transform: translate(-50%, -50%); 129 | text-align: right; 130 | } 131 | .content .right .form-wrappepr h1 { 132 | float: left; 133 | font-family: "iconfont" !important; 134 | font-style: normal; 135 | vertical-align: middle; 136 | transition: .3s; 137 | -webkit-font-smoothing: antialiased; 138 | -moz-osx-font-smoothing: grayscale; 139 | margin: 30px 0; 140 | } 141 | .content .right .form-wrappepr .inputs { 142 | display: block; 143 | width: 100%; 144 | height: 70px; 145 | margin: 30px 0; 146 | border-radius: 10px; 147 | border: 0; 148 | background-color: rgb(210, 223, 237); 149 | color: rgb(80, 82, 84); 150 | font-family: "iconfont" !important; 151 | font-style: normal; 152 | transition: .3s; 153 | -webkit-font-smoothing: antialiased; 154 | -moz-osx-font-smoothing: grayscale; 155 | outline: none; 156 | padding: 20px; 157 | box-sizing: border-box; 158 | font-size: 20px; 159 | } 160 | .content .right .form-wrappepr .tips { 161 | display: block; 162 | margin-top: -15px; 163 | color: rgb(160, 170, 182); 164 | cursor: pointer; 165 | } 166 | .content .right .form-wrappepr button { 167 | width: 100%; 168 | height: 50px; 169 | background-color: rgb(68, 96, 241); 170 | border-radius: 10px; 171 | font-size: 15px; 172 | color: #fff; 173 | border: 0; 174 | font-weight: 600; 175 | margin: 30px 0; 176 | cursor: pointer; 177 | box-shadow: -20px 28px 42px 0 rgba(62, 145, 255, 0.37); 178 | font-family: "iconfont" !important; 179 | font-style: normal; 180 | transition: .3s; 181 | -webkit-font-smoothing: antialiased; 182 | -moz-osx-font-smoothing: grayscale; 183 | } 184 | .content .right .form-wrappepr .other-login .divider { 185 | width: 100%; 186 | margin: 20px 0; 187 | text-align: center; 188 | display: flex; 189 | align-items: center; 190 | justify-content: space-between; 191 | } 192 | .content .right .form-wrappepr .other-login .divider .line { 193 | display: inline-block; 194 | max-width: 35%; 195 | width: 35%; 196 | flex: 1; 197 | height: 1px; 198 | background-color: rgb(162, 172, 185); 199 | } 200 | .content .right .form-wrappepr .other-login .divider .divider-text { 201 | vertical-align: middle; 202 | margin: 0px 20px; 203 | display: inline-block; 204 | width: 150px; 205 | color: rgb(162, 172, 185); 206 | white-space: normal; 207 | } 208 | .content .right .form-wrappepr .other-login .other-login-wrapper { 209 | width: 100%; 210 | display: flex; 211 | justify-content: center; 212 | align-items: center; 213 | } 214 | .content .right .form-wrappepr .other-login .other-login-wrapper .other-login-item { 215 | width: 70px; 216 | padding: 10px; 217 | text-align: center; 218 | border-radius: 10px; 219 | cursor: pointer; 220 | font-weight: 600; 221 | color: rgb(51, 49, 116); 222 | margin: 0 10px; 223 | transition: 0.4s; 224 | } 225 | .content .right .form-wrappepr .other-login .other-login-wrapper .other-login-item img { 226 | width: 40px; 227 | height: 40px; 228 | vertical-align: middle; 229 | } 230 | .content .right .form-wrappepr .other-login .other-login-wrapper .other-login-item span { 231 | vertical-align: middle; 232 | } 233 | .content .right .form-wrappepr .other-login .other-login-wrapper .other-login-item:hover { 234 | width: 80px; 235 | height: 50%; 236 | background-color: #fff; 237 | border: 0; 238 | box-shadow: -20px 10px 32px 1px rgba(182, 183, 185, 0.37); 239 | } 240 | 241 | @keyframes movement { 242 | 0%, 100% { 243 | background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax; 244 | background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax; 245 | } 246 | 25% { 247 | background-size: 100vmax 100vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 60vmax 60vmax; 248 | background-position: -60vmax -90vmax, 50vmax -40vmax, 0vmax -20vmax, -40vmax -20vmax, 40vmax 60vmax; 249 | } 250 | 50% { 251 | background-size: 80vmax 80vmax, 110vmax 110vmax, 80vmax 80vmax, 60vmax 60vmax, 80vmax 80vmax; 252 | background-position: -50vmax -70vmax, 40vmax -30vmax, 10vmax 0vmax, 20vmax 10vmax, 30vmax 70vmax; 253 | } 254 | 75% { 255 | background-size: 90vmax 90vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 70vmax 70vmax; 256 | background-position: -50vmax -40vmax, 50vmax -30vmax, 20vmax 0vmax, -10vmax 10vmax, 40vmax 60vmax; 257 | } 258 | } 259 | @keyframes sphereAnimation { 260 | 0% { 261 | width: 10%; 262 | } 263 | 100% { 264 | width: 90%; 265 | transform: translate(-30%, 5%); 266 | } 267 | } 268 | @keyframes peopleAnimation { 269 | 0% { 270 | width: 40%; 271 | } 272 | 100% { 273 | width: 70%; 274 | transform: translate(90%, -10%); 275 | } 276 | } 277 | @keyframes pOtherAnimation { 278 | 0% { 279 | transform: translate(90%, -10%); 280 | } 281 | 100% { 282 | transform: translate(90%, -15%); 283 | } 284 | } 285 | @keyframes sOtherAnimation { 286 | 0% { 287 | transform: translate(-30%, 5%); 288 | } 289 | 100% { 290 | transform: translate(-30%, 10%); 291 | } 292 | }/*# sourceMappingURL=style.css.map */ -------------------------------------------------------------------------------- /src/assets/css/style.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA;EACI,eAAA;ACCJ;;ADEA;EACI,SAAA;EACA,iBAAA;EACA,yBAAA;EACA,qYAAA;EAKA,8FAAA;EACA,mGAAA;EACA,4BAAA;EACA,uCAAA;ACHJ;;ADMA;EACI,WAAA;EACA,cAAA;EACA,eAAA;EACA,WAAA;EACA,YAAA;EACA,MAAA;EACA,OAAA;EACA,2BAAA;EACA,mCAAA;ACHJ;;ADMA;EACI,WAAA;EACA,YAAA;EACA,kBAAA;EACA,SAAA;EACA,QAAA;EACA,gCAAA;EACA,UAAA;EACA,mBAAA;EACA,oCAAA;EACA,2CAAA;EACA,aAAA;ACHJ;ADKI;EACI,OAAA;EACA,kBAAA;ACHR;ADIQ;EACI,kBAAA;EACA,SAAA;EACA,UAAA;EACA,UAAA;EACA,6BAAA;EACA,6BAAA;EACA,+BAAA;ACFZ;ADIQ;EACI,kBAAA;EACA,UAAA;EACA,QAAA;EACA,UAAA;EAEA,UAAA;ACHZ;ADKQ;EACI,6BAAA;EACA,6BAAA;EACA,+BAAA;ACHZ;ADKQ;EACI,+BAAA;EACA,8BAAA;EACA,iCAAA;EACA,mCAAA;EACA,sBAAA;ACHZ;ADKQ;EACI,6BAAA;EACA,6BAAA;EACA,+BAAA;ACHZ;ADKQ;EACI,+BAAA;EACA,8BAAA;EACA,iCAAA;EACA,mCAAA;EACA,sBAAA;ACHZ;ADMI;EACI,OAAA;EACA,kBAAA;EACA,WAAA;ACJR;ADKQ;EACI,UAAA;EACA,iBAAA;EACA,uBAAA;EACA,eAAA;EACA,gBAAA;EACA,2CAAA;EACA,kBAAA;EACA,SAAA;EACA,OAAA;EACA,6BAAA;ACHZ;ADIY;EACI,WAAA;EACA,YAAA;EACA,YAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,gBAAA;ACFhB;ADGgB;EACI,SAAA;EACA,sBAAA;EACA,mBAAA;EACA,eAAA;EACA,yDAAA;ACDpB;ADKQ;EACI,UAAA;EACA,kBAAA;EACA,SAAA;EACA,QAAA;EACA,gCAAA;EACA,iBAAA;ACHZ;ADIY;EACI,WAAA;EACA,2CAAA;EACA,cAAA;ACFhB;ADKY;EACI,cAAA;EACA,WAAA;EACA,YAAA;EACA,cAAA;EACA,mBAAA;EACA,SAAA;EACA,oCAAA;EACA,sBAAA;EACA,2CAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;EACA,eAAA;ACHhB;ADKY;EACI,cAAA;EACA,iBAAA;EACA,yBAAA;EACA,eAAA;ACHhB;ADKY;EACI,WAAA;EACA,YAAA;EACA,kCAAA;EACA,mBAAA;EACA,eAAA;EACA,WAAA;EACA,SAAA;EACA,gBAAA;EACA,cAAA;EACA,eAAA;EACA,sDAAA;EACA,2CAAA;ACHhB;ADMgB;EACI,WAAA;EACA,cAAA;EACA,kBAAA;EACA,aAAA;EACA,mBAAA;EACA,8BAAA;ACJpB;ADKoB;EACI,qBAAA;EACA,cAAA;EACA,UAAA;EACA,OAAA;EACA,WAAA;EACA,oCAAA;ACHxB;ADKoB;EACI,sBAAA;EACA,gBAAA;EAEA,qBAAA;EACA,YAAA;EACA,yBAAA;EACA,mBAAA;ACJxB;ADOgB;EACI,WAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;ACLpB;ADMoB;EACI,WAAA;EAEA,aAAA;EACA,kBAAA;EACA,mBAAA;EACA,eAAA;EACA,gBAAA;EACA,uBAAA;EACA,cAAA;EACA,gBAAA;ACLxB;ADMwB;EACI,WAAA;EACA,YAAA;EACA,sBAAA;ACJ5B;ADMwB;EACI,sBAAA;ACJ5B;ADOwB;EACI,WAAA;EACA,WAAA;EACA,sBAAA;EACA,SAAA;EACA,yDAAA;ACL5B;;ADcA;EACI;IAEI,8FAAA;IACA,mGAAA;ECZN;EDcE;IACI,8FAAA;IACA,mGAAA;ECZN;EDcE;IACI,4FAAA;IACA,gGAAA;ECZN;EDcE;IACI,4FAAA;IACA,iGAAA;ECZN;AACF;ADcA;EACI;IACI,UAAA;ECZN;EDcE;IACI,UAAA;IACA,8BAAA;ECZN;AACF;ADcA;EACI;IACI,UAAA;ECZN;EDcE;IACI,UAAA;IACA,+BAAA;ECZN;AACF;ADeA;EACI;IACI,+BAAA;ECbN;EDeE;IACI,+BAAA;ECbN;AACF;ADeA;EACI;IACI,8BAAA;ECbN;EDeE;IACI,+BAAA;ECbN;AACF","file":"style.css"} -------------------------------------------------------------------------------- /src/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | font-size: 15px; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | min-height: 100vh; 8 | background-color: #abc6f8; 9 | background-image: radial-gradient(closest-side, rgb(255, 255, 255), rgba(235, 105, 78, 0)), 10 | radial-gradient(closest-side, rgb(250, 203, 203), rgba(243, 11, 164, 0)), 11 | radial-gradient(closest-side, rgb(237, 252, 202), rgba(254, 234, 131, 0)), 12 | radial-gradient(closest-side, rgb(197, 248, 241), rgba(170, 142, 245, 0)), 13 | radial-gradient(closest-side, rgb(206, 200, 243), rgba(248, 192, 147, 0)); 14 | background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax; 15 | background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax; 16 | background-repeat: no-repeat; 17 | animation: 10s movement linear infinite; 18 | } 19 | 20 | body::after { 21 | content: ""; 22 | display: block; 23 | position: fixed; 24 | width: 100%; 25 | height: 100%; 26 | top: 0; 27 | left: 0; 28 | backdrop-filter: blur(10px); 29 | -webkit-backdrop-filter: blur(10px); 30 | } 31 | 32 | .content { 33 | width: 90vw; 34 | height: 90vh; 35 | position: absolute; 36 | left: 50%; 37 | top: 50%; 38 | transform: translate(-50%, -50%); 39 | z-index: 1; 40 | border-radius: 30px; 41 | background: rgba(255, 255, 255, 0.6); 42 | border: 1px solid rgba(255, 255, 255, 0.18); 43 | display: flex; 44 | // overflow: hidden; 45 | .left { 46 | flex: 1; 47 | position: relative; 48 | .sphere { 49 | position: absolute; 50 | left: 30%; 51 | width: 90%; 52 | z-index: 1; 53 | animation: sphereAnimation 2s; 54 | animation-fill-mode: forwards; 55 | animation-timing-function: ease; 56 | } 57 | .people { 58 | position: absolute; 59 | left: -50%; 60 | top: 20%; 61 | width: 70%; 62 | // height: 100px; 63 | z-index: 2; 64 | } 65 | .p-animtion { 66 | animation: peopleAnimation 2s; 67 | animation-fill-mode: forwards; 68 | animation-timing-function: ease; 69 | } 70 | .p-other-animtion { 71 | animation-name: pOtherAnimation; // 动画名称 72 | animation-direction: alternate; // 动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。 73 | animation-timing-function: linear; // 动画执行方式,linear:匀速;ease:先慢再快后慢;ease-in:由慢速开始;ease-out:由慢速结束;ease-in-out:由慢速开始和结束; 74 | animation-iteration-count: infinite; // 动画播放次数,infinite:一直播放 75 | animation-duration: 3s; // 动画完成时间 76 | } 77 | .s-animtion { 78 | animation: sphereAnimation 2s; 79 | animation-fill-mode: forwards; 80 | animation-timing-function: ease; 81 | } 82 | .s-other-animtion { 83 | animation-name: sOtherAnimation; // 动画名称 84 | animation-direction: alternate; // 动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。 85 | animation-timing-function: linear; // 动画执行方式,linear:匀速;ease:先慢再快后慢;ease-in:由慢速开始;ease-out:由慢速结束;ease-in-out:由慢速开始和结束; 86 | animation-iteration-count: infinite; // 动画播放次数,infinite:一直播放 87 | animation-duration: 3s; // 动画完成时间 88 | } 89 | } 90 | .right { 91 | flex: 1; 92 | position: relative; 93 | z-index: 12; 94 | .top { 95 | width: 80%; 96 | margin-left: 38px; 97 | color: rgb(51, 52, 124); 98 | font-size: 20px; 99 | font-weight: 600; 100 | font-family: "Century Gothic", Times, serif; 101 | position: absolute; 102 | left: 50%; 103 | top: 5%; 104 | transform: translate(-50%, 0); 105 | .top-item { 106 | float: left; 107 | width: 150px; 108 | height: 40px; 109 | line-height: 40px; 110 | text-align: center; 111 | margin-right: 10px; 112 | transition: 0.5s; 113 | &:hover { 114 | border: 0; 115 | background-color: #fff; 116 | border-radius: 50px; 117 | cursor: pointer; 118 | box-shadow: -20px 10px 32px 1px rgba(182, 183, 185, 0.37); 119 | } 120 | } 121 | } 122 | .form-wrappepr { 123 | width: 60%; 124 | position: absolute; 125 | left: 50%; 126 | top: 50%; 127 | transform: translate(-50%, -50%); 128 | text-align: right; 129 | h1 { 130 | float: left; 131 | font-family: "Century Gothic", Times, serif; 132 | margin: 30px 0; 133 | // color: rgb(68,96,241); 134 | } 135 | .inputs { 136 | display: block; 137 | width: 100%; 138 | height: 70px; 139 | margin: 30px 0; 140 | border-radius: 10px; 141 | border: 0; 142 | background-color: rgb(210 223 237); 143 | color: rgb(80, 82, 84); 144 | font-family: "Century Gothic", Times, serif; 145 | outline: none; 146 | padding: 20px; 147 | box-sizing: border-box; 148 | font-size: 20px; 149 | } 150 | .tips { 151 | display: block; 152 | margin-top: -15px; 153 | color: rgb(160, 170, 182); 154 | cursor: pointer; 155 | } 156 | button { 157 | width: 100%; 158 | height: 50px; 159 | background-color: rgb(68, 96, 241); 160 | border-radius: 10px; 161 | font-size: 15px; 162 | color: #fff; 163 | border: 0; 164 | font-weight: 600; 165 | margin: 30px 0; 166 | cursor: pointer; 167 | box-shadow: -20px 28px 42px 0 rgba(62, 145, 255, 0.37); 168 | font-family: "Century Gothic", Times, serif; 169 | } 170 | .other-login { 171 | .divider { 172 | width: 100%; 173 | margin: 20px 0; 174 | text-align: center; 175 | display: flex; 176 | align-items: center; 177 | justify-content: space-between; 178 | .line { 179 | display: inline-block; 180 | max-width: 35%; 181 | width: 35%; 182 | flex: 1; 183 | height: 1px; 184 | background-color: rgb(162, 172, 185); 185 | } 186 | .divider-text { 187 | vertical-align: middle; 188 | margin: 0px 20px; 189 | // line-height: 0px; 190 | display: inline-block; 191 | width: 150px; 192 | color: rgb(162, 172, 185); 193 | white-space: normal; 194 | } 195 | } 196 | .other-login-wrapper { 197 | width: 100%; 198 | display: flex; 199 | justify-content: center; 200 | align-items: center; 201 | .other-login-item { 202 | width: 70px; 203 | // border: 1px solid rgb(162, 172, 185); 204 | padding: 10px; 205 | text-align: center; 206 | border-radius: 10px; 207 | cursor: pointer; 208 | font-weight: 600; 209 | color: rgb(51, 49, 116); 210 | margin: 0 10px; 211 | transition: 0.4s; 212 | img { 213 | width: 40px; 214 | height: 40px; 215 | vertical-align: middle; 216 | } 217 | span { 218 | vertical-align: middle; 219 | } 220 | 221 | &:hover { 222 | width: 80px; 223 | height: 50%; 224 | background-color: #fff; 225 | border: 0; 226 | box-shadow: -20px 10px 32px 1px rgba(182, 183, 185, 0.37); 227 | } 228 | } 229 | } 230 | } 231 | } 232 | } 233 | } 234 | 235 | @keyframes movement { 236 | 0%, 237 | 100% { 238 | background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax; 239 | background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax; 240 | } 241 | 25% { 242 | background-size: 100vmax 100vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 60vmax 60vmax; 243 | background-position: -60vmax -90vmax, 50vmax -40vmax, 0vmax -20vmax, -40vmax -20vmax, 40vmax 60vmax; 244 | } 245 | 50% { 246 | background-size: 80vmax 80vmax, 110vmax 110vmax, 80vmax 80vmax, 60vmax 60vmax, 80vmax 80vmax; 247 | background-position: -50vmax -70vmax, 40vmax -30vmax, 10vmax 0vmax, 20vmax 10vmax, 30vmax 70vmax; 248 | } 249 | 75% { 250 | background-size: 90vmax 90vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 70vmax 70vmax; 251 | background-position: -50vmax -40vmax, 50vmax -30vmax, 20vmax 0vmax, -10vmax 10vmax, 40vmax 60vmax; 252 | } 253 | } 254 | @keyframes sphereAnimation { 255 | 0% { 256 | width: 10%; 257 | } 258 | 100% { 259 | width: 90%; 260 | transform: translate(-30%, 5%); 261 | } 262 | } 263 | @keyframes peopleAnimation { 264 | 0% { 265 | width: 40%; 266 | } 267 | 100% { 268 | width: 70%; 269 | transform: translate(90%, -10%); 270 | } 271 | } 272 | 273 | @keyframes pOtherAnimation { 274 | 0% { 275 | transform: translate(90%, -10%); 276 | } 277 | 100% { 278 | transform: translate(90%, -15%); 279 | } 280 | } 281 | @keyframes sOtherAnimation { 282 | 0% { 283 | transform: translate(-30%, 5%); 284 | } 285 | 100% { 286 | transform: translate(-30%, 10%); 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /src/assets/font/demo.css: -------------------------------------------------------------------------------- 1 | /* Logo 字体 */ 2 | @font-face { 3 | font-family: "iconfont logo"; 4 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); 5 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), 6 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), 7 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), 8 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); 9 | } 10 | 11 | .logo { 12 | font-family: "iconfont logo"; 13 | font-size: 160px; 14 | font-style: normal; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | /* tabs */ 20 | .nav-tabs { 21 | position: relative; 22 | } 23 | 24 | .nav-tabs .nav-more { 25 | position: absolute; 26 | right: 0; 27 | bottom: 0; 28 | height: 42px; 29 | line-height: 42px; 30 | color: #666; 31 | } 32 | 33 | #tabs { 34 | border-bottom: 1px solid #eee; 35 | } 36 | 37 | #tabs li { 38 | cursor: pointer; 39 | width: 100px; 40 | height: 40px; 41 | line-height: 40px; 42 | text-align: center; 43 | font-size: 16px; 44 | border-bottom: 2px solid transparent; 45 | position: relative; 46 | z-index: 1; 47 | margin-bottom: -1px; 48 | color: #666; 49 | } 50 | 51 | 52 | #tabs .active { 53 | border-bottom-color: #f00; 54 | color: #222; 55 | } 56 | 57 | .tab-container .content { 58 | display: none; 59 | } 60 | 61 | /* 页面布局 */ 62 | .main { 63 | padding: 30px 100px; 64 | width: 960px; 65 | margin: 0 auto; 66 | } 67 | 68 | .main .logo { 69 | color: #333; 70 | text-align: left; 71 | margin-bottom: 30px; 72 | line-height: 1; 73 | height: 110px; 74 | margin-top: -50px; 75 | overflow: hidden; 76 | *zoom: 1; 77 | } 78 | 79 | .main .logo a { 80 | font-size: 160px; 81 | color: #333; 82 | } 83 | 84 | .helps { 85 | margin-top: 40px; 86 | } 87 | 88 | .helps pre { 89 | padding: 20px; 90 | margin: 10px 0; 91 | border: solid 1px #e7e1cd; 92 | background-color: #fffdef; 93 | overflow: auto; 94 | } 95 | 96 | .icon_lists { 97 | width: 100% !important; 98 | overflow: hidden; 99 | *zoom: 1; 100 | } 101 | 102 | .icon_lists li { 103 | width: 100px; 104 | margin-bottom: 10px; 105 | margin-right: 20px; 106 | text-align: center; 107 | list-style: none !important; 108 | cursor: default; 109 | } 110 | 111 | .icon_lists li .code-name { 112 | line-height: 1.2; 113 | } 114 | 115 | .icon_lists .icon { 116 | display: block; 117 | height: 100px; 118 | line-height: 100px; 119 | font-size: 42px; 120 | margin: 10px auto; 121 | color: #333; 122 | -webkit-transition: font-size 0.25s linear, width 0.25s linear; 123 | -moz-transition: font-size 0.25s linear, width 0.25s linear; 124 | transition: font-size 0.25s linear, width 0.25s linear; 125 | } 126 | 127 | .icon_lists .icon:hover { 128 | font-size: 100px; 129 | } 130 | 131 | .icon_lists .svg-icon { 132 | /* 通过设置 font-size 来改变图标大小 */ 133 | width: 1em; 134 | /* 图标和文字相邻时,垂直对齐 */ 135 | vertical-align: -0.15em; 136 | /* 通过设置 color 来改变 SVG 的颜色/fill */ 137 | fill: currentColor; 138 | /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 139 | normalize.css 中也包含这行 */ 140 | overflow: hidden; 141 | } 142 | 143 | .icon_lists li .name, 144 | .icon_lists li .code-name { 145 | color: #666; 146 | } 147 | 148 | /* markdown 样式 */ 149 | .markdown { 150 | color: #666; 151 | font-size: 14px; 152 | line-height: 1.8; 153 | } 154 | 155 | .highlight { 156 | line-height: 1.5; 157 | } 158 | 159 | .markdown img { 160 | vertical-align: middle; 161 | max-width: 100%; 162 | } 163 | 164 | .markdown h1 { 165 | color: #404040; 166 | font-weight: 500; 167 | line-height: 40px; 168 | margin-bottom: 24px; 169 | } 170 | 171 | .markdown h2, 172 | .markdown h3, 173 | .markdown h4, 174 | .markdown h5, 175 | .markdown h6 { 176 | color: #404040; 177 | margin: 1.6em 0 0.6em 0; 178 | font-weight: 500; 179 | clear: both; 180 | } 181 | 182 | .markdown h1 { 183 | font-size: 28px; 184 | } 185 | 186 | .markdown h2 { 187 | font-size: 22px; 188 | } 189 | 190 | .markdown h3 { 191 | font-size: 16px; 192 | } 193 | 194 | .markdown h4 { 195 | font-size: 14px; 196 | } 197 | 198 | .markdown h5 { 199 | font-size: 12px; 200 | } 201 | 202 | .markdown h6 { 203 | font-size: 12px; 204 | } 205 | 206 | .markdown hr { 207 | height: 1px; 208 | border: 0; 209 | background: #e9e9e9; 210 | margin: 16px 0; 211 | clear: both; 212 | } 213 | 214 | .markdown p { 215 | margin: 1em 0; 216 | } 217 | 218 | .markdown>p, 219 | .markdown>blockquote, 220 | .markdown>.highlight, 221 | .markdown>ol, 222 | .markdown>ul { 223 | width: 80%; 224 | } 225 | 226 | .markdown ul>li { 227 | list-style: circle; 228 | } 229 | 230 | .markdown>ul li, 231 | .markdown blockquote ul>li { 232 | margin-left: 20px; 233 | padding-left: 4px; 234 | } 235 | 236 | .markdown>ul li p, 237 | .markdown>ol li p { 238 | margin: 0.6em 0; 239 | } 240 | 241 | .markdown ol>li { 242 | list-style: decimal; 243 | } 244 | 245 | .markdown>ol li, 246 | .markdown blockquote ol>li { 247 | margin-left: 20px; 248 | padding-left: 4px; 249 | } 250 | 251 | .markdown code { 252 | margin: 0 3px; 253 | padding: 0 5px; 254 | background: #eee; 255 | border-radius: 3px; 256 | } 257 | 258 | .markdown strong, 259 | .markdown b { 260 | font-weight: 600; 261 | } 262 | 263 | .markdown>table { 264 | border-collapse: collapse; 265 | border-spacing: 0px; 266 | empty-cells: show; 267 | border: 1px solid #e9e9e9; 268 | width: 95%; 269 | margin-bottom: 24px; 270 | } 271 | 272 | .markdown>table th { 273 | white-space: nowrap; 274 | color: #333; 275 | font-weight: 600; 276 | } 277 | 278 | .markdown>table th, 279 | .markdown>table td { 280 | border: 1px solid #e9e9e9; 281 | padding: 8px 16px; 282 | text-align: left; 283 | } 284 | 285 | .markdown>table th { 286 | background: #F7F7F7; 287 | } 288 | 289 | .markdown blockquote { 290 | font-size: 90%; 291 | color: #999; 292 | border-left: 4px solid #e9e9e9; 293 | padding-left: 0.8em; 294 | margin: 1em 0; 295 | } 296 | 297 | .markdown blockquote p { 298 | margin: 0; 299 | } 300 | 301 | .markdown .anchor { 302 | opacity: 0; 303 | transition: opacity 0.3s ease; 304 | margin-left: 8px; 305 | } 306 | 307 | .markdown .waiting { 308 | color: #ccc; 309 | } 310 | 311 | .markdown h1:hover .anchor, 312 | .markdown h2:hover .anchor, 313 | .markdown h3:hover .anchor, 314 | .markdown h4:hover .anchor, 315 | .markdown h5:hover .anchor, 316 | .markdown h6:hover .anchor { 317 | opacity: 1; 318 | display: inline-block; 319 | } 320 | 321 | .markdown>br, 322 | .markdown>p>br { 323 | clear: both; 324 | } 325 | 326 | 327 | .hljs { 328 | display: block; 329 | background: white; 330 | padding: 0.5em; 331 | color: #333333; 332 | overflow-x: auto; 333 | } 334 | 335 | .hljs-comment, 336 | .hljs-meta { 337 | color: #969896; 338 | } 339 | 340 | .hljs-string, 341 | .hljs-variable, 342 | .hljs-template-variable, 343 | .hljs-strong, 344 | .hljs-emphasis, 345 | .hljs-quote { 346 | color: #df5000; 347 | } 348 | 349 | .hljs-keyword, 350 | .hljs-selector-tag, 351 | .hljs-type { 352 | color: #a71d5d; 353 | } 354 | 355 | .hljs-literal, 356 | .hljs-symbol, 357 | .hljs-bullet, 358 | .hljs-attribute { 359 | color: #0086b3; 360 | } 361 | 362 | .hljs-section, 363 | .hljs-name { 364 | color: #63a35c; 365 | } 366 | 367 | .hljs-tag { 368 | color: #333333; 369 | } 370 | 371 | .hljs-title, 372 | .hljs-attr, 373 | .hljs-selector-id, 374 | .hljs-selector-class, 375 | .hljs-selector-attr, 376 | .hljs-selector-pseudo { 377 | color: #795da3; 378 | } 379 | 380 | .hljs-addition { 381 | color: #55a532; 382 | background-color: #eaffea; 383 | } 384 | 385 | .hljs-deletion { 386 | color: #bd2c00; 387 | background-color: #ffecec; 388 | } 389 | 390 | .hljs-link { 391 | text-decoration: underline; 392 | } 393 | 394 | /* 代码高亮 */ 395 | /* PrismJS 1.15.0 396 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ 397 | /** 398 | * prism.js default theme for JavaScript, CSS and HTML 399 | * Based on dabblet (http://dabblet.com) 400 | * @author Lea Verou 401 | */ 402 | code[class*="language-"], 403 | pre[class*="language-"] { 404 | color: black; 405 | background: none; 406 | text-shadow: 0 1px white; 407 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 408 | text-align: left; 409 | white-space: pre; 410 | word-spacing: normal; 411 | word-break: normal; 412 | word-wrap: normal; 413 | line-height: 1.5; 414 | 415 | -moz-tab-size: 4; 416 | -o-tab-size: 4; 417 | tab-size: 4; 418 | 419 | -webkit-hyphens: none; 420 | -moz-hyphens: none; 421 | -ms-hyphens: none; 422 | hyphens: none; 423 | } 424 | 425 | pre[class*="language-"]::-moz-selection, 426 | pre[class*="language-"] ::-moz-selection, 427 | code[class*="language-"]::-moz-selection, 428 | code[class*="language-"] ::-moz-selection { 429 | text-shadow: none; 430 | background: #b3d4fc; 431 | } 432 | 433 | pre[class*="language-"]::selection, 434 | pre[class*="language-"] ::selection, 435 | code[class*="language-"]::selection, 436 | code[class*="language-"] ::selection { 437 | text-shadow: none; 438 | background: #b3d4fc; 439 | } 440 | 441 | @media print { 442 | 443 | code[class*="language-"], 444 | pre[class*="language-"] { 445 | text-shadow: none; 446 | } 447 | } 448 | 449 | /* Code blocks */ 450 | pre[class*="language-"] { 451 | padding: 1em; 452 | margin: .5em 0; 453 | overflow: auto; 454 | } 455 | 456 | :not(pre)>code[class*="language-"], 457 | pre[class*="language-"] { 458 | background: #f5f2f0; 459 | } 460 | 461 | /* Inline code */ 462 | :not(pre)>code[class*="language-"] { 463 | padding: .1em; 464 | border-radius: .3em; 465 | white-space: normal; 466 | } 467 | 468 | .token.comment, 469 | .token.prolog, 470 | .token.doctype, 471 | .token.cdata { 472 | color: slategray; 473 | } 474 | 475 | .token.punctuation { 476 | color: #999; 477 | } 478 | 479 | .namespace { 480 | opacity: .7; 481 | } 482 | 483 | .token.property, 484 | .token.tag, 485 | .token.boolean, 486 | .token.number, 487 | .token.constant, 488 | .token.symbol, 489 | .token.deleted { 490 | color: #905; 491 | } 492 | 493 | .token.selector, 494 | .token.attr-name, 495 | .token.string, 496 | .token.char, 497 | .token.builtin, 498 | .token.inserted { 499 | color: #690; 500 | } 501 | 502 | .token.operator, 503 | .token.entity, 504 | .token.url, 505 | .language-css .token.string, 506 | .style .token.string { 507 | color: #9a6e3a; 508 | background: hsla(0, 0%, 100%, .5); 509 | } 510 | 511 | .token.atrule, 512 | .token.attr-value, 513 | .token.keyword { 514 | color: #07a; 515 | } 516 | 517 | .token.function, 518 | .token.class-name { 519 | color: #DD4A68; 520 | } 521 | 522 | .token.regex, 523 | .token.important, 524 | .token.variable { 525 | color: #e90; 526 | } 527 | 528 | .token.important, 529 | .token.bold { 530 | font-weight: bold; 531 | } 532 | 533 | .token.italic { 534 | font-style: italic; 535 | } 536 | 537 | .token.entity { 538 | cursor: help; 539 | } 540 | -------------------------------------------------------------------------------- /src/assets/font/font.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'SSFY'; 3 | src: url('阿里妈妈东方大楷_Regular.ttf'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } -------------------------------------------------------------------------------- /src/assets/font/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; /* Project id 3996937 */ 3 | src: url('iconfont.woff2?t=1681088355288') format('woff2'), 4 | url('iconfont.woff?t=1681088355288') format('woff'), 5 | url('iconfont.ttf?t=1681088355288') format('truetype'); 6 | } 7 | 8 | .iconfont { 9 | font-family: "iconfont" !important; 10 | font-size: 16px; 11 | font-style: normal; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | .icon-shanchu:before { 17 | content: "\e630"; 18 | } 19 | 20 | .icon-iconyuanbanben_fanyi:before { 21 | content: "\e6b6"; 22 | } 23 | 24 | .icon-wenben:before { 25 | content: "\e600"; 26 | } 27 | 28 | .icon-luyin:before { 29 | content: "\e740"; 30 | } 31 | 32 | .icon-tupian:before { 33 | content: "\e623"; 34 | } 35 | 36 | .icon-luyin1:before { 37 | content: "\e602"; 38 | } 39 | 40 | .icon-shezhi:before { 41 | content: "\e8b8"; 42 | } 43 | 44 | .icon-qingchu:before { 45 | content: "\e609"; 46 | } 47 | 48 | .icon-xinxi:before { 49 | content: "\e624"; 50 | } 51 | 52 | .icon-weidenglu:before { 53 | content: "\e6a3"; 54 | } 55 | 56 | .icon-daoru:before { 57 | content: "\e645"; 58 | } 59 | 60 | .icon-daochu:before { 61 | content: "\e646"; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.js: -------------------------------------------------------------------------------- 1 | window._iconfont_svg_string_3996937='',function(l){var c=(c=document.getElementsByTagName("script"))[c.length-1],t=c.getAttribute("data-injectcss"),c=c.getAttribute("data-disable-injectsvg");if(!c){var i,e,o,a,n,h=function(c,t){t.parentNode.insertBefore(c,t)};if(t&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}i=function(){var c,t=document.createElement("div");t.innerHTML=l._iconfont_svg_string_3996937,(t=t.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",t=t,(c=document.body).firstChild?h(t,c.firstChild):c.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(i,0):(e=function(){document.removeEventListener("DOMContentLoaded",e,!1),i()},document.addEventListener("DOMContentLoaded",e,!1)):document.attachEvent&&(o=i,a=l.document,n=!1,s(),a.onreadystatechange=function(){"complete"==a.readyState&&(a.onreadystatechange=null,d())})}function d(){n||(n=!0,o())}function s(){try{a.documentElement.doScroll("left")}catch(c){return void setTimeout(s,50)}d()}}(window); -------------------------------------------------------------------------------- /src/assets/font/iconfont.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "3996937", 3 | "name": "openai", 4 | "font_family": "iconfont", 5 | "css_prefix_text": "icon-", 6 | "description": "", 7 | "glyphs": [ 8 | { 9 | "icon_id": "1346663", 10 | "name": "删除", 11 | "font_class": "shanchu", 12 | "unicode": "e630", 13 | "unicode_decimal": 58928 14 | }, 15 | { 16 | "icon_id": "12791171", 17 | "name": "翻译", 18 | "font_class": "iconyuanbanben_fanyi", 19 | "unicode": "e6b6", 20 | "unicode_decimal": 59062 21 | }, 22 | { 23 | "icon_id": "1233", 24 | "name": "文本", 25 | "font_class": "wenben", 26 | "unicode": "e600", 27 | "unicode_decimal": 58880 28 | }, 29 | { 30 | "icon_id": "4933359", 31 | "name": "录音", 32 | "font_class": "luyin", 33 | "unicode": "e740", 34 | "unicode_decimal": 59200 35 | }, 36 | { 37 | "icon_id": "7588121", 38 | "name": "图片", 39 | "font_class": "tupian", 40 | "unicode": "e623", 41 | "unicode_decimal": 58915 42 | }, 43 | { 44 | "icon_id": "13644711", 45 | "name": "录音", 46 | "font_class": "luyin1", 47 | "unicode": "e602", 48 | "unicode_decimal": 58882 49 | }, 50 | { 51 | "icon_id": "1727422", 52 | "name": "205设置", 53 | "font_class": "shezhi", 54 | "unicode": "e8b8", 55 | "unicode_decimal": 59576 56 | }, 57 | { 58 | "icon_id": "4329214", 59 | "name": "清除", 60 | "font_class": "qingchu", 61 | "unicode": "e609", 62 | "unicode_decimal": 58889 63 | }, 64 | { 65 | "icon_id": "7588125", 66 | "name": "信息", 67 | "font_class": "xinxi", 68 | "unicode": "e624", 69 | "unicode_decimal": 58916 70 | }, 71 | { 72 | "icon_id": "7960199", 73 | "name": "未登录", 74 | "font_class": "weidenglu", 75 | "unicode": "e6a3", 76 | "unicode_decimal": 59043 77 | }, 78 | { 79 | "icon_id": "8094179", 80 | "name": "导入", 81 | "font_class": "daoru", 82 | "unicode": "e645", 83 | "unicode_decimal": 58949 84 | }, 85 | { 86 | "icon_id": "8094181", 87 | "name": "导出", 88 | "font_class": "daochu", 89 | "unicode": "e646", 90 | "unicode_decimal": 58950 91 | } 92 | ] 93 | } 94 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/font/iconfont.ttf -------------------------------------------------------------------------------- /src/assets/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/font/iconfont.woff -------------------------------------------------------------------------------- /src/assets/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/font/iconfont.woff2 -------------------------------------------------------------------------------- /src/assets/font/阿里妈妈东方大楷_Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/font/阿里妈妈东方大楷_Regular.ttf -------------------------------------------------------------------------------- /src/assets/img/ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/ai.png -------------------------------------------------------------------------------- /src/assets/img/bj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/bj.png -------------------------------------------------------------------------------- /src/assets/img/emoji/clown-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/clown-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/face-screaming-in-fear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/face-screaming-in-fear.png -------------------------------------------------------------------------------- /src/assets/img/emoji/face-vomiting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/face-vomiting.png -------------------------------------------------------------------------------- /src/assets/img/emoji/face-with-tongue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/face-with-tongue.png -------------------------------------------------------------------------------- /src/assets/img/emoji/face-without-mouth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/face-without-mouth.png -------------------------------------------------------------------------------- /src/assets/img/emoji/ghost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/ghost.png -------------------------------------------------------------------------------- /src/assets/img/emoji/hibiscus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/hibiscus.png -------------------------------------------------------------------------------- /src/assets/img/emoji/jack-o-lantern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/jack-o-lantern.png -------------------------------------------------------------------------------- /src/assets/img/emoji/lips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/lips.png -------------------------------------------------------------------------------- /src/assets/img/emoji/loudly-crying-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/loudly-crying-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/money-bag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/money-bag.png -------------------------------------------------------------------------------- /src/assets/img/emoji/money-mouth-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/money-mouth-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/new-moon-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/new-moon-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/ok-hand-yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/ok-hand-yellow.png -------------------------------------------------------------------------------- /src/assets/img/emoji/pile-of-poo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/pile-of-poo.png -------------------------------------------------------------------------------- /src/assets/img/emoji/pouting-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/pouting-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/rainbow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/rainbow.png -------------------------------------------------------------------------------- /src/assets/img/emoji/rocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/rocket.png -------------------------------------------------------------------------------- /src/assets/img/emoji/shamrock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/shamrock.png -------------------------------------------------------------------------------- /src/assets/img/emoji/slightly-smiling-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/slightly-smiling-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/smiling-face-with-heart-eyes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/smiling-face-with-heart-eyes.png -------------------------------------------------------------------------------- /src/assets/img/emoji/smiling-face-with-horns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/smiling-face-with-horns.png -------------------------------------------------------------------------------- /src/assets/img/emoji/smiling-face-with-sunglasses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/smiling-face-with-sunglasses.png -------------------------------------------------------------------------------- /src/assets/img/emoji/smiling-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/smiling-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/sparkles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/sparkles.png -------------------------------------------------------------------------------- /src/assets/img/emoji/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/star.png -------------------------------------------------------------------------------- /src/assets/img/emoji/thinking-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/thinking-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/thought-balloon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/thought-balloon.png -------------------------------------------------------------------------------- /src/assets/img/emoji/thumbs-up-yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/thumbs-up-yellow.png -------------------------------------------------------------------------------- /src/assets/img/emoji/tired-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/tired-face.png -------------------------------------------------------------------------------- /src/assets/img/emoji/two-hearts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/two-hearts.png -------------------------------------------------------------------------------- /src/assets/img/emoji/victory-hand-yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/emoji/victory-hand-yellow.png -------------------------------------------------------------------------------- /src/assets/img/fileImg/excel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/fileImg/excel.png -------------------------------------------------------------------------------- /src/assets/img/fileImg/pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/fileImg/pdf.png -------------------------------------------------------------------------------- /src/assets/img/fileImg/ppt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/fileImg/ppt.png -------------------------------------------------------------------------------- /src/assets/img/fileImg/txt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/fileImg/txt.png -------------------------------------------------------------------------------- /src/assets/img/fileImg/unknowfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/fileImg/unknowfile.png -------------------------------------------------------------------------------- /src/assets/img/fileImg/word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/fileImg/word.png -------------------------------------------------------------------------------- /src/assets/img/fileImg/zpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/fileImg/zpi.png -------------------------------------------------------------------------------- /src/assets/img/head.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/head.jpg -------------------------------------------------------------------------------- /src/assets/img/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/img1.png -------------------------------------------------------------------------------- /src/assets/img/img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/img2.png -------------------------------------------------------------------------------- /src/assets/img/shuaxin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/shuaxin.png -------------------------------------------------------------------------------- /src/assets/img/snapchat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/img/snapchat.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/202252197/ChatGPT_JCM/75aa5db35880d9068cfc84836d238b8b0686a3c6/src/assets/logo.png -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | const { app, BrowserWindow,globalShortcut,ipcMain,screen,protocol } = require('electron') 2 | import path from "path"; 3 | 4 | let mainWindow 5 | function createWindow() { 6 | mainWindow = new BrowserWindow({ 7 | width: 1000, 8 | height: 800, 9 | frame: false, 10 | webPreferences: { 11 | nodeIntegration: true, 12 | enableRemoteModule: true, 13 | contextIsolation: false, 14 | webSecurity: false, 15 | }, 16 | menu: null 17 | }) 18 | mainWindow.loadURL(process.env.IS_ELECTRON?'http://localhost:8080':`file://${__dirname}/index.html`) 19 | mainWindow.on('closed', function() { 20 | mainWindow = null 21 | }) 22 | 23 | // 注册快捷键 24 | // 打开 DevTools 工具 25 | globalShortcut.register('Ctrl+Shift+Alt+I', () => { 26 | mainWindow.webContents.openDevTools() 27 | }) 28 | // 退出app 29 | globalShortcut.register('esc', () => { 30 | app.quit() 31 | }) 32 | 33 | // 打开dev工具 34 | mainWindow.webContents.openDevTools() 35 | 36 | windowMove(mainWindow); 37 | } 38 | 39 | /** 40 | * 窗口移动 41 | * @param win 42 | */ 43 | function windowMove(win) { 44 | 45 | let winStartPosition = {x: 0, y: 0}; 46 | let mouseStartPosition = {x: 0, y: 0}; 47 | let movingInterval = null; 48 | 49 | /** 50 | * 窗口移动事件 51 | */ 52 | ipcMain.on("window-move-open", (events, canMoving) => { 53 | if (canMoving) { 54 | // 读取原位置 55 | const winPosition = win.getPosition(); 56 | winStartPosition = { x: winPosition[0], y: winPosition[1] }; 57 | mouseStartPosition = screen.getCursorScreenPoint(); 58 | // 清除 59 | if (movingInterval) { 60 | clearInterval(movingInterval); 61 | } 62 | // 新开 63 | movingInterval = setInterval(() => { 64 | // 实时更新位置 65 | const cursorPosition = screen.getCursorScreenPoint(); 66 | const x = winStartPosition.x + cursorPosition.x - mouseStartPosition.x; 67 | const y = winStartPosition.y + cursorPosition.y - mouseStartPosition.y; 68 | win.setPosition(x, y, true); 69 | }, 20); 70 | } else { 71 | clearInterval(movingInterval); 72 | movingInterval = null; 73 | } 74 | }); 75 | 76 | } 77 | 78 | app.on('ready', ()=>{ 79 | createWindow(); 80 | }) 81 | 82 | app.on('window-all-closed', function() { 83 | if (process.platform !== 'darwin') { 84 | app.quit() 85 | } 86 | }) 87 | 88 | app.on('will-quit', () => { 89 | globalShortcut.unregisterAll() 90 | }) 91 | 92 | app.on('activate', function() { 93 | if (mainWindow === null) { 94 | createWindow() 95 | } 96 | }) 97 | -------------------------------------------------------------------------------- /src/components/Emoji.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 66 | 67 | 157 | -------------------------------------------------------------------------------- /src/components/File.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 51 | 52 | 118 | -------------------------------------------------------------------------------- /src/components/FileCard.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 40 | 41 | -------------------------------------------------------------------------------- /src/components/HeadImg.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 18 | 19 | 55 | 56 | -------------------------------------------------------------------------------- /src/components/HeadPortrait.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | -------------------------------------------------------------------------------- /src/components/Nav.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 71 | 72 | -------------------------------------------------------------------------------- /src/components/PersonCard.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 45 | 46 | 112 | -------------------------------------------------------------------------------- /src/components/RoleCard.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 44 | 45 | 111 | -------------------------------------------------------------------------------- /src/components/Session.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 48 | 49 | -------------------------------------------------------------------------------- /src/config/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | // 引入i18n插件 3 | import VueI18n from "vue-i18n"; 4 | // 引入语言包 5 | import enLocale from "@/lang/en"; 6 | import zhLocale from "@/lang/zh-CN"; 7 | // 引入element-ui语言包 8 | import elementEn from 'element-ui/lib/locale/lang/en' 9 | import elementZh from 'element-ui/lib/locale/lang/zh-CN' 10 | // 下面不可少的两个配置【参考官网 按需加载里定制 i18n】 11 | import ElementLocale from 'element-ui/lib/locale' 12 | ElementLocale.i18n((key, value) => i18n.t(key, value)) 13 | 14 | Vue.use(VueI18n); 15 | 16 | const messages = { 17 | en: { 18 | ...enLocale, 19 | ...elementEn // element-ui语言包 20 | }, 21 | zh: { 22 | ...zhLocale, 23 | ...elementZh 24 | }, 25 | }; 26 | 27 | // 配置i18n 28 | const i18n = new VueI18n({ 29 | locale: localStorage.getItem("lang") || "zh", // 从缓存中获取当前的语言类型 30 | messages, 31 | }); 32 | 33 | export default i18n; 34 | -------------------------------------------------------------------------------- /src/lang/en.js: -------------------------------------------------------------------------------- 1 | export default { 2 | placeholder: { 3 | question: "Enter your question here~", 4 | openai_key: "Please enter OpenAI KEY", 5 | role_name: "role name", 6 | session_name: "session name", 7 | model_name: "model name", 8 | slightly_name: "fine-tuned model name", 9 | file_name: "file name", 10 | suffix: "Text snippet to add at the end.", 11 | stop: "Token to stop generating text.", 12 | response_count: "Number of Answers Generated", 13 | trainingDataFileID: 'ID of training data file', 14 | validationDataFileID: 'ID of validation data file', 15 | modelName: 'Model name', 16 | trainingIterations: 'Number of training iterations', 17 | batchSize: 'Batch size', 18 | learningRate: 'Learning rate', 19 | ftsuffix: 'Suffix', 20 | }, 21 | session: { 22 | title: "session", 23 | create: "create session", 24 | export: "Export the session list", 25 | import: "Import the session list", 26 | clear: "Clear the session list" 27 | }, 28 | model: { 29 | title: "model", 30 | talk: "chat", 31 | online_title: "online", 32 | online: "Online query after opening", 33 | suffix_title: "suffix", 34 | suffix: "A text snippet to add at the end of the generated text", 35 | max_tokens_title: "Maximum word count", 36 | max_tokens: "Specifies the maximum number of words to generate, which cannot exceed 2048.", 37 | temperature_title: "Randomness(0-2)", 38 | temperature: "Specifies the randomness of the generated text, ranging from 0 to 2, where higher values are more diverse and creative, and lower values are more conservative and deterministic.", 39 | top_p_title: "Reserved word ratio(0-1)", 40 | top_p: "Specifies the proportion of words with the highest probability of being retained at each step, ranging from 0 to 1, similar to temperature, but more flexible and robust.", 41 | n_title: "Result count", 42 | n: "This parameter produces many results", 43 | stream_title: "Stream output", 44 | stream: "Enable streaming output", 45 | echo_title: "Echo words", 46 | echo: "echo prompt word", 47 | stop_title: "Stop token", 48 | stop: "Sets the token at which the model stops generating text", 49 | frequency_penalty_title: "Word repetition(0-1)", 50 | frequency_penalty: "Specify the degree to reduce the probability of repeated words, the range is 0 to 1, the higher the more to avoid repetition.", 51 | presence_penalty_title: "Topic repetition(0-1)", 52 | presence_penalty: "Specify the degree to reduce the occurrence probability of repeated topics, ranging from 0 to 1, the higher means avoiding repetition.", 53 | max_results_title: "Specify the amount of online query data, it is not recommended to be too large.", 54 | max_results: "max_results" 55 | }, 56 | slightly: { 57 | title: { 58 | whole: "FT", 59 | abbreviation: "FT" 60 | }, 61 | retrieveFineTuning: 'Retrieve fine-tuning', 62 | cancelFineTuning: 'Cancel fine-tuning', 63 | hideCanceledFineTuning: 'Hide canceled fine-tuning', 64 | showCanceledFineTuning: 'Show canceled fine-tuning', 65 | deleteFineTuningModel: 'Delete fine-tuning model', 66 | createFineTuning: 'Create fine-tuning', 67 | create: 'Create', 68 | fileIDTrainingData: 'File ID containing training data', 69 | fileIDValidationData: 'File ID containing validation data', 70 | modelOptions: 'You can choose the model name from ada, babbage, curie, davinci, or the name of your own fine-tuned model.', 71 | epochs: 'By adjusting the number of n_epochs, you can control the training period and number of training times of the model, thereby affecting the performance and convergence speed of the model.', 72 | batchSize: 'A larger batch_size can speed up the training speed, stability, and generalization ability of the model, while a smaller batch_size can reduce memory and computing resource usage, and improve the performance of the model on test data.', 73 | fineTunedName: 'A string of up to 40 characters that will be added to the fine-tuned model name.', 74 | learningRate: 'You can control how many times the learning rate used during fine-tuning training is compared to the learning rate used by the pre-trained model. For example, if you set it to 2.0, the learning rate used during fine-tuning training will be twice that of the pre-trained model.', 75 | promptAttention: 'Setting a higher value will make the model pay more attention to prompts when generating text, while setting a lower value will make the model focus more on its own language model and generate more free text.' 76 | }, 77 | file: { 78 | title: "file", 79 | upload: "Upload files", 80 | delete: "Delete Files", 81 | retrieve: "Retrieve files", 82 | view: "View file content" 83 | }, 84 | image: { 85 | title: "image", 86 | production: "Production picture", 87 | production_title: "After opening, the content sent by the chat is information describing the picture", 88 | change: "Change picture", 89 | change_title: "After opening, upload the picture first, and then enter the prompt words to modify.", 90 | size: "Size", 91 | size_title: "The size of the image.", 92 | count: "Quantity", 93 | count_title: "The number of generated images." 94 | }, 95 | audio: { 96 | title: "audio", 97 | to_text_title: "Speech to Text", 98 | to_text: "Speech to Text", 99 | language_title: "Translate speech or audio files from one or more source languages to a target language", 100 | language: "Language", 101 | temperature_title: "Specify the randomness of speech recognition, ranging from 0 to 1. Higher values indicate more diversity and creativity, while lower values indicate more conservatism and certainty.", 102 | temperature: "Randomness(0-1)", 103 | }, 104 | role: { 105 | title: "role" 106 | }, 107 | setting: { 108 | title: "set", 109 | Language: "Chinese Language" 110 | }, 111 | file_card: { 112 | unknown: "unknown" 113 | }, 114 | person_card: { 115 | train: "training...", 116 | cancel: "Cancelled" 117 | }, 118 | util_js: { 119 | select: "Please select an image to upload!", 120 | path: "The path is incorrect!", 121 | notallowed: "This file type is not allowed to be uploaded. please upload ", 122 | type: " A file of type, the current file type is" 123 | }, 124 | message: { 125 | start_recording: "Start recording~", 126 | fail_audio: "Failed to get audio stream~", 127 | end_recording: "End recording~", 128 | edit_picture: "Edit picture mode: Please upload the picture in the upper right corner of the chat window first, and then send the modified content~", 129 | msg_empty: "Message cannot be empty~", 130 | model_del: "The model has been deleted or canceled...", 131 | valid_png: "Please upload a valid PNG file~", 132 | less_4M: "Please upload a file smaller than 4MB~", 133 | upload_complete: "Image upload completed, please give me a prompt to edit~", 134 | get_model_fail: "Failed to get model list~~", 135 | valid_json: "Please upload a valid JSON file~~", 136 | only_file: "Can only search for files~", 137 | fail_file: "Failed to search for files~", 138 | openai_free: "In order to reduce misuse, OpenAI free accounts cannot download fine-tuned training files~", 139 | only_del_file: "Can only delete files~", 140 | del_file_succ: "Congratulations on successfully deleting the file~", 141 | del_fail: "Failed to delete the file~", 142 | create_succ: "Congratulations on successfully creating fine-tuning~", 143 | create_fail: "Failed to create fine-tuning...", 144 | only_del_model: "Can only delete the model in fine-tuning~", 145 | del_model_succ: "Congratulations on successfully deleting the fine-tuned model~", 146 | del_fail_ing: "Failed to delete the fine-tuned model. The model is being trained or has been cancelled midway", 147 | only_cancel: "Can only cancel fine-tuned models in training~", 148 | cancel_succ: "Successfully canceled this model~", 149 | cancel_fail: "Failed to cancel the fine-tuned model~", 150 | only_model: "Can only search for fine-tuned models~", 151 | verify_model_fail: "Failed to search for fine-tuned models~", 152 | get_files_fail:"Failed to get file list~", 153 | get_roles_fail:"Failed to get role list~" 154 | }, 155 | index: { 156 | detail: "The model behind ChatGPT v3.5", 157 | lastMsg: "The model behind ChatGPT v3.5", 158 | up_file_id: "The file has been uploaded successfully, and the file ID is", 159 | copy: ", and it has been copied for you~", 160 | file_id: "`File ID:`", 161 | file_name: "`File Name:`", 162 | file_size: "`File Size:`", 163 | obj: "`Object:`", 164 | status: "`Status:`", 165 | status_des: "`Status Description:`", 166 | target: "`Target:`", 167 | file_time: "`File Creation Time:`", 168 | task_id: "`Fine-tuning Task ID:`", 169 | task_type: "`Task Type:`", 170 | model_type: "`Model Type:`", 171 | task_time: "`Fine-tuning Task Creation Time:`", 172 | task_list: "`Fine-tuning Event List`\n", 173 | obj_log_info_time: "| Object | Log Level | Information | Creation Time |\n", 174 | model_id: "\n`Fine-tuned Model ID:`", 175 | args: "\n\n`Fine-tuning Arguments:`\n", 176 | item_setting: "| Property | Value Set |\n", 177 | user_group: "\n`User Group:`", 178 | results_null: "\n\n`Training Results File List: None`\n\n", 179 | results: "\n\n`Training Results File List:`\n\n", 180 | table_head: "| ID | File Name | File Size | Object | Status | \n", 181 | statu: "\n`Status:`", 182 | files_null: "\n\n`Training File List: None`\n\n", 183 | files: "\n\n`Training File List:`\n\n", 184 | verifys_null: "\n\n`Verification File List: None`\n\n", 185 | verifys: "\n\n`Verification File List:`\n\n", 186 | last_time: "\n`Last Update Timestamp:`", 187 | } 188 | }; 189 | -------------------------------------------------------------------------------- /src/lang/zh-CN.js: -------------------------------------------------------------------------------- 1 | export default { 2 | placeholder: { 3 | question: "在此输入您的问题~", 4 | openai_key: "请输入OpenAI KEY", 5 | role_name: "角色名称", 6 | session_name: "会话名称", 7 | model_name: "模型名称", 8 | slightly_name: "微调模型名称", 9 | file_name: "文件名称", 10 | suffix: "末尾添加的文本片段", 11 | stop: "停止生成文本的令牌", 12 | response_count: "生成的答案次数", 13 | trainingDataFileID: '训练数据的文件ID', 14 | validationDataFileID: '验证数据文件ID', 15 | modelName: '模型名称', 16 | trainingIterations: '训练次数', 17 | batchSize: '每批数据的大小', 18 | learningRate: '学习率', 19 | ftsuffix: '后缀', 20 | }, 21 | session: { 22 | title: "会话", 23 | create: "创建会话", 24 | export: "导出会话列表", 25 | import: "导入会话列表", 26 | clear: "清除会话列表" 27 | }, 28 | model: { 29 | title: "模型", 30 | talk: "对话", 31 | online_title: "联网", 32 | online: "打开之后联网查询", 33 | suffix_title: "后缀", 34 | suffix: "在生成文本末尾添加的文本片段", 35 | max_tokens_title: "最大单词数", 36 | max_tokens: "指定要生成的最大单词数,不能超过2048。", 37 | temperature_title: "随机度(0-2)", 38 | temperature: "指定生成文本的随机性,范围是0到2,越高表示越多样化和创造性,越低表示越保守和确定性。", 39 | top_p_title: "保留词比例(0-1)", 40 | top_p: "指定在每个步骤中保留概率最高的单词的比例,范围是0到1,与temperature类似,但更加灵活和稳健。", 41 | n_title: "结果规模", 42 | n: "此参数会生成许多结果", 43 | stream_title: "流式输出", 44 | stream: "开启流式输出", 45 | echo_title: "回显词", 46 | echo: "回显提示词", 47 | stop_title: "停止令牌", 48 | stop: "设置模型停止生成文本的令牌", 49 | frequency_penalty_title: "单词重复度(0-1)", 50 | frequency_penalty: "指定降低重复单词出现概率的程度,范围是0到1,越高表示越避免重复。", 51 | presence_penalty_title: "话题重复度(0-1)", 52 | presence_penalty: "指定降低重复话题出现概率的程度,范围是0到1,越高表示越避免重复。", 53 | max_results_title: "指定联网查询数据的数量,不建议太大。", 54 | max_results: "查询规模" 55 | }, 56 | slightly: { 57 | title: { 58 | whole: "微调", 59 | abbreviation: "微调" 60 | }, 61 | retrieveFineTuning: '检索微调', 62 | cancelFineTuning: '取消微调', 63 | hideCanceledFineTuning: '隐藏已取消的微调', 64 | showCanceledFineTuning: '显示已取消的微调', 65 | deleteFineTuningModel: '删除微调模型', 66 | createFineTuning: '创建微调', 67 | create: '创建', 68 | fileIDTrainingData: '包含训练数据的文件ID', 69 | fileIDValidationData: '包含验证数据的文件ID', 70 | modelOptions: '您可以选择ada、babbage、curie、davinci或者是你自己通过微调训练的模型名称', 71 | epochs: '通过调整n_epochs的数量,可以控制模型的训练时期和训练次数,从而影响模型的性能和收敛速度', 72 | batchSize: '较大的 batch_size 可以加快模型的训练速度、模型的稳定性和泛化能力,较小的 batch_size 可以减少内存和计算资源的使用、提高模型在测试数据上的性能', 73 | fineTunedName: '最多 40 个字符的字符串,将添加到微调的模型名称中。', 74 | learningRate: '可以控制微调训练期间使用的学习率是预训练模型使用的学习率的多少倍。例如,如果您设置为2.0,则微调训练期间使用的学习率将是预训练模型使用的学习率的两倍。', 75 | promptAttention: '设置较高的值,那么模型在生成文本时会更加注重提示,设置较低的值模型则会更加注重自己的语言模型,生成更自由的文本' 76 | }, 77 | file: { 78 | title: "文件", 79 | upload: "上传文件", 80 | delete: "删除文件", 81 | retrieve: "检索文件", 82 | view: "查看文件内容" 83 | }, 84 | image: { 85 | title: "图片", 86 | production: "产图模式", 87 | production_title: "打开之后聊天发送的内容为描述图片的信息", 88 | change: "改图模式", 89 | change_title: "打开之后先上传图片,然后再输入提示词进行修改。", 90 | size: "图片大小", 91 | size_title: "生成图片的大小", 92 | count: "图片数量", 93 | count_title: "生成图片的数量" 94 | }, 95 | audio: { 96 | title: "音频", 97 | to_text_title: "语音转文字", 98 | to_text: "语音转文字", 99 | language_title: "将一个或多个来源语言的语音或音频文件翻译成目标语言", 100 | language: "语言", 101 | temperature_title: "指定语音识别的随机性,范围是0到1,越高表示越多样化和创造性,越低表示越保守和确定性。", 102 | temperature: "随机度(0-1)", 103 | }, 104 | role: { 105 | title: "角色" 106 | }, 107 | setting: { 108 | title: "设置", 109 | Language: "英文语言" 110 | }, 111 | file_card: { 112 | unknown: "未知" 113 | }, 114 | person_card: { 115 | train: "正在训练...", 116 | cancel: "已取消" 117 | }, 118 | util_js: { 119 | select: "请选择要上传的图片!", 120 | path: "路径不正确!", 121 | notallowed: "该文件类型不允许上传。请上传 ", 122 | type: " 类型的文件,当前文件类型为" 123 | }, 124 | message: { 125 | start_recording: "开始录音咯~", 126 | fail_audio: "获取音频流失败啦~", 127 | end_recording: "结束录音咯~", 128 | edit_picture: "编辑图片模式:请您聊天窗口右上角先上传图片,再发送修改的内容~", 129 | msg_empty: "消息不能为空哦~", 130 | model_del: "模型已被删除或已取消...", 131 | valid_png: "请上传一个有效的PNG文件~", 132 | less_4M: "请上传一个小于4MB的文件~", 133 | upload_complete: "图片上传完成啦,请给我提示进行编辑~", 134 | get_model_fail: "获取模型列表失败哦~~", 135 | valid_json: "请上传一个有效的JSON文件~~", 136 | only_file: "只能检索文件哦~", 137 | fail_file: "文件检索失败了~", 138 | openai_free: "OpenAI为了减少滥用,免费帐户将无法下载微调训练的文件~", 139 | only_del_file: "只能删除文件哦~", 140 | del_file_succ: "恭喜您删除成功~", 141 | del_fail: "文件删除失败了~", 142 | create_succ: "恭喜您微调创建成功~", 143 | create_fail: "微调创建失败了...", 144 | only_del_model: "只能删除微调中的模型哦~", 145 | del_model_succ: "恭喜您微调模型删除成功~", 146 | del_fail_ing: "微调模型删除失败了,模型正在训练中或者中途已取消", 147 | only_cancel: "只能取消进行训练中的微调模型哦~", 148 | cancel_succ: "成功取消此模型~", 149 | cancel_fail: "取消微调模型失败~", 150 | only_model: "只能检索的微调模型哦~", 151 | verify_model_fail: "检索微调模型失败~", 152 | get_files_fail:"获取文件列表失败哦~", 153 | get_roles_fail:"获取角色列表失败哦~", 154 | }, 155 | index: { 156 | detail: "chatgpt v3.5 所基于的模型", 157 | lastMsg: "chatgpt v3.5 所基于的模型", 158 | up_file_id: "文件已上传成功,文件ID是", 159 | copy: ",已经帮您复制啦~", 160 | file_id: "`文件ID:`", 161 | file_name: "`文件名称:`", 162 | file_size: "`文件大小:`", 163 | obj: "`对象:`", 164 | status: "`状态:`", 165 | status_des: "`状态描述`", 166 | target: "`目的` ", 167 | file_time: "`文件创建时间`", 168 | task_id: "`微调任务ID:`", 169 | task_type: "`任务类型:`", 170 | model_type: "`模型的类型:`", 171 | task_time: "`微调任务的创建时间:`", 172 | task_list: "`微调的事件列表` \n", 173 | obj_log_info_time: "| 对象 | 日志级别 | 信息 | 创建时间 |\n", 174 | model_id: "\n `微调的模型ID:`", 175 | args: "\n\n `微调使用的参数:` \n", 176 | item_setting: "| 属性 | 设置的值 | \n", 177 | user_group: "\n`用户所属组:`", 178 | results_null: "\n\n`训练结果文件列表:没有`\n\n", 179 | results: "\n\n`训练结果文件列表:`\n\n", 180 | table_head: "| ID | 文件名称 | 文件大小 | 对象 | 状态 | \n", 181 | statu: "\n`状态:`", 182 | files_null: "\n\n`训练的文件列表:没有`\n\n", 183 | files: "\n\n`训练的文件列表:`\n\n", 184 | verifys_null: "\n\n`验证的文件列表:没有`\n\n", 185 | verifys: "\n\n`验证的文件列表:`\n\n", 186 | last_time: "\n`最后更新时间戳:`", 187 | } 188 | }; 189 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import ElementUI from 'element-ui'; 4 | import VueRouter from 'vue-router' 5 | import 'element-ui/lib/theme-chalk/index.css'; 6 | import router from './router/index' 7 | import { copyToClipboard } from '@/util/util' 8 | import i18n from '@/config/i18n' 9 | Vue.use(VueRouter) 10 | Vue.config.productionTip = false 11 | Vue.use(ElementUI); 12 | 13 | /** 14 | * 复制 15 | */ 16 | 17 | Vue.prototype.$copy = function (value,mes) { 18 | if (copyToClipboard(value)) { 19 | this.$message.success(mes) 20 | } 21 | } 22 | 23 | new Vue({ 24 | i18n, 25 | router, 26 | render: h => h(App), 27 | }).$mount('#app') 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import VueRouter from 'vue-router' 2 | 3 | import ChatHome from '../view/pages/chatHome/index.vue' 4 | import Setting from '../view/pages/setting.vue' 5 | import UserInfo from '../view/pages/user/userInfo.vue' 6 | export default new VueRouter({ 7 | routes: [ 8 | { 9 | path: "/", 10 | redirect: "/ChatHome", 11 | }, 12 | { 13 | path: "/ChatHome", 14 | name: "ChatHome", 15 | component: ChatHome, 16 | }, 17 | { 18 | path: "/Setting", 19 | name: "Setting", 20 | component: Setting 21 | }, 22 | { 23 | path: "/UserInfo", 24 | name: "UserInfo", 25 | component: UserInfo 26 | } 27 | ] 28 | }) -------------------------------------------------------------------------------- /src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | //AI头像地址设置 2 | export const AI_HEAD_IMG_URL="https://th.bing.com/th?id=ODL.3e2fbff4543f0d3632d34be6d02adc93&w=100&h=100&c=12&pcl=faf9f7&o=6&dpr=1.5&pid=13.1" 3 | //用户头像地址设置 4 | export const USER_HEAD_IMG_URL="https://avatars.githubusercontent.com/u/40659515?v=4" 5 | //用户名称设置 6 | export const USER_NAME="君尘陌" 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/util/util.js: -------------------------------------------------------------------------------- 1 | import i18n from '@/config/i18n' 2 | //防抖 3 | export function debounce(fn) { 4 | console.log(1) 5 | let t = null //只会执行一次 6 | debugger 7 | 8 | return function () { 9 | if (t) { 10 | clearTimeout(t) 11 | } 12 | t = setTimeout(() => { 13 | console.log(temp); //可以获取 14 | // console.log(arguments[0]) //undefined 15 | fn.apply(this, arguments) 16 | //在这个回调函数里面的argument是这个回调函数的参数,因为没有参数所以undefined,可以通过外面的函数赋值来进行访问 17 | //也可以改变成箭头函数,箭头函数的this是指向定义函数的那一层的,所以访问到的arguments是上一层函数的arguments 18 | }, 1000) 19 | 20 | } 21 | } 22 | //节流 23 | export function throttle(fn, delay = 200) { 24 | let timer = null 25 | console.log(fn); 26 | debugger 27 | return function () { 28 | if (timer) return 29 | timer = setTimeout(() => { 30 | debugger 31 | fn.apply(this, arguments) 32 | timer = null 33 | }) 34 | } 35 | } 36 | //下拉动画 37 | export function animation(obj, target, fn1) { 38 | // console.log(fn1); 39 | // fn是一个回调函数,在定时器结束的时候添加 40 | // 每次开定时器之前先清除掉定时器 41 | clearInterval(obj.timer); 42 | obj.timer = setInterval(function () { 43 | // 步长计算公式 越来越小 44 | // 步长取整 45 | var step = (target - obj.scrollTop) / 10; 46 | step = step > 0 ? Math.ceil(step) : Math.floor(step); 47 | if (obj.scrollTop >= target) { 48 | clearInterval(obj.timer); 49 | // 如果fn1存在,调用fn 50 | if (fn1) { 51 | fn1(); 52 | } 53 | } else { 54 | // 每30毫秒就将新的值给obj.left 55 | obj.scrollTop = obj.scrollTop + step; 56 | } 57 | }, 10); 58 | } 59 | 60 | //判断文件类型 61 | export function judgeFileType(file) { 62 | if (file == null || file == "") { 63 | alert(i18n.t('util_js.select')); 64 | return false; 65 | } 66 | if (file.lastIndexOf('.') == -1) { //如果不存在"." 67 | alert(i18n.t('util_js.path')); 68 | return false; 69 | } 70 | var AllImgExt = ".jpg|.jpeg|.gif|.bmp|.png|"; 71 | var extName = file.substring(file.lastIndexOf(".")).toLowerCase();//(把路径中的所有字母全部转换为小写) 72 | if (AllImgExt.indexOf(extName + "|") == -1) { 73 | ErrMsg = i18n.t('util_js.notallowed') + AllImgExt + i18n.t('util_js.type') + extName; 74 | alert(ErrMsg); 75 | return false; 76 | } 77 | } 78 | 79 | //文件类型 80 | export function fileType() { 81 | return { 82 | 'application/msword': 'word', 83 | 'application/pdf': 'pdf', 84 | 'application/vnd.ms-powerpoint': 'ppt', 85 | 'application/vnd.ms-excel': 'excel', 86 | 'aplication/zip': 'zpi', 87 | } 88 | } 89 | 90 | /** 91 | * 获取当前时间 92 | */ 93 | export function getNowTime() { 94 | // 创建一个Date对象 95 | var date = new Date(); 96 | // 获取年份、月份、日期、小时、分钟和秒数 97 | var year = date.getFullYear(); 98 | var month = date.getMonth() + 1; // 注意月份从0开始计数 99 | var day = date.getDate(); 100 | var hour = date.getHours(); 101 | var minute = date.getMinutes(); 102 | var second = date.getSeconds(); 103 | // 如果月份、日期、小时、分钟或秒数小于10,需要在前面补0 104 | if (month < 10) { 105 | month = "0" + month; 106 | } 107 | if (day < 10) { 108 | day = "0" + day; 109 | } 110 | if (hour < 10) { 111 | hour = "0" + hour; 112 | } 113 | if (minute < 10) { 114 | minute = "0" + minute; 115 | } 116 | if (second < 10) { 117 | second = "0" + second; 118 | } 119 | // 拼接成字符串 120 | var currentTime = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second; 121 | // 输出结果 122 | return currentTime; 123 | } 124 | 125 | 126 | /** 127 | * 格式化时间 128 | */ 129 | export function JCMFormatDate(dateStr) { 130 | let date = new Date(dateStr); 131 | let year = date.getFullYear(); 132 | let month = date.getMonth() + 1; 133 | let day = date.getDate(); 134 | let hour = date.getHours(); 135 | let minute = date.getMinutes(); 136 | let second = date.getSeconds(); 137 | return `${year}/${month}/${day} ${hour}:${minute}:${second}`; 138 | } 139 | 140 | 141 | //将时间戳转换为正常时间 142 | export function JCMFormatTimestamp(timestamp){ 143 | const date = new Date(timestamp * 1000); // 转换为Date对象 144 | const options = { // 背景时间的格式选项 145 | year: 'numeric', // 年份(4位数字) 146 | month: 'long', // 月份的全称 147 | day: 'numeric', // 天(数字) 148 | hour: 'numeric', // 小时(数字) 149 | minute: 'numeric',// 分钟(数字) 150 | second: 'numeric' // 秒钟(数字) 151 | }; 152 | return date.toLocaleDateString('zh-CN', options); 153 | } 154 | /** 155 | * 复制到剪切板 156 | */ 157 | 158 | export function copyToClipboard(content) { 159 | const clipboardData = window.clipboardData 160 | if (clipboardData) { 161 | clipboardData.clearData() 162 | clipboardData.setData('Text', content) 163 | return true 164 | } else if (document.execCommand) { 165 | const el = document.createElement('textarea') 166 | el.value = content 167 | el.setAttribute('readonly', '') 168 | el.style.position = 'absolute' 169 | el.style.left = '-9999px' 170 | document.body.appendChild(el) 171 | el.select() 172 | document.execCommand('copy') 173 | document.body.removeChild(el) 174 | return true 175 | } 176 | return false 177 | 178 | } 179 | 180 | /** 181 | * 生成UUID 182 | * @returns 183 | */ 184 | export function generateUUID() { 185 | var d = new Date().getTime(); 186 | if (window.performance && typeof window.performance.now === "function") { 187 | d += performance.now(); //use high-precision timer if available 188 | } 189 | var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { 190 | var r = (d + Math.random() * 16) % 16 | 0; 191 | d = Math.floor(d / 16); 192 | return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); 193 | }); 194 | return uuid; 195 | } 196 | 197 | /** 198 | * 是否在pc端下 199 | */ 200 | export function isPc(){ 201 | return navigator.userAgent.toLowerCase().indexOf(' electron/') > -1 202 | } -------------------------------------------------------------------------------- /src/view/home.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 65 | 66 | 82 | -------------------------------------------------------------------------------- /src/view/pages/chatHome/chatwindow.vue: -------------------------------------------------------------------------------- 1 | 141 | 142 | 926 | 927 | 928 | 1362 | -------------------------------------------------------------------------------- /src/view/pages/setting.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 48 | 49 | 65 | -------------------------------------------------------------------------------- /src/view/pages/user/userInfo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | 37 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('@vue/cli-service') 2 | const NodePolyfillPlugin = require('node-polyfill-webpack-plugin') 3 | 4 | module.exports = defineConfig({ 5 | 6 | configureWebpack: config => { 7 | config.plugins = [ 8 | ...config.plugins, 9 | new NodePolyfillPlugin() 10 | ], 11 | config.experiments = { 12 | syncWebAssembly: true 13 | } 14 | // 非Node环境下去掉electron模块 15 | if (!process.env.IS_ELECTRON) { 16 | config.externals = { 17 | electron: 'commonjs2 electron', 18 | } 19 | } 20 | }, 21 | transpileDependencies: true, 22 | publicPath: './', // 设置资源文件的根路径 23 | devServer: { 24 | hot: true//自动保存 25 | }, 26 | pluginOptions: { 27 | electronBuilder: { 28 | nodeIntegration: true, 29 | customFileProtocol: "./", 30 | mainProcessFile: 'src/background.js', 31 | builderOptions: { 32 | appId: 'com.example.app', 33 | productName: 'ChatGPT_JCM', 34 | win: { 35 | icon: './public/app.ico' 36 | }, 37 | mac: { 38 | icon: './public/app.icns' 39 | } 40 | } 41 | } 42 | } 43 | }) 44 | --------------------------------------------------------------------------------