update chat api

This commit is contained in:
Zhang Minghan 2023-07-19 08:27:14 +08:00
parent 4d74ec5efe
commit 82fde730c0
5 changed files with 90 additions and 12 deletions

View File

@ -9,6 +9,7 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"axios": "^1.4.0",
"vue": "^3.2.45", "vue": "^3.2.45",
"vue-router": "^4.2.4" "vue-router": "^4.2.4"
}, },

64
app/pnpm-lock.yaml generated
View File

@ -5,6 +5,9 @@ settings:
excludeLinksFromLockfile: false excludeLinksFromLockfile: false
dependencies: dependencies:
axios:
specifier: ^1.4.0
version: 1.4.0
vue: vue:
specifier: ^3.2.45 specifier: ^3.2.45
version: 3.2.45 version: 3.2.45
@ -438,6 +441,20 @@ packages:
resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
dev: true dev: true
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: false
/axios@1.4.0:
resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==}
dependencies:
follow-redirects: 1.15.2
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
dev: false
/balanced-match@1.0.2: /balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true dev: true
@ -448,6 +465,13 @@ packages:
balanced-match: 1.0.2 balanced-match: 1.0.2
dev: true dev: true
/combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
dependencies:
delayed-stream: 1.0.0
dev: false
/csstype@2.6.21: /csstype@2.6.21:
resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
@ -455,6 +479,11 @@ packages:
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
dev: true dev: true
/delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
dev: false
/esbuild@0.16.17: /esbuild@0.16.17:
resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -488,6 +517,25 @@ packages:
/estree-walker@2.0.2: /estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
/follow-redirects@1.15.2:
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
dev: false
/form-data@4.0.0:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
engines: {node: '>= 6'}
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
dev: false
/fsevents@2.3.2: /fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -530,6 +578,18 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.4.15
dev: true dev: true
/mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
dev: false
/mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
dependencies:
mime-db: 1.52.0
dev: false
/minimatch@5.1.6: /minimatch@5.1.6:
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -561,6 +621,10 @@ packages:
picocolors: 1.0.0 picocolors: 1.0.0
source-map-js: 1.0.2 source-map-js: 1.0.2
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false
/resolve@1.22.2: /resolve@1.22.2:
resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
hasBin: true hasBin: true

View File

@ -67,7 +67,6 @@ aside {
.container { .container {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
flex-shrink: 0;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;

View File

@ -1,5 +1,6 @@
import { reactive, ref } from "vue"; import { reactive, ref } from "vue";
import type { Ref } from "vue"; import type { Ref } from "vue";
import axios from "axios";
type Message = { type Message = {
content: string; content: string;
@ -20,8 +21,23 @@ export class Conversation {
this.len = ref(0); this.len = ref(0);
} }
public addMessage(message: Message): void { public async send(content: string): Promise<void> {
this.state.value = true; this.state.value = true;
this.addMessageFromUser(content);
const res = await axios.post("https://api.fystart.cn/gpt", {
"id": this.id,
"message": content,
}, {
headers: { "Content-Type": "application/json" },
method: "POST",
});
if (res.data.status === true) {
this.addMessageFromAI(res.data.message);
}
this.state.value = false;
}
public addMessage(message: Message): void {
this.messages.push(message); this.messages.push(message);
this.len.value++; this.len.value++;
} }

View File

@ -10,12 +10,12 @@ const input = ref("");
const inputEl = ref<HTMLElement | undefined>(); const inputEl = ref<HTMLElement | undefined>();
const chatEl = ref<HTMLElement | undefined>(); const chatEl = ref<HTMLElement | undefined>();
function send() { async function send() {
if (input.value) { let val = input.value.trim();
console.log(input.value) if (val) {
conversation.addMessageFromUser(input.value);
input.value = ""; input.value = "";
nextTick(() => { await conversation.send(val);
await nextTick(() => {
if (!chatEl.value) return; if (!chatEl.value) return;
const el = chatEl.value as HTMLElement; const el = chatEl.value as HTMLElement;
el.scrollTop = el.scrollHeight; el.scrollTop = el.scrollHeight;
@ -25,17 +25,15 @@ function send() {
onMounted(() => { onMounted(() => {
if (!inputEl.value) return; if (!inputEl.value) return;
(inputEl.value as HTMLElement).addEventListener("keydown", (e) => { (inputEl.value as HTMLElement).addEventListener("keydown", async (e) => {
if (e.key === "Enter") { if (e.key === "Enter") await send();
send();
}
}); });
}); });
</script> </script>
<template> <template>
<div class="chat-wrapper" ref="chatEl"> <div class="chat-wrapper" ref="chatEl">
<div class="conversation" v-if="state"> <div class="conversation" v-if="length">
<div class="message" v-for="(message, index) in messages" :key="index" :class="{'user': message.role === 'user'}"> <div class="message" v-for="(message, index) in messages" :key="index" :class="{'user': message.role === 'user'}">
<div class="grow" v-if="message.role === 'user'"></div> <div class="grow" v-if="message.role === 'user'"></div>
<div class="content">{{ message.content }}</div> <div class="content">{{ message.content }}</div>