From 4e090a39979a9d2dcb22b072f8f6ff06aa59771d Mon Sep 17 00:00:00 2001 From: charles <981744753@qq.com> Date: 星期一, 29 七月 2024 16:47:29 +0800 Subject: [PATCH] feat:新增会话,会话记录模块 --- /dev/null | 6 src/router/routes/modules/session.ts | 28 ++ src/assets/images/u64.png | 0 src/assets/images/u74.png | 0 src/views/session/sessionManager/components/addSession.vue | 40 ++ src/api/session.ts | 29 ++ src/router/routes/modules/sessionRecords.ts | 28 ++ src/assets/images/u69.png | 0 src/views/session/sessionManager/index.vue | 350 +++++++++++++++++++++++++ src/assets/images/u767.png | 0 src/views/sessionRecords/sessionRecordsManager/index.vue | 312 ++++++++++++++++++++++ 11 files changed, 787 insertions(+), 6 deletions(-) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index cff1354..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ -<component name="InspectionProjectProfileManager"> - <profile version="1.0"> - <option name="myName" value="Project Default" /> - <inspection_tool class="Stylelint" enabled="true" level="ERROR" enabled_by_default="true" /> - </profile> -</component> \ No newline at end of file diff --git a/src/api/session.ts b/src/api/session.ts new file mode 100644 index 0000000..fe2b47f --- /dev/null +++ b/src/api/session.ts @@ -0,0 +1,29 @@ +import axios from 'axios'; + +export interface ISessionListResult { + code:number; + msg:string; + data:any; +} +// 浼氳瘽鍒楄〃 +export function sessionListApi() { + return axios.get<ISessionListResult>('/api/conversation/list?modeltype=localragflow'); +} +// 鍒犻櫎浼氳瘽 +export function deleteSessionApi(conversation_ids:string[]) { + return axios.post<ISessionListResult>('/api/conversation/del?modeltype=localragflow',{conversation_ids}); +} +// 鏂板浼氳瘽 +export function addSessionApi(params:any) { + return axios.get<ISessionListResult>('/api/getConId/kdwithai?platform=localragflow',{params}); +} + +// 鑱婂ぉ +export function chatApi(data:{conversation_id:string,messages:string}) { + return axios.post<ISessionListResult>('/api/tech/cloudminds/query?modeltype=localragflow',data); +} + +// 鑾峰彇浼氳瘽璇︽儏 +export function getSessionDetailsApi(conversation_id:string) { + return axios.get<ISessionListResult>('/api/conversation/get?modeltype=localragflow',{params:{conversation_id}}); +} \ No newline at end of file diff --git a/src/assets/images/u64.png b/src/assets/images/u64.png new file mode 100644 index 0000000..f50a80e --- /dev/null +++ b/src/assets/images/u64.png Binary files differ diff --git a/src/assets/images/u69.png b/src/assets/images/u69.png new file mode 100644 index 0000000..59be7bd --- /dev/null +++ b/src/assets/images/u69.png Binary files differ diff --git a/src/assets/images/u74.png b/src/assets/images/u74.png new file mode 100644 index 0000000..db5aeca --- /dev/null +++ b/src/assets/images/u74.png Binary files differ diff --git a/src/assets/images/u767.png b/src/assets/images/u767.png new file mode 100644 index 0000000..19740b7 --- /dev/null +++ b/src/assets/images/u767.png Binary files differ diff --git a/src/router/routes/modules/session.ts b/src/router/routes/modules/session.ts new file mode 100644 index 0000000..6ccd4d7 --- /dev/null +++ b/src/router/routes/modules/session.ts @@ -0,0 +1,28 @@ +import { DEFAULT_LAYOUT } from '../base'; +import { AppRouteRecordRaw } from '../types'; +const session: AppRouteRecordRaw = { + path: '/session', + name: 'session', + component: DEFAULT_LAYOUT, + meta: { + locale: 'menu.session', + requiresAuth: true, + icon: 'icon-voice', + order: 3, + hideInMenu:false + }, + children:[ + { + path:'sessionManager', + name:"sessionManager", + meta:{ + requiresAuth: true, + hideInMenu:true, + roles: ['*'], + activeMenu:'session' + }, + component:()=>import('@/views/session/sessionManager/index.vue'), + } + ] +}; +export default session; \ No newline at end of file diff --git a/src/router/routes/modules/sessionRecords.ts b/src/router/routes/modules/sessionRecords.ts new file mode 100644 index 0000000..f70c5e3 --- /dev/null +++ b/src/router/routes/modules/sessionRecords.ts @@ -0,0 +1,28 @@ +import { DEFAULT_LAYOUT } from '../base'; +import { AppRouteRecordRaw } from '../types'; +const sessionRecords: AppRouteRecordRaw = { + path: '/sessionRecords', + name: 'sessionRecords', + component: DEFAULT_LAYOUT, + meta: { + locale: 'menu.sessionRecords', + requiresAuth: true, + icon: 'icon-list', + order: 3, + hideInMenu:false + }, + children:[ + { + path:'sessionRecordsManager', + name:"sessionRecordsManager", + meta:{ + requiresAuth: true, + hideInMenu:true, + roles: ['*'], + activeMenu:'sessionRecords' + }, + component:()=>import('@/views/sessionRecords/sessionRecordsManager/index.vue'), + } + ] +}; +export default sessionRecords; \ No newline at end of file diff --git a/src/views/session/sessionManager/components/addSession.vue b/src/views/session/sessionManager/components/addSession.vue new file mode 100644 index 0000000..0a1c997 --- /dev/null +++ b/src/views/session/sessionManager/components/addSession.vue @@ -0,0 +1,40 @@ +<script setup lang="ts"> + import { defineProps ,ref,defineEmits} from 'vue'; + import { Message } from '@arco-design/web-vue'; + import { addSessionApi }from '@/api/session'; + const props=defineProps({ + modalObj:Object + }); + const conversation_name=ref(''); + const emit = defineEmits(['addSession']); + const handleOk=async ()=>{ + if(conversation_name.value){ + const {code}=await addSessionApi({conversation_name:conversation_name.value}); + if(code===200){ + Message.success('娣诲姞鎴愬姛'); + emit('addSession') + } + }else{ + Message.warning('浼氳瘽鍚嶇О涓嶈兘涓虹┖'); + } + } +</script> + +<template> + <div> + <a-modal v-model:visible="modalObj.add" @ok="handleOk" @cancel="modalObj.add=false"> + <template #title> + 鏂板浼氳瘽 + </template> + <a-form> + <a-form-item label="浼氳瘽鍚嶇О:"> + <a-input placeholder="璇疯緭鍏ヤ細璇濆悕绉�" v-model="conversation_name" style="width: 80%"></a-input> + </a-form-item> + </a-form> + </a-modal> + </div> +</template> + +<style scoped lang="scss"> + +</style> diff --git a/src/views/session/sessionManager/index.vue b/src/views/session/sessionManager/index.vue new file mode 100644 index 0000000..fd1e5fd --- /dev/null +++ b/src/views/session/sessionManager/index.vue @@ -0,0 +1,350 @@ +<script setup lang="ts"> + import { IconMoreVertical,IconQuestionCircleFill,IconPoweroff,IconCommon ,IconSend} from '@arco-design/web-vue/es/icon'; + import img1 from '@/assets/images/u64.png' + import img2 from '@/assets/images/u69.png' + import img3 from '@/assets/images/u74.png'; + import AddSession from './components/addSession.vue' + import { ref, onMounted, computed, reactive, nextTick } from 'vue'; + import { useUserStore,useAppStore } from '@/store'; + import { sessionListApi, deleteSessionApi,getSessionDetailsApi,chatApi }from '@/api/session'; + import { Message } from '@arco-design/web-vue'; + const userStore = useUserStore(); + const appStore = useAppStore(); + const theme = computed(() => { + return appStore.theme; + }); + const sessionList=ref([]);//浼氳瘽鍒楄〃 + const sessionDetailList=ref([]);//鏍规嵁浼氳瘽id鍑烘潵鐨勪細璇濊鎯� + const activeSessionId=ref(''); + const inputMsg=ref(''); + const scrollbar = ref(null); + + const currIndex = ref(0) + const displayedText = ref('');// 姝e湪鏄剧ず鐨勬枃瀛� + let timer: number|null = null; + const streamStr=ref(''); + const modalObj=reactive({ add:false }); + //鏌ヨ浼氳瘽鍒楄〃 + const querySessionList = async () => { + const { code, data } =await sessionListApi(); + if (code === 200) { + sessionList.value = data; + if(Array.isArray(data)&&data.length>0){ + activeSessionId.value=data[0].id; + const res= await getSessionDetailsApi(data[0].id); + if(res.code===200){ + sessionDetailList.value=res.data.message; + refreshScroll(); + } + } + }else{ + Message.warning('鏌ヨ澶辫触'); + } + }; + //鏍规嵁浼氳瘽id鍒犻櫎浼氳瘽 + const deleteSession=async (session)=>{ + const {code}=await deleteSessionApi([session.id]); + if(code===200){ + Message.success('鍒犻櫎鎴愬姛'); + querySessionList(); + } + }; + // eslint-disable-next-line prettier/prettier + // 鏂板浼氳瘽涔嬪悗鍒锋柊浼氳瘽鍒楄〃 + const addSession=()=>{ + querySessionList(); + }; + // 鍒濆鍖栨暟鎹� + const initData =()=>{ + querySessionList(); + }; + // 鑾峰彇鐧诲綍淇℃伅 + const userName=computed(()=>{ + return userStore.name; + }); + const avatar = computed(() => { + return userStore.avatar; + }); + const refreshScroll=()=>{ + nextTick(()=>{ + const container = document.getElementById('home'); + scrollbar.value.scrollTop(container.scrollHeight); + }); + }; + // 鏍规嵁浼氳瘽id 鏌ヨ浼氳瘽璇︽儏 + const querySessionDetail=async (session)=>{ + activeSessionId.value=session.id; + const {code,data}= await getSessionDetailsApi(session.id); + if(code===200){ + sessionDetailList.value=data.message; + refreshScroll();//鍒锋柊婊氬姩鏉′綅缃� + } + }; + const sendMessage= async ()=>{ + if(inputMsg.value){ + const {code,data} =await chatApi({conversation_id:activeSessionId.value,messages:inputMsg.value}); + const res= await getSessionDetailsApi(activeSessionId.value); + if(res.code===200){ + sessionDetailList.value=res.data.message.map((item,index)=>{ + if(index===res.data.message.length-1){ + item.role='last'; + streamStr.value=item.content; + startDisplayStr(); + } + return item; + }); + refreshScroll(); + } + inputMsg.value=''; + }else{ + Message.warning('娑堟伅涓嶈兘涓虹┖'); + } + }; + onMounted(()=>{ + initData(); + }); + //鏂囧瓧涓�涓竴涓緭鍑� + const startDisplayStr = () => { + if (timer) { + clearTimeout(timer!); + } + const res = streamStr.value; + // 灏嗘暟缁勪腑鐨勫瓧绗︿覆鎷兼帴璧锋潵 + if (currIndex.value < res.length) { + displayedText.value += res[currIndex.value]; + currIndex.value++; + setTimeout(startDisplayStr, 100); + } else { + clearTimeout(timer!); + timer = null + } + } + +</script> + +<template> + <div class="container"> + <AddSession :modalObj="modalObj" @addSession="addSession"></AddSession> + <a-row :gutter="[0,0]"> + <a-col :span="5"> + <a-card class="left"> + <template #cover> + <a-button type="outline" class="card-btn" @click="modalObj.add=true"> + +鏂板缓浼氳瘽 + </a-button> + </template> + <a-scrollbar class="left-list" style="height: 60vh;overflow-y: auto;"> + <div class="item" :class="{isLeftActive:activeSessionId===session.id}" v-for="session in sessionList" :key="session.id" @click="querySessionDetail(session)"> + <div class="item-left"> + <IconQuestionCircleFill/>銆� + {{session.name}} + </div> + <div class="item-right"> + <a-popover position="bottom"> + <icon-more-vertical></icon-more-vertical> + <template #content> + <!--<div> + <a-button type="text" size="mini">缂栬緫</a-button> + </div>--> + <div> + <a-button type="text" size="mini" @click="deleteSession(session)">鍒犻櫎</a-button> + </div> + </template> + </a-popover> + </div> + </div> + </a-scrollbar> + <div class="left-bottom"> + <div class="item"><IconCommon/>銆�<span>鍚戞湅鍙嬫帹鑽�</span></div> + <div class="item"><IconCommon/>銆�<span>鏈�鏂版秷鎭�</span></div> + <div class="item"><IconCommon/>銆�<span>闂鍙嶉</span></div> + <div class="item"><IconCommon/>銆�<span>甯歌闂</span></div> + <div class="item"><IconPoweroff/>銆�<span>閫�鍑�</span></div> + </div> + </a-card> + </a-col> + <a-col :span="19"> + <a-card class="right"> + <div v-if="sessionDetailList.length===0"> + <div class="right-title">ChatAI</div> + <a-row justify="center" class="right-middle"> + <a-col :span="5" class="item"> + <p><a-image :src="img1" width="50px"></a-image></p> + <p>绀轰緥</p> + </a-col> + <a-col :span="5" class="item"> + <p><a-image :src="img2" width="50px"></a-image></p> + <p>鏍稿績鍔熻兘</p> + </a-col> + <a-col :span="5" class="item"> + <p><a-image :src="img3" width="50px"></a-image></p> + <p>灞�闄愭��</p> + </a-col> + </a-row> + <a-row justify="center" class="right-middle-list"> + <a-col :span="6" class="item">鈥滆鐢ㄧ畝鍗曠殑鏈瑙i噴閲忓瓙璁$畻鈥�</a-col> + <a-col :span="6" class="item">鍙互瀵瑰巻鍙插璇濊繘琛岃蹇�</a-col> + <a-col :span="6" class="item">鍙兘浼氬嚭鐜伴敊璇殑鍐呭</a-col> + </a-row> + <a-row justify="center" class="right-middle-list"> + <a-col :span="6" class="item">鈥滄彁渚涗竴浜涘簡绁�10宀佸瀛愮敓鏃ョ殑鍒涙剰锛熲��</a-col> + <a-col :span="6" class="item">鍏佽鐢ㄦ埛瀵圭瓟妗堣繘琛屼慨姝�</a-col> + <a-col :span="6" class="item">鍙兘浼氫骇鐢熸湁瀹虫垨铏氬亣鐨勫唴瀹�</a-col> + </a-row> + <a-row justify="center" class="right-middle-list"> + <a-col :span="6" class="item">鈥滃浣曞湪Javascript涓彂鍑篽ttp璇锋眰锛熲��</a-col> + <a-col :span="6" class="item">鍙互鎺ュ彈鎴栨嫆缁濅笉鎭板綋鐨勮缁�</a-col> + <a-col :span="6" class="item">瀵�2023骞翠互鍚庡緱涓栫晫鍜屼簨浠朵簡瑙f湁闄�</a-col> + </a-row> + </div> + <a-scrollbar ref="scrollbar" id="home" v-else class="chat-list" style="width:90%;overflow:auto;height: 70vh;margin: 0px auto"> + <div class="chat-item" v-for="sessionDetail in sessionDetailList"> + <a-comment + v-if="sessionDetail.role==='user'" + avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp" + > + <template #content> + <div :class="{light:theme==='light'}">{{sessionDetail.content}}</div> + </template> + </a-comment> + <a-comment + v-else-if="sessionDetail.role==='assistant'" + avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/9eeb1800d9b78349b24682c3518ac4a3.png~tplv-uwbnlip3yd-webp.webp" + > + <template #content> + <a-card class="chat-item-answer" style="background-color: rgba(63, 64, 79, 1);"> + <div :class="{light:theme==='light'}">{{sessionDetail.content}}</div> + </a-card> + </template> + </a-comment> + <a-comment + v-else-if="sessionDetail.role==='last'" + avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/9eeb1800d9b78349b24682c3518ac4a3.png~tplv-uwbnlip3yd-webp.webp" + > + <template #content> + <a-card class="chat-item-answer" style="background-color: rgba(63, 64, 79, 1);"> + <div :class="{light:theme==='light'}"> {{displayedText}}</div> + </a-card> + </template> + </a-comment> + </div> + </a-scrollbar> + <div class="bottom"> + <div class="input"> + <a-input v-model="inputMsg"> + <template #suffix> + <icon-send style="cursor: pointer" @click="sendMessage"/> + </template> + </a-input></div> + <div class="text">鍐呭鐢盇I鐢熸垚锛屼粎渚涘弬鑰冿紝璇烽伒瀹堛�婄敤鎴峰崗璁�嬨�併�婁釜浜轰俊鎭繚鎶よ鍒欍�嬶紝鍩轰簬ChatGPT澶фā鍨嬶紝鐗堟湰锛歏3.3.0</div> + </div> + </a-card> + </a-col> + </a-row> + </div> +</template> + +<style scoped lang="scss"> + .isLeftActive{ + background-color:rgba(52, 53, 66, 1) ; + } + .light{ + color: white !important; + } + .container{ + background-color: #1d2129; + .left,.right{ + color: white; + height: calc(100vh - 60px); + border: 0px; + } + .left{ + position: relative; + background-color: rgba(30, 33, 34, 1); + .card-btn { + width: 90%; + margin: 15px auto; + border: 1px solid white; + color: white; + } + .left-list{ + .item{ + display: flex; + justify-content: space-between; + padding-left: 30px; + color: white; + cursor: pointer; + line-height: 40px; + .item-right{ + margin-right: 10px; + } + &:hover{ + background-color:rgba(52, 53, 66, 1) ; + } + } + } + .left-bottom{ + position: absolute; + bottom: 30px; + left:40px; + .item{ + text-align: left; + color: white; + font-size: 12px; + line-height: 30px; + } + } + } + .right{ + position: relative; + background-color: rgba(52, 53, 66, 1); + .right-title{ + font-size: 30px; + color: white; + text-align: center; + margin-top: 100px; + } + .right-middle{ + margin-top: 40px; + text-align: center; + color: white; + } + .right-middle-list{ + color: white; + .item{ + padding-top:15px; + text-align: center; + height: 50px; + background-color: rgba(63, 64, 79, 1); + margin:8px 20px; + border-radius: 10px; + } + } + .bottom{ + width: 100%; + position: absolute; + bottom: 40px; + left:20%; + .input{ + width: 60%; + } + .text{ + font-size: 12px; + color: lightgrey; + line-height: 40px; + } + } + .chat-list{ + width: 90%; + margin: 0px auto; + .chat-item{ + margin-top: 20px; + .chat-item-answer{ + color: white; + } + } + } + + } + } +</style> diff --git a/src/views/sessionRecords/sessionRecordsManager/index.vue b/src/views/sessionRecords/sessionRecordsManager/index.vue new file mode 100644 index 0000000..02f4e77 --- /dev/null +++ b/src/views/sessionRecords/sessionRecordsManager/index.vue @@ -0,0 +1,312 @@ +<script setup lang="ts"> + import { IconSearch,IconTiktokColor ,IconSend,IconClose} from '@arco-design/web-vue/es/icon'; + import { useAppStore} from '@/store'; + import {computed,ref,onMounted,reactive} from 'vue'; + import {sessionListApi}from '@/api/session'; + import { Message } from '@arco-design/web-vue'; + import moment from 'moment'; + import AddSession from '@/views/session/sessionManager/components/addSession.vue'; + const sessionList=ref([]);//浼氳瘽鍒楄〃 + const modalObj=reactive({add:false}); + //鏌ヨ浼氳瘽鍒楄〃 + const querySessionList=async ()=>{ + const {code,data} =await sessionListApi(); + if(code===200){ + sessionList.value=data; + }else{ + Message.warning('鏌ヨ澶辫触'); + } + }; + //鏂板浼氳瘽涔嬪悗鍒锋柊浼氳瘽鍒楄〃 + const addSession=()=>{ + querySessionList(); + }; + onMounted(()=>{ + querySessionList(); + }); + const appStore = useAppStore(); + const theme = computed(() => { + return appStore.theme; + }); +</script> + +<template> + <div class="container"> + <AddSession :modalObj="modalObj" @addSession="addSession"></AddSession> + <a-card class="top-title">AI浼氳瘽璁板綍</a-card> + <a-row :gutter="[5,5]" style="margin-top: 3px"> + <a-col :span="4"> + <a-card style="height: 60px"> + <template #cover> + <div style="display: flex;justify-content: space-between"> + <a-button type="primary" shape="round" class="card-btn-1" @click="modalObj.add=true"> + +鏂板缓浼氳瘽 + </a-button> + <a-button type="default" shape="circle" class="card-btn-2"> + <icon-search /> + </a-button> + </div> + </template> + </a-card> + <a-card class="left"> + <a-scrollbar class="left-list" style="height: calc(100vh - 160px);overflow-y: auto;overflow-x: hidden;"> + <div class="item" v-for="session in sessionList"> + <div class="text" :class="{light:theme==='dark'}">{{session.name}}</div> + <div class="time">{{moment(new Date(session.create_time)).format('YYYY-MM-DD HH:mm:ss')}}</div> + </div> + </a-scrollbar> + </a-card> + </a-col> + <a-col :span="15"> + <a-card class="center"> + <div class="center-title">鏅鸿兘闂瓟</div> + <div class="center-content"> + 鎴戝彲浠ョ悊瑙e拰瀛︿範浜虹被鐨勮瑷�锛屽叿澶囧杞璇濈殑鑳藉姏锛岀幇鍦ㄥ拰鎴戝紑濮嬩氦娴佸惂~ + </div> + <div class="center-question"> + <div class="center-question-left">璇曚竴璇曡繖鏍烽棶鎴�</div> + <div class="center-question-right"> + <a-button type="primary">鎹竴鎹�</a-button> + </div> + </div> + <a-row justify="space-around" class="center-list"> + <a-col :span="7" class="item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </a-col> + <a-col :span="7" class="item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </a-col> + <a-col :span="7" class="item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </a-col> + <a-col :span="7" class="item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </a-col> + <a-col :span="7" class="item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </a-col> + <a-col :span="7" class="item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </a-col> + </a-row> + <div class="center-bottom"> + <a-textarea style="height: 180px" placeholder="杈撳叆鎮ㄦ兂浜嗚В鐨勫唴瀹癸紝Shift+Enter鎹㈣" :max-length="500" allow-clear show-word-limit> + </a-textarea> + </div> + </a-card> + </a-col> + <a-col :span="5"> + <a-card class="right"> + <div class="right-top"> + <div class="right-title">鏁版櫤搴�</div> + <div class="right-btn"> + <a-button type="outline" shape="circle" style="border: none;"> + <icon-search /> + </a-button> + <a-button type="outline" shape="circle" style="border: none;margin-left: -10px"> + <icon-close/> + </a-button> + </div> + </div> + <div class="right-tag"> + <a-space> + <a-button type="primary" shape="round" size="mini" class="btn">鍏ㄩ儴</a-button> + <a-button type="outline" shape="round" size="mini" class="btn">鏂囨。鍒涗綔</a-button> + <a-button type="outline" shape="round" size="mini" class="btn">鐭ヨ瘑瀛︿範</a-button> + </a-space> + <a-space style="margin-top:10px "> + <a-button type="outline" shape="round" size="mini" class="btn">鏁堢巼鎻愬崌</a-button> + </a-space> + </div> + <div class="right-list"> + <div class="right-item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </div> + <div class="right-item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </div> + <div class="right-item"> + <div class="item-title"> + <IconTiktokColor></IconTiktokColor>鎶栭煶甯﹁揣鑴氭湰 + </div> + <div class="item-content" :class="{dark:theme==='dark'}"> + 缂栧啓寮曚汉娉ㄧ洰涓斿叿鏈夎鏈嶅姏鐨勩�侀�傜敤浜庝骇鍝佺殑... + </div> + </div> + </div> + </a-card> + </a-col> + </a-row> + </div> +</template> + +<style scoped lang="scss"> + .light{ + color: white !important; + } + .dark{ + color: gray !important; + } + .container{ + .top-title{ + line-height:60px; + font-size: 25px; + font-family: 榛戜綋; + } + .center,.right{ + box-sizing: border-box; + height: calc(100vh - 100px); + } + .left{ + /* height: calc(100vh - 160px); + overflow-y: auto; + overflow-x: hidden;*/ + border: 0px; + .left-list{ + .item{ + cursor: pointer; + .text,.time{ + line-height: 30px; + } + .text{ + color: black; + } + .time{ + color: gray; + font-size: 12px; + } + } + } + } + .card-btn-1 { + margin: 10px; + width: 75%; + } + .card-btn-2 { + margin:10px 10px; + } + .center{ + position: relative; + .center-title{ + line-height:60px; + font-size: 25px; + font-family: 榛戜綋; + color: deepskyblue; + } + .center-content{ + font-size: 14px; + color: gray; + } + .center-question{ + margin-top: 20px; + display: flex; + justify-content: space-between; + .center-question-left{ + margin-top: 5px; + margin-left: 20px; + } + .center-question-right{ + margin-right: 20px; + } + } + .center-list{ + margin-top: 10px; + .item{ + border-radius: 10px; + margin-top: 10px; + padding: 10px; + height: 120px; + background-color: lightcyan; + .item-title{ + text-align: center; + line-height:40px; + font-size: 20px; + font-family: 榛戜綋; + color: black; + } + } + } + .center-bottom{ + position: absolute; + width: 90%; + bottom: 70px; + left:5%; + } + } + .right{ + .right-top{ + display: flex; + justify-content: space-between; + .right-title{ + font-size: 25px; + font-family: 榛戜綋; + color: black; + } + .right-btn{ + position: relative; + left:20px; + top:0px; + } + } + .right-tag{ + margin-top: 20px; + } + .right-list{ + .right-item{ + border-radius: 10px; + margin-top: 10px; + padding: 10px; + height: 120px; + background-color: lightcyan; + .item-title{ + text-align: center; + line-height:40px; + font-size: 20px; + font-family: 榛戜綋; + color: black; + } + } + } + } + } +</style> -- Gitblit v1.8.0