写作目的:为积极响应戴鸿君老师对项目实训内容的建设性意见,特写本系列个人纪实,记录团队在项目实训的工作中个人的贡献。
页面展示:
询问我被邻居打断了两条腿,应该做什么才能让邻居付出代价:
界面设计:
界面本体嵌入主体的主框架,在顶栏的基础上进行细化的修改。
<template >
<div class="main" style="">
<!-- 对话框组件 -->
<div style="height: 100vh" v-if="showDialog1" class="dialog-overlay">
<h2 class="fancy-font" style="text-align: center">用户问题咨询</h2>
<div class="ask">
<input style="text-align: center"
type="text"
id="username"
placeholder="请输入您的问题"
v-model="question"
/>
<button @click="submit()" class="submit">询问</button>
</div>
<div class="answer" v-html="renderAnswer"></div>
</div>
</div>
</template>
在页面调用定义的AIRequest资源
import {AIRequest} from "@/utils/request";
并触发submit方法进行后端AI模型的访问
submit() {
const err = (msg) => `# *${msg}*`
const question = this.question;
if (!question) {
this.answer = err("未输入内容")
return;
}
AIRequest.chat(question,true).then(response =>{
// 处理响应
console.log(response);
if (response.code !=0) {
this.answer = err("发生错误,请查看服务器日志");
return;
}
this.answer = response.data.answer;
})
.catch(error => {
// 处理错误情况
console.error(error);
this.answer = err("发生错误,请查看服务器日志");
})
},
request.js中申请一个新的资源AIRequest
const otherURL = "http://localhost:9091/api";
/**
* @type {{
* chat(string): Promise<any>,
* ask(string): Promise<any>,
* clear(): Promise<any>
* }}
*/
export const AIRequest = {
async _send(api, body, isPost) {
const res = await fetch(`${otherURL}/ai/${api}`,
isPost ? { method: "post", body: JSON.stringify(body) }
: { method: "get" });
if (res.status !== 200)
return Promise.reject("请求失败");
return await res.json();
},
async ask(input) {
return await this._send("ask", { input }, true);
},
async chat(input) {
return await this._send("chat", { input }, true);
},
async clear(input) {
return await this._send("clear");
},
}
对接后端的开放的AI接口
const root = path.dirname(fileURLToPath(import.meta.url));
const defaultPort = 9091;
const tunnel = {
ssh: {
host: "yourhost",
port: port,
username: "username",
password: "password"
},
port: 12315
};
const third = {
api: "https://api.moonshot.cn/v1/chat/completions",
key: "sk-key",
preset: "preset",
temperature: 0.5
}
export { root, defaultPort, tunnel, third };
Markdown结构输出:
<div class="answer" v-html="renderAnswer"></div>
import MarkdownIt from "markdown-it";
renderAnswer() {
return this.md.render(this.answer);
}
//样式
.main{
background-image: url("../../assets/法院相关图片/背景图.jpg");
}
.fancy-font {
font-family: 'Pacifico', cursive; /* 使用 'Pacifico' 字体,如果字体加载失败则使用默认的手写字体 */
color: #330000; /* 设置字体颜色 */
font-size: 40px;
opacity: 0.8;
font-weight: bold;
}
.dialog-overlay {
background-color: white;
background-image: url("../../assets/法院相关图片/背景图.jpg");
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 1em;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}
h2 {
font-size: 2em;
}
.ask {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 80%;
}
.ask >>> input {
width: 85%;
border-radius: 2em;
}
.ask >>> .submit {
width: 12%;
}
.submit {
display: flex;
justify-content: center;
align-items: center;
position: relative;
font-size: 20px;
color: white;
padding: .3em .6em;
border: 0;
border-radius: .5em;
background: dodgerblue;
overflow: hidden;
user-select: none;
box-shadow: 0 .1em .2em #1e1e1e;
transition: .2s;
}
.submit::after {
content: "";
pointer-events: none;
position: absolute;
width: 120%;
padding-top: 120%;
border-radius: 50%;
background-color: rgba(255, 255, 255, .5);
opacity: 0;
transition: .5s;
}
.submit:hover {
background: #187ad8;
box-shadow: 0 .1em .2em .05em #1e1e1e;
}
.submit:active {
transform: scale(0.96);
box-shadow: 0 .1em .2em #1e1e1e;
}
.submit:active::after {
opacity: 1;
width: 0;
padding-top: 0;
transition: 0s;
}
.answer {
font-family: 'Pacifico', cursive; /* 使用 'Pacifico' 字体,如果字体加载失败则使用默认的手写字体 */
font-size: 20px;
margin: .5em 2em;
padding: 1em;
background-color: rgba(255, 192, 203, 0.5);
border-radius: 5px;
height: 75vh;
line-height: 1.5em;
box-shadow: 0 0 5px 1px #0000007f;
overflow-y: auto;
min-width: 80%;
}
.answer >>> ol {
padding-left: 1em;
}
.pri {
transform: translateX(-69vw);
font-size: 0.3rem;
color: #187ad8;
background-color: transparent;
border: none;
margin-top: 0.3rem;
}