SpringBoo+vue3+vite整合讯飞星火3.5通过webscoket实现聊天功能(前端代码)附带展示效果

news2024/11/16 21:52:28

访问地址: 
天梦星服务平台 (tmxkj.top)icon-default.png?t=N7T8https://tmxkj.top/#/site

 后端文档:

SpringBoo+vue3整合讯飞星火3.5通过webscoket实现聊天功能(全网首发)附带展示效果_springboot websocket vue3-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_53722480/article/details/139107409

1.样式库我使用了 tailwindcss,找到tailwindcss,里面有安装教程,不使用可以跳过,样式自己重新写也可以

 2.vue html

<template>
<div class="theme-controller bg-base-200 pt-1 pb-1 w-full d-flex justify-center items-center">
<div class="content-container ">
	<!--侧边栏-->
	<div class="side">
		<div class="h-full w-full  bg-base-300 rounded-r-3xl ">
			<div class="side-logo d-flex align-center text-base-0">
				<img style="width: 35px;height: 35px" class="rounded-md" src="../assets/Logo.png"> </img>
				<span class="ml-4 text-2xl font-weight-bold">AI人工智能助手</span>
			</div>
			<div class="side-api d-flex items-center">
				<el-button style="height: 40px;" class="w-36  bg-info border-0">
					<svg t="1715778624612" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4291" width="18" height="18">
						<path d="M760.32 183.466667h-13.653333v-59.733334a57.173333 57.173333 0 0 0-114.346667 0v59.733334H400.213333v-59.733334a57.173333 57.173333 0 0 0-114.346666 0v59.733334h-16.213334c-75.946667 0-138.24 61.44-138.24 138.24v494.08c0 75.946667 61.44 138.24 138.24 138.24H759.466667c75.946667 0 138.24-61.44 138.24-138.24V321.706667c0.853333-75.946667-61.44-138.24-137.386667-138.24zM515.413333 296.96c85.333333 0 154.453333 69.12 154.453334 154.453333 0 85.333333-69.12 154.453333-154.453334 154.453334-85.333333 0-154.453333-69.12-154.453333-154.453334 0-86.186667 69.12-154.453333 154.453333-154.453333zM748.373333 742.4c0 52.906667-42.666667 95.573333-95.573333 95.573333H378.026667c-52.906667 0-95.573333-42.666667-95.573334-95.573333 0-52.906667 42.666667-95.573333 95.573334-95.573333h273.92c52.906667 0 96.426667 42.666667 96.426666 95.573333z" p-id="4292" fill="#ffffff"></path>
					</svg>
					<span class="mt-0.5 ml-1">账户中心</span>
				</el-button>
				<el-button style="height: 40px;" class="w-36  bg-info border-0">
					<svg t="1715779300040" class="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8561" width="18" height="18">
						<path d="M924.17025 258.44833h0.04335c-55.093306 0-103.987667-35.705346-121.41046-88.638413l-5.639017-17.198822C779.74133 99.674415 730.836131 63.940169 675.742825 63.940169H348.239112c-55.093306 0-104.009342 35.734246-121.432134 88.667313L221.175186 169.784629C203.741555 222.728534 154.836357 258.441106 99.743051 258.441106H99.703314c-19.738366 0-35.763145 16.209013-35.763145 36.20025V777.035613h0.469617l397.129861 172.493959a126.731582 126.731582 0 0 0 100.920706 0L959.590214 777.035613h0.234808V294.644969c0-19.991237-15.916406-36.196638-35.654772-36.196639zM895.884854 734.860388l-358.989731 155.992338a62.495193 62.495193 0 0 1-49.931131 0L127.880338 734.860388V320.296897a187.991322 187.991322 0 0 0 31.699152-7.557222 192.21065 192.21065 0 0 0 94.609775-68.997583 193.821798 193.821798 0 0 0 27.714631-53.944551L287.550138 172.598719C296.357265 145.870284 320.748452 127.880338 348.239112 127.880338h327.503713c27.50511 0 51.89991 17.989946 60.688974 44.718381l5.649855 17.187985A193.312444 193.312444 0 0 0 811.715027 285.621096a190.660914 190.660914 0 0 0 52.586273 27.118579 195.34986 195.34986 0 0 0 31.583554 7.557222v414.563491z" fill="#ffffff" p-id="8562"></path><path d="M511.998194 255.999097c-141.383635 0-255.999097 114.615462-255.999097 255.999097S370.614559 768.004516 511.998194 768.004516 768.004516 653.385441 768.004516 511.998194s-114.619075-255.999097-256.006322-255.999097z m177.009507 330.736846a192.904239 192.904239 0 1 1 15.056646-74.737749 191.936105 191.936105 0 0 1-15.071096 74.741361z" fill="#ffffff" p-id="8563"></path><path d="M596.052423 425.393583l-105.392906 105.392906-62.726389-62.72639a31.970084 31.970084 0 0 0-45.213286 45.213286l85.333032 85.333032a31.970084 31.970084 0 0 0 45.213286 0l127.999548-127.999548A31.970084 31.970084 0 0 0 596.052423 425.393583z" fill="#ffffff" p-id="8564"></path>
					</svg>
					<span class="mt-0.5 ml-1">申请接口</span>
				</el-button>
			</div>
			<div class="side-talke d-flex justify-center items-center">
				<div class="talke d-flex justify-center items-center bg-warning cursor-pointer">
					<svg t="1715779790026" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13505" width="21" height="21">
						<path d="M908.8 305.6c-5.4-10.5-16.3-17.8-28.9-17.8-17.8 0-32.2 14.4-32.2 32.1 0 6 1.7 11.7 4.6 16.5l-0.1 0.1c26.9 52.4 42.1 111.8 42.1 174.7 0 211.6-171.6 383.2-383.2 383.2S127.8 722.8 127.8 511.2 299.4 128.1 511 128.1c62.5 0 121.5 15 173.6 41.5l0.2-0.4c4.6 2.6 10 4.1 15.7 4.1 17.8 0 32.2-14.4 32.2-32.1 0-13.1-7.9-24.4-19.3-29.4C652.6 80.9 583.9 63.5 511 63.5 263.7 63.5 63.2 264 63.2 511.2S263.7 958.9 511 958.9s447.7-200.4 447.7-447.7c0-74.1-18-144-49.9-205.6z" fill="#ffffff" p-id="13506"></path><path d="M770.7 219.7a32.2 32.1 0 1 0 64.4 0 32.2 32.1 0 1 0-64.4 0Z" fill="#ffffff" p-id="13507"></path><path d="M512.4 704.1c17.5 0 31.9-14.3 31.9-31.9V544.3h127.8c17.5 0 31.9-14.3 31.9-31.9 0-17.5-14.3-31.9-31.9-31.9H544.3V352.6c0-17.5-14.3-31.9-31.9-31.9-17.5 0-31.9 14.3-31.9 31.9v127.9h-128c-17.5 0-31.9 14.3-31.9 31.9 0 17.6 14.4 31.9 31.9 31.9h128v127.9c0 17.5 14.3 31.9 31.9 31.9z" fill="#ffffff" p-id="13508"></path>
					</svg>
					<span class="ml-1">新建对话</span>
				</div>
			</div>
			<div class="side-history d-flex items-center text-base-0">
				<div class="h-full d-flex flex-column justify-center align-center" @click="modelTypeFun(true)">
					<div class="h-full w-full d-flex justify-center align-center">历时对话</div>
					<div class="w-full h-0.5" :class="modelType? 'bg-amber-50':''"></div>
				</div>
				<div  class="h-full d-flex flex-column justify-center align-center" @click="modelTypeFun(false)">
					<div class="h-full w-full d-flex justify-center align-center">助手列表</div>
					<div  class="w-full h-0.5" :class="modelType? '':'bg-amber-50'"></div>
				</div>
			</div>
			<div class="side-content bg-base-100 touch-pan-y overflow-auto" v-if="modelType">
				<div v-for="(item,index) in historyList" @mouseenter="deleteIndexFun(true,index)" @mouseleave="deleteIndexFun(false,index)" @click="selectItemFun(item)" class="h-14 pl-5 d-flex justify-space-between
				 align-center pr-5 w-full hover:bg-base-200">
					<div class="line-clamp-1">{{item.title}}</div>
					<div v-show="deleteIndex===index" @click="deleteSparkChatFun([item])">
						<svg t="1716195021573" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1505" width="28" height="28">
							<path d="M839.68 307.2H184.32a40.96 40.96 0 0 1 0-81.92h655.36a40.96 40.96 0 1 1 0 81.92zM593.92 184.32h-163.84a40.96 40.96 0 1 1 0-81.92h163.84a40.96 40.96 0 0 1 0 81.92zM389.12 716.8V430.08a40.96 40.96 0 0 1 81.92 0v286.72a40.96 40.96 0 0 1-81.92 0z m163.84 0V430.08a40.96 40.96 0 0 1 81.92 0v286.72a40.96 40.96 0 0 1-81.92 0zM266.24 348.16a40.96 40.96 0 0 1 40.96 40.96v409.6a40.96 40.96 0 0 0 40.96 40.96h327.68a40.96 40.96 0 0 0 40.96-40.96V389.12a40.96 40.96 0 1 1 81.92 0v409.6a122.88 122.88 0 0 1-122.88 122.88H348.16a122.88 122.88 0 0 1-122.88-122.88V389.12a40.96 40.96 0 0 1 40.96-40.96z" fill="#f75959" p-id="1506"></path>
						</svg>
					</div>
				</div>
			</div>
			<div class="side-content bg-base-100 touch-pan-y overflow-auto" v-else>
				<div v-for="item in assistantList" class="h-14 pl-5 d-flex align-center pr-5 w-full hover:bg-base-200">
					 <div :title="item.modelDescribe">
						 <div>{{item.modelName}}</div>
						 <div class="text-xs line-clamp-1">{{item.modelDescribe}}</div>
					 </div>
					 <div></div>
				</div>
			</div>
			<div class="side-foot d-flex pl-5 pr-5 justify-space-between align-center pr-5 w-full ">
				<div class="d-flex align-center">
					<svg t="1715781825072"  viewBox="0 0 1372 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="51787" width="30" height="30">
						<path d="M696.145702 6.492596c230.726809 0 419.60034 179.243574 434.938553 406.13583l0.152511 2.788765 5.882553 1.220086c133.12 28.977021 232.034043 146.083404 235.302128 285.478127l0.065362 7.102639c0 165.408681-134.078638 299.487319-299.48732 299.487319H319.291915C153.905021 1008.705362 19.826383 874.626723 19.826383 709.218043c0-142.488511 100.003404-263.102638 235.367489-292.602554l5.860766-1.198298 0.196085-2.83234C276.392851 188.198128 461.344681 10.392511 688.650894 6.53617z m0 65.361702c-204.647489 0-370.557277 165.909787-370.579064 370.034383l0.522894 31.417191-29.979234 2.941277c-119.17617 11.699745-210.944 112.313191-210.944 232.970894 0 129.307234 104.818383 234.125617 234.125617 234.125617H1073.021277c129.307234 0 234.125617-104.796596 234.125617-234.125617 0-120.657702-91.724255-221.271149-210.900426-232.949107l-29.543489-2.897702 0.043574-29.696-0.065362-8.279149c-3.747404-201.422979-168.197447-363.541787-370.513702-363.541787zM608.909617 379.533617c11.002553 0 20.174979 2.091574 27.539064 6.252936 7.342298 4.161362 13.290213 9.542809 17.821957 16.100766 4.509957 6.53617 8.322723 13.595234 11.438298 21.133617 3.093787 7.538383 7.037277 17.604085 11.830468 30.197107l101.855319 251.577191 2.069788 5.098213c6.601532 16.558298 9.891404 28.759149 9.891404 36.667915 0 9.041702-3.769191 17.320851-11.285787 24.859234a37.147234 37.147234 0 0 1-27.277617 11.329361c-6.209362 0-11.525447-1.132936-15.948256-3.333446a32.680851 32.680851 0 0 1-11.176851-9.06349c-3.006638-3.790979-6.252936-9.651745-9.695319-17.538723a1028.531745 1028.531745 0 0 1-8.932766-20.87217l-18.606298-48.955915h-158.502127l-18.628085 50.001702-1.960852 5.163574c-6.427234 16.689021-11.982979 28.127319-16.645446 34.336681-5.141787 6.819404-13.573447 10.24-25.273192 10.24-9.934979 0-18.693447-3.638468-26.318979-10.893617-7.625532-7.276936-11.438298-15.512511-11.438297-24.750298 0-5.316085 0.871489-10.806468 2.658042-16.471149 1.764766-5.664681 4.706043-13.573447 8.780255-23.682723l99.720171-253.189447 1.786553-4.531745 8.453447-21.65651a132.466383 132.466383 0 0 1 12.767319-25.403915c4.531745-6.754043 10.457872-12.200851 17.821957-16.340426 7.364085-4.183149 16.449362-6.274723 27.25583-6.274723z m282.711149 0c11.89583 0 21.504 3.943489 28.868085 11.830468 7.364085 7.908766 11.02434 19.913532 11.02434 36.057872v307.178213l-0.108936 4.706043c-0.653617 13.791319-4.292085 24.270979-10.915404 31.460766-7.364085 7.974128-16.994043 11.982979-28.868085 11.982978-11.329362 0-20.697872-4.052426-28.04017-12.113702-7.364085-8.061277-11.046128-20.08783-11.046128-36.036085v-307.2l0.130723-5.163574c0.718979-13.399149 4.313872-23.639149 10.762894-30.72 7.276936-7.995915 16.667234-11.982979 28.192681-11.982979z m-283.234043 83.249021l-57.714383 160.898724h116.496341l-58.781958-160.898724z" fill="#ffffff" p-id="51788"></path>
					</svg>
					<span class="ml-2 text-xl">天梦星开发平台</span>
				</div>
				<div class="-rotate-90 cursor-pointer ">
					<svg t="1715780362871" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="44227" width="20" height="20">
						<path d="M484.864 281.2928l-304.64 304.64a38.4 38.4 0 1 0 54.3232 54.3232L512 362.752l277.4528 277.504a38.2976 38.2976 0 0 0 54.272 0 38.4 38.4 0 0 0 0-54.3232l-304.64-304.64a39.424 39.424 0 0 0-54.2208 0z" fill="#ffffff" p-id="44228"></path>
						<path d="M512 12.8C236.7488 12.8 12.8 236.7488 12.8 512s223.9488 499.2 499.2 499.2a496.4864 496.4864 0 0 0 448.3072-279.296 38.4 38.4 0 0 0-68.9152-33.8944A420.096 420.096 0 0 1 512 934.4c-232.9088 0-422.4-189.4912-422.4-422.4S279.0912 89.6 512 89.6s422.4 189.4912 422.4 422.4a38.4 38.4 0 0 0 76.8 0c0-275.2512-223.9488-499.2-499.2-499.2z" fill="#ffffff" p-id="44229"></path>
					</svg>
				</div>
			</div>
		</div>
	</div>
	<!--接收内容聊天框-->
	<div class="content ">
		<div class="content-body" ref="scrollContainer">
			<div class="item-content bg-base-300 rounded-lg position-relative mt-2 p-5" v-for="item in sparkList">
				<div class="position-absolute -mt-5 -ml-16 z-50">
					<el-image style="width: 40px;height: 40px" class="rounded-full" :src="userInfo?.image? configuration.visitFileUrl+userInfo.image :'https://daisyui.com/images/stock/photo-1534528741775-53994a69daeb.jpg'"></el-image>
				</div>
				<div v-if="item.type==='send'" class="text-span">
				   {{item.content.text}}
				</div>
				<div v-else>
					<keep-alive v-for="item2 in item.content">
            <div v-if="item2.type" class="w-full bg-base-100 rounded-t-md rounded-r-md mt-2 mb-2 rounded-md">
							<div class="d-flex justify-space-between align-center rounded-t-md rounded-r-md  p-3 w-full bg-base-200">
								<div class="font-weight-bold text-span">{{returnFirst(item2.text)}}</div>
								<div @click="copyContentFun(item2.text)" class="text-sm cursor-pointer">复制代码</div>
							</div>
							<div class="p-3 text-span">
								{{getContent(item2.text)}}
							</div>
						</div>
						<text class="mt-1 text-pretty leading-3 text-span" v-else>{{item2.text}}</text>
					</keep-alive>
				</div>
			</div>
		</div>
		<!--发送请求框-->
		<div class="mt-md-2 w-full d-flex justify-center">
			<div class="content-foot bg-base-300">
				<div class="input-texture">
					<el-input
						v-model="form.content"
						maxlength="2000"
						class="el-input-text"
						:clearable="true"
						:autosize="{ minRows: 2, maxRows: 5 }"
						type="textarea"
						placeholder="在此输入你想了解的内容"
					/>
				</div>
				<div class="foot-btn">
					<div>
					</div>
					<div>
						<el-button style="height: 40px;" @click="sendSocket()" class=" bg-primary border-0 w-20 h-12">发送</el-button>
					</div>
				</div>
			</div>
		</div>
	</div>
	<div v-if="loginShow">
		<login-page @receive-login="receiveLogin"></login-page>
	</div>
</div>
</div>
</template>

 3.js 代码  部分代码不能直接用,我把页面源码全部放上来了,你按照自己的需求分析提取相关内容,主要是socket的连接功能,你主要看这个,socket 的连接地址是ws://localhost:8082/websocket/+`{uuid}`

<script setup>
import { onBeforeUnmount, onMounted, ref } from 'vue'
import {
	addSparkChat,
	deleteSparkChat,
	queryAllLargeMode,
	querySparkChat,
	updateSparkChat
} from '../interface/sparkApi.js'
import { getSelUserInfo, getVerifyUser } from '../interface/UserApi.js'
import { configuration } from '../../env.product.js'
import { ElMessage } from 'element-plus'
import LoginPage from '../components/loginPage.vue'
let socket = null;
const modelType =ref(true);
const userInfo = ref();
const deleteIndex =ref(-1);
const form =ref({
	content:null,
	userId:null,
	type:"spark",
	historyId:null,
	chatType:null,
});
const historyList = ref([]);
const assistantList = ref([]);
const selectChat = ref({
	modelKey:"",
	list:[],
	title:""
});
const sparkList = ref([]);
const sparkEdit = ref(false);
const loginShow = ref(false);

onMounted(()=>{
	sparkList.value.push({
		content:[{
			text: "我是你的AI智能助手,请问我有什么能帮到您?",
			title: null,
			type: false,
		}],
		type:"back"
	})
	verifyUser();
})


/**
 * 回话记录删除鼠标移入移除事件
 */
function deleteIndexFun(val,index){
	deleteIndex.value=-1;
	if (val){
		deleteIndex.value=index
	}
}
/**
 * 复制代码
 * @param val
 */
function copyContentFun(val){
	const el = document.createElement('textarea');
	el.value = getContent(val);
	document.body.appendChild(el);
	el.select();
	document.execCommand('copy');
	document.body.removeChild(el);
	ElMessage({
		message: '复制成功',
		type: 'success',
		plain: true,
	})
}

/**
 * 返回首个拼音或者字
 * @param s
 * @return {*|null}
 */
function returnFirst(s) {
	const pattern = /```(\w+)/;
	const matches = s.match(pattern);
	return matches ? matches[1] : null;
}
/**
 * 返回正文内容
 * @param item
 * @return {*}
 */
function getContent(item) {
	let title = returnFirst(item);
	let result = (item.replace(/```/g, "\n")).replace(title,"") || item;
	return result;
}

/**
 * 进入页面连接webSocket
 */
 function openSocket() {
	const socketUrl = configuration.ws + userInfo.value.userId;
	if (socket != null) {
		socket.close()
		socket = null
	}
	//创建socket
	socket = new WebSocket(socketUrl)
	//打开事件
	socket.onopen = function () {
	//	console.log("websocket已打开");
	}
	//监听服务器返回的数据信息
	socket.onmessage = msg => {
		let lastIndex = (sparkList.value).length - 1;
		let lastContentIndex = sparkList.value[lastIndex].content.length - 1;
		if (msg.data.indexOf("``") !== -1) {
			if (sparkEdit.value){
				let oldValue = sparkList.value[lastIndex].content[lastContentIndex>=0?lastContentIndex:0].text;
				sparkList.value[lastIndex].content[lastContentIndex>=0?lastContentIndex:0].text=oldValue+""+msg.data
			}else {
				sparkList.value[lastIndex].content.push({
					text: msg.data,
					title: null,
					type: true,
				})
			}
			sparkEdit.value = ! sparkEdit.value;
		}else {
			if (sparkEdit.value){
				let oldValue = sparkList.value[lastIndex].content[lastContentIndex>=0?lastContentIndex:0].text;
				sparkList.value[lastIndex].content[lastContentIndex>=0?lastContentIndex:0].text=oldValue+""+msg.data
			}else {
				sparkList.value[lastIndex].content.push({
					text: msg.data,
					type: false,
				})
			}
		}
	}
	//关闭事件
	socket.onclose = function () {
		addSparkChatFun();
		// console.log("websocket已关闭");
	}
	//发生了错误事件
	socket.onerror = function () {
	//	console.log('websocket发生了错误')
		closeSocket()
	}
}
/**
 * 关闭socket
 */
function closeSocket() {
	if (socket !== null) {
		socket.close()
		socket = null
	}
}

/**
 * 发送socket信息
 */
function sendSocket() {
	sparkEdit.value = false;
	if (socket !== null) {
		let list = sparkList.value;
		let model ={
			content:{
				text:form.value.content,
				type:false
			},
			type:"send"
		};
		let model2 ={
			content:[],
			type:"back"
		};
		sparkList.value=[...list,model,model2];
		socket.send(JSON.stringify(form.value));
		form.value.content = null;
		setTimeout(()=>{
			addSparkChatFun();
		},5000)
	}
}

/**
 * 选中历史对话数据
 */
function selectItemFun(item){
	selectChat.value = item;
	sparkList.value = JSON.parse(item.list);
}

/**
 * 新增/修改会话记录
 */
function addSparkChatFun(){
	if (sparkList.value.length>=1){
		sparkList.value.shift();
		selectChat.value.title=sparkList.value[0].content.text;
		selectChat.value.list=JSON.stringify(sparkList.value);
		if (selectChat.value.id==null){
			addSparkChat(selectChat.value).then(res=>{
			if (res.code===200){
				selectChat.value.id=res.data;
				querySparkChatFun();
			}
			})
		}else {
			updateSparkChat(selectChat.value);
			querySparkChatFun();
		}
	}
}

/**
 * 删除会话记录
 */
function deleteSparkChatFun(val){
	deleteSparkChat(val).then(res=>{
		querySparkChatFun();
		ElMessage({
			message: res.msg,
			type: res.code==200?'success' :'error',
			plain: true,
		})
	})
}


/**
 * 校验用户是否已经登录
 */
function verifyUser() {
	getVerifyUser().then((res) => {
		if (res.code === 200) {
			localStorage.setItem('token', res.data)
			new selUserInfoFun()
		} else {
			loginShow.value = true;
		}
	})
}

/**
 * 接收登录状态
 */
function receiveLogin(e) {
	selUserInfoFun();
}

/**
 * 查询用户信息
 * @constructor
 */
function selUserInfoFun() {
	getSelUserInfo().then((res) => {
		if (res.code === 200) {
			userInfo.value = res.data;
			form.value.userId=res.data.userId;
			querySparkChatFun();
			queryAllLargeModeFun();
			openSocket();
			loginShow.value = false;
		}else {
			loginShow.value = true;
		}
	})
}
/**
 * 查询用户历史记录
 */
function querySparkChatFun(){
	querySparkChat({}).then(res=>{
		if(res.code === 200){
			historyList.value=res.data;
		}
	})
}
/**
 * 查询模型分类
 */
function queryAllLargeModeFun(){
	queryAllLargeMode({}).then(res=>{
		if(res.code === 200){
			form.value.chatType=res.data[0]?.modelKey || null;
			selectChat.value.modelKey=res.data[0]?.modelKey || null;
			assistantList.value=res.data;
		}
	})
}

/**
 * 切换历史/模型分类
 * @param type
 */
function modelTypeFun(type){
	modelType.value=type;
}
/**
 * 页面销毁之前
 */
onBeforeUnmount(() => {
	closeSocket();
})
</script>

4.css

<style scoped>
.content-container {
	height: calc(100vh - 74px);
	width: 100%;
	display: flex;
	padding: 4px 0 4px 0;
}
 .side{
   width: 260px;
	 height: 100%;
 }
 .content{
	 width: calc(100% - 310px);
	 height: 100%;
	 display: flex;
	 flex-direction: column;
	 align-items: center;
	 user-select: text;
 }
 .content-body{
	 width: 100%;
	 flex: 1;
	 overflow-y: scroll;
	 display: flex;
   align-items: center;
	 flex-direction: column;
 }
 .item-content{
	 width: 85%;
 }
 .content-foot{
	 width: 85%;
	 min-height: 120px;
	 max-height: 300px;
	 border-radius: 15px;
	 display: flex;
	 align-items: center;
	 flex-direction: column;
	 padding: 5px 0 5px 0;
 }
 .input-texture{
	 width: 98%;
	 height: auto;
 }

 .foot-btn{
   height: 40px;
	 width: 98%;
	 display: flex;
	 justify-content: space-between;
	 align-items: center;
 }
 :deep(.el-textarea__inner) {
	 outline: none;
	 border: none;
	 resize: none;
	 box-shadow: none;
	 background:transparent;
	 font-size: large;
 }
 .side-logo{
   width: 100%;
	 height:100px;
	 padding: 0 20px 0 20px;
 }
 .side-api{
	 width: 100%;
	 height:50px;
	 padding: 0 20px 0 20px;
	 justify-content: space-between;
 }
 .side-talke{
	 width: 100%;
	 height:50px;
	 padding: 0 20px 0 20px;
 }
 .talke{
	 width: 100%;
	 height: 40px;
	 border-radius: 6px;
 }
.side-history{
	width: 100%;
	height:50px;
	justify-content: space-evenly;
}
.side-content{
	width: 100%;
	height: calc(100% - 300px);
}
.side-foot{
	width: 100%;
	height:50px;
}
.text-span{
	white-space: pre-wrap;
}
</style>

 备注:样式你不用安装也可以,你根据自己需求重新也可以

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1839409.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GBT20041.21金属导管弯曲试验机

一、前言 电动金属导管弯曲试验机依据(GB/T20041.21-2008电缆管理用导管系统刚性导管系统的特殊要求》、《GB/T14823.1电气安装用导管特殊要求金属导管》、《JG/T3050建筑用绝缘电工套管及配件》及《ZBG33008聚氯乙稀塑料波纹电线管》开发的新型产品。适用于金属导管等材料做弯…

【话题】层出不穷的大模型产品,你怎么选?

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 引言元宝体验产品介绍AI作画 文档总结AI超级产品文章推荐 引言 随着近日腾讯元宝APP的正式上线&#xff0c;国内大模型产品又添一员。 关于接连出现的“全能“大模型AI…

判断单链表是否带环且返回节点

今天鄙人为大家带来的是一道简单的逻辑运算题。用用到了一个我们在链表中提及过的方法快慢法。这道题其实没啥考的实际意义。只是我们如果能了解这道题的解决方法的话。对我们后面梳理逻辑会有很大的帮助。 单链表的题目 我们可以看到上面的题目。就是让我们判断是否带环。也许…

渲染农场深度解析:原理理解、配置要点与高效使用策略

许多设计领域的新手可能对“渲染农场”这一概念感到陌生。渲染农场是一种强大的计算资源集合&#xff0c;它通过高性能的CPU和GPU以及专业的渲染引擎&#xff0c;为设计项目提供必要的渲染支持。这种平台由多台计算机或渲染节点组成&#xff0c;形成一个分布式网络&#xff0c;…

统计信号处理基础 习题解答10-17

题目&#xff1a; 在选择不含信息的或者不假设任何先验知识的先验PDF时,我们需要从数据中得到最大的信息量。在这种方式下,数据是了解未知参数的主要贡献者。利用习题10.15的结果,这种方法可以通过选择使I最大的来实现。对于例10.1的高斯先验PDF,该如何选择和2使得 是不含信息…

N4中文分类

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊# 前言 前言 上周学习了英文文本分类&#xff0c;这次进行中文分类实战。 1. 数据读取 import pandas as pd train_data pd.read_csv(train.csv,sep\t,head…

qt.qpa.xcb: could not connect to display问题解决

1、问题描述 以服务器pi5作为远程解释器&#xff0c;本地win11使用vscode远程调试视觉时报错如下&#xff1a; qt.qpa.xcb: could not connect to display qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "xxxxx" even though it was …

室内灰尘对老人小孩危害不容忽视,资深家政推荐除灰尘空气净化器

正所谓“病从口入&#xff0c;尘从窗入”&#xff0c;室内灰尘问题不容小觑。尤其是对老人和小孩来说&#xff0c;灰尘中的有害物质更是威胁健康的重要因素。近期天气炎热&#xff0c;家家户户每天都会开窗通风&#xff0c;然而这也带来了灰尘和毛絮的问题。即使每天打扫&#…

java 线程之间通信-volatile 和 synchronized

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

LabVIEW Windows与RT系统的比较与选择

LabVIEW是一种系统设计和开发环境&#xff0c;广泛应用于各类工程和科学应用中。LabVIEW Windows和LabVIEW RT&#xff08;Real-Time&#xff09;是LabVIEW的两个主要版本&#xff0c;分别适用于不同的应用场景。以下从多个角度详细分析两者的区别&#xff0c;并提供选择建议。…

国际期货行情相关术语

1&#xff09;合约&#xff1a;期货行情表提供了期货交易的相关信息 &#xff0c;行情表中每一个期货合约都有合约代码&#xff08;由期货合约交易代码和合约到期月份组成&#xff09;来标识。 &#xff08;2&#xff09;开盘价&#xff1a;当日某一期货合约交易开始前五分钟集…

开发者配置项、开发者选项自定义

devOptions.vue源码 <!-- 开发者选项 &#xff08;CtrlAltShiftD&#xff09;--> <template><div :class"$options.name" v-if"visible"><el-dialog:custom-class"sg-el-dialog":append-to-body"true":close-on…

安装pytorch环境

安装&#xff1a;Anaconda3 通过命令行查显卡nvidia-smi 打开Anacanda prompt 新建 conda create -n pytorch python3.6 在Previous PyTorch Versions | PyTorch选择1.70&#xff0c;安装成功&#xff0c;但torch.cuda.is_available 返回false conda install pytorch1.7.0…

银行数仓项目实战(四)--了解银行业务(存款)

文章目录 项目准备存款活期定期整存整取零存整取存本取息教育储蓄定活两便通知存款 对公存款对公账户协议存款 利率 项目准备 &#xff08;贴源层不必写到项目文档&#xff0c;因为没啥操作没啥技术&#xff0c;只是数据。&#xff09; 可以看到&#xff0c;银行的贴源层并不紧…

keil MDK自动生成带版本bin文件

作为嵌入式单片机开发&#xff0c;在Keil MDK&#xff08;Microcontroller Development Kit&#xff09;中开发完编译完后&#xff0c;经常需要手动进行版本号添加用于发版&#xff0c;非常麻烦&#xff0c;如果是对外发行的话&#xff0c;更容易搞错&#xff0c;特此码哥提供一…

基于若依的ruoyi-nbcio流程管理系统增加所有任务功能(一)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

最好用的智能猫砂盆存在吗?自用分享智能猫砂盆测评!

在现代都市的忙碌生活中&#xff0c;作为一名上班族&#xff0c;经常因为需要加班或频繁出差而忙碌得不可开交。急匆匆地出门&#xff0c;却忘了给猫咪及时铲屎。但是大家要知道&#xff0c;不及时清理猫砂盆会让猫咪感到不适&#xff0c;还会引发各种健康问题&#xff0c;如泌…

无问芯穹Qllm-Eval:制作多模型、多参数、多维度的量化方案

前言 近年来&#xff0c;大语言模型&#xff08;Large Models, LLMs&#xff09;受到学术界和工业界的广泛关注&#xff0c;得益于其在各种语言生成任务上的出色表现&#xff0c;大语言模型推动了各种人工智能应用&#xff08;例如ChatGPT、Copilot等&#xff09;的发展。然而…

2021 hnust 湖科大 C语言课程设计报告+代码+流程图源文件+指导书

2021 hnust 湖科大 C语言课程设计报告代码流程图源文件指导书 目录 报告 下载链接 https://pan.baidu.com/s/14NFsDbT3iS-a-_7l0N5Ulg?pwd1111

D111FCE01LC2NB70带流量调节派克比例阀

D111FCE01LC2NB70带流量调节派克比例阀 派克比例阀&#xff1a;由于采用&#xff08;秉圣135陈工6653询3053&#xff09;电液混合控制技术&#xff0c;响应速度更快、精度更高、控制更平稳。同时&#xff0c;由于采用高质量的材料制造&#xff0c;具有较高的承压能力和抗磨损性…