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