mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-17 08:46:38 +08:00
使用 Element UI 实现会话界面
This commit is contained in:
parent
e2c3f50c8a
commit
aa3a38348f
27
web/package-lock.json
generated
27
web/package-lock.json
generated
@ -8,6 +8,7 @@
|
||||
"name": "yycloud-webssh",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"axios": "^0.27.2",
|
||||
"core-js": "^3.8.3",
|
||||
"element-plus": "^2.1.11",
|
||||
@ -1689,9 +1690,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@element-plus/icons-vue": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-1.1.4.tgz",
|
||||
"integrity": "sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz",
|
||||
"integrity": "sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
@ -4997,6 +4998,14 @@
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/element-plus/node_modules/@element-plus/icons-vue": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-1.1.4.tgz",
|
||||
"integrity": "sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/element-plus/node_modules/@popperjs/core": {
|
||||
"name": "@sxzz/popperjs-es",
|
||||
"version": "2.11.7",
|
||||
@ -12206,9 +12215,9 @@
|
||||
"integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw=="
|
||||
},
|
||||
"@element-plus/icons-vue": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-1.1.4.tgz",
|
||||
"integrity": "sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz",
|
||||
"integrity": "sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==",
|
||||
"requires": {}
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
@ -14932,6 +14941,12 @@
|
||||
"normalize-wheel-es": "^1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-1.1.4.tgz",
|
||||
"integrity": "sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"@popperjs/core": {
|
||||
"version": "npm:@sxzz/popperjs-es@2.11.7",
|
||||
"resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
|
||||
|
@ -8,6 +8,7 @@
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"axios": "^0.27.2",
|
||||
"core-js": "^3.8.3",
|
||||
"element-plus": "^2.1.11",
|
||||
|
42
web/src/components/ConfigDialog.vue
Normal file
42
web/src/components/ConfigDialog.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-show="show"
|
||||
title="聊天配置"
|
||||
width="30%"
|
||||
:before-close="beforeClose"
|
||||
>
|
||||
<span>正在努力开发中...</span>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="show = false">取消</el-button>
|
||||
<el-button type="primary" @click="show = false">
|
||||
保存
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {defineComponent} from "vue"
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ConfigDialog',
|
||||
data() {
|
||||
return {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeClose: function () {
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="stylus">
|
||||
|
||||
</style>
|
@ -15,26 +15,33 @@
|
||||
|
||||
</div><!-- end chat box -->
|
||||
|
||||
<div class="input-box" :style="{width: inputBoxWidth+'px'}" id="input-box">
|
||||
<div class="input-box">
|
||||
<div class="input-container">
|
||||
<textarea class="input-text" id="input-text" rows="1" :style="{minHeight:'24px', height: textHeight+'px'}"
|
||||
v-on:keydown="inputKeyDown"
|
||||
v-model="inputValue"
|
||||
placeholder="Input any thing here..."
|
||||
v-on:focus="focus"></textarea>
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
:autosize="{ minRows: 1, maxRows: 10 }"
|
||||
v-on:keydown="inputKeyDown"
|
||||
v-on:focus="focus"
|
||||
type="textarea"
|
||||
placeholder="Input any thing here..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="btn-container">
|
||||
<button type="button"
|
||||
class="btn btn-success"
|
||||
:disabled="sending"
|
||||
v-on:click="sendMessage">发送
|
||||
</button>
|
||||
<el-row>
|
||||
<el-button type="success" class="send" :disabled="sending" v-on:click="sendMessage">发送</el-button>
|
||||
<el-button type="danger" class="config" circle @click="showDialog = true">
|
||||
<el-icon>
|
||||
<Tools/>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
</div><!-- end input box -->
|
||||
</div><!-- end container -->
|
||||
|
||||
<config-dialog v-model="showDialog"></config-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -44,21 +51,19 @@ import ChatPrompt from "@/components/ChatPrompt.vue";
|
||||
import ChatReply from "@/components/ChatReply.vue";
|
||||
import {randString} from "@/utils/libs";
|
||||
import {ElMessage} from 'element-plus'
|
||||
import {Tools} from '@element-plus/icons-vue'
|
||||
import ConfigDialog from '@/components/ConfigDialog.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: "XChat",
|
||||
components: {ChatPrompt, ChatReply},
|
||||
components: {ChatPrompt, ChatReply, Tools, ConfigDialog},
|
||||
data() {
|
||||
return {
|
||||
title: "ChatGPT 控制台",
|
||||
chatData: [],
|
||||
inputBoxHeight: 63,
|
||||
inputBoxWidth: 0,
|
||||
inputValue: '',
|
||||
textHeight: 24,
|
||||
textWidth: 0,
|
||||
chatBoxHeight: 0,
|
||||
isMobile: false,
|
||||
showDialog: false,
|
||||
|
||||
socket: null,
|
||||
sending: false
|
||||
@ -69,24 +74,9 @@ export default defineComponent({
|
||||
|
||||
mounted: function () {
|
||||
nextTick(() => {
|
||||
this.inputBoxHeight = document.getElementById("input-box").offsetHeight;
|
||||
this.textWidth = document.getElementById("input-text").offsetWidth;
|
||||
this.chatBoxHeight = window.innerHeight - this.inputBoxHeight - 40;
|
||||
this.chatBoxHeight = window.innerHeight - 61;
|
||||
})
|
||||
|
||||
//判断是否手机端访问
|
||||
const userAgentInfo = navigator.userAgent.toLowerCase();
|
||||
const Agents = ["android", "iphone", "windows phone", "ipad", "ipod"];
|
||||
for (let v = 0; v < Agents.length; v++) {
|
||||
if (userAgentInfo.toLowerCase().indexOf(Agents[v]) >= 0) {
|
||||
this.isMobile = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.inputBoxWidth = window.innerWidth;
|
||||
|
||||
window.addEventListener('resize', this.windowResize);
|
||||
|
||||
// 初始化 WebSocket 对象
|
||||
const socket = new WebSocket(process.env.VUE_APP_WS_HOST + '/api/chat');
|
||||
socket.addEventListener('open', () => {
|
||||
@ -135,23 +125,15 @@ export default defineComponent({
|
||||
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
window.removeEventListener("resize", this.windowResize);
|
||||
},
|
||||
|
||||
methods: {
|
||||
inputKeyDown: function (e) {
|
||||
|
||||
if (e.keyCode === 13) {
|
||||
if (!this.isMobile) { // PC 端按回车键直接提交数据
|
||||
if (this.sending) {
|
||||
e.preventDefault();
|
||||
return this.sendMessage();
|
||||
} else {
|
||||
return this.inputResize(true);
|
||||
this.sendMessage();
|
||||
}
|
||||
|
||||
}
|
||||
this.inputResize(false);
|
||||
},
|
||||
|
||||
// 发送消息
|
||||
@ -172,55 +154,16 @@ export default defineComponent({
|
||||
this.sending = true;
|
||||
this.socket.send(this.inputValue);
|
||||
this.inputValue = '';
|
||||
this.inputResize(false);
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 根据输入内容的多少动态调整输入框的大小
|
||||
* @param flag 是否输入回车键,如果输入了回车键则需要增加一行
|
||||
*/
|
||||
inputResize: function (flag) {
|
||||
let line = 1;
|
||||
if (flag) {
|
||||
line++;
|
||||
}
|
||||
|
||||
let textWidth = 0;
|
||||
for (let i in this.inputValue) {
|
||||
if (this.inputValue[i] === '\n') {
|
||||
line++;
|
||||
textWidth = 0; // 换行之后前面字数清零
|
||||
continue;
|
||||
}
|
||||
if (this.inputValue.charCodeAt(Number(i)) < 128) {
|
||||
textWidth += 8; // 英文字符宽度
|
||||
} else {
|
||||
textWidth += 16; // 中文字符宽度
|
||||
}
|
||||
|
||||
if (textWidth >= this.textWidth) { // 另起一行
|
||||
textWidth = textWidth - this.textWidth;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
this.inputBoxHeight = 63 + (line - 1) * 24;
|
||||
this.textHeight = line * 24;
|
||||
},
|
||||
|
||||
windowResize: function () {
|
||||
this.inputResize(false);
|
||||
this.chatBoxHeight = window.innerHeight - this.inputBoxHeight - 40;
|
||||
this.inputBoxWidth = window.innerWidth;
|
||||
},
|
||||
|
||||
// 获取焦点
|
||||
focus: function () {
|
||||
setTimeout(function () {
|
||||
document.getElementById('container').scrollTo(0, document.getElementById('container').scrollHeight)
|
||||
}, 200)
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
})
|
||||
@ -267,12 +210,13 @@ export default defineComponent({
|
||||
|
||||
.input-box {
|
||||
padding 10px;
|
||||
width 100%;
|
||||
|
||||
position: absolute;
|
||||
bottom: 0
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
|
||||
.input-container {
|
||||
overflow hidden
|
||||
@ -306,8 +250,15 @@ export default defineComponent({
|
||||
.btn-container {
|
||||
margin-left 10px;
|
||||
|
||||
button {
|
||||
width 70px;
|
||||
.el-row {
|
||||
flex-wrap nowrap
|
||||
width 106px;
|
||||
align-items center
|
||||
}
|
||||
|
||||
.send {
|
||||
width 60px;
|
||||
height 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user