wujingjing
2024-06-28 96d13ee431fef2fb5eaba05654cd7e0216ce36ab
新建聊天室
已修改8个文件
131 ■■■■■ 文件已修改
src/components/chat/Chat.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chat/components/playBar/PlayBar.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/customDirective.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/index.ts 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/component/sidebar/waterLeftAside/asideNew.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/component/sidebar/waterLeftAside/types.ts 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/chatRoom.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/ch/home/component/waterRight/top.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chat/Chat.vue
@@ -44,6 +44,8 @@
import { md } from './libs/markdown';
import { RoleEnum, roleImageMap, type ChatMessage } from './types';
import PlayBar from '/@/components/chat/components/playBar/PlayBar.vue';
import { activeChatRoom } from '/@/stores/chatRoom';
import router from '/@/router';
let apiKey = '';
let isConfig = ref(false);
@@ -71,8 +73,13 @@
    if (getAPIKey()) {
        switchConfigStatus();
    }
    const inputValue = history.state.inputValue;
    messageContent.value = inputValue;
    if (!activeChatRoom.value) {
        router.replace({
            name: 'Home',
        });
        return;
    }
    messageContent.value = activeChatRoom.value.title;
    sendOrSave();
});
@@ -144,6 +151,10 @@
const sendOrSave = () => {
    if (!messageContent.value.length) return;
    if (activeChatRoom.value.isInitial) {
        activeChatRoom.value.title = messageContent.value;
        activeChatRoom.value.isInitial = false;
    }
    if (isConfig.value) {
        if (saveAPIKey(messageContent.value.trim())) {
            switchConfigStatus();
src/components/chat/components/playBar/PlayBar.vue
@@ -6,7 +6,7 @@
            </el-button>
        </div>
        <div class="set-input">
            <el-input @keydown.enter="isTalking || emits('sendClick')" v-model="inputValue" placeholder="在这里输入您的问题开始和AI对话" class="set-inputAnswer" />
            <el-input v-elInputFocus @keydown.enter="isTalking || emits('sendClick')" v-model="inputValue" placeholder="在这里输入您的问题开始和AI对话" class="set-inputAnswer" />
        </div>
        <div class="h100 flex items-center">
            <div class="upload_img space-y">
src/directive/customDirective.ts
@@ -53,6 +53,14 @@
    });
}
export const eleFocusDirective =(app:App)=>{
    app.directive('elInputFocus',{
        mounted:(el)=>{
            el.querySelector('input.el-input__inner')?.focus()
        }
    })
}
/**
 * 自定义拖动指令
 * @description  使用方式:v-drag="[dragDom,dragHeader]",如 `<div v-drag="['.drag-container .el-dialog', '.drag-container .el-dialog__header']"></div>`
src/directive/index.ts
@@ -1,6 +1,6 @@
import type { App } from 'vue';
import { authDirective } from '/@/directive/authDirective';
import { wavesDirective, dragDirective } from '/@/directive/customDirective';
import { wavesDirective, dragDirective,eleFocusDirective } from '/@/directive/customDirective';
import { inputLimit } from '/@/directive/inputLimit';
/**
@@ -18,4 +18,6 @@
    dragDirective(app);
    // 输入限制指令
    inputLimit(app);
    eleFocusDirective(app);
}
src/layout/component/sidebar/waterLeftAside/asideNew.vue
@@ -28,18 +28,18 @@
            <div class="flex-auto text-[#ccc] flex flex-col items-center mt-6 overflow-y-auto" ref="chatRoomRef">
                <div
                    :class="{ 'bg-[#41424a]': index === activeIndex }"
                    :class="{ 'bg-[#41424a]': item.id === activeRoomId }"
                    class="group flex items-center w-full h-10 rounded-md cursor-pointer px-2 py-2 flex-0"
                    v-for="(item, index) in chatRoomList"
                    :key="index"
                    @click="roomClick(item, index)"
                    @click="roomClick(item)"
                >
                    <div class="ywicon icon-xiaoxi flex-0 mr-2.5"></div>
                    <div class="flex-auto text-ellipsis text-nowrap text-sm group-hover:text-[#0084ff]">chat room</div>
                    <div class="text-gray-100 flex items-center space-x-2 ml-1">
                        <div class="ywicon invisible icon-bianji visible group-hover:visible !text-sm"></div>
                        <el-popconfirm title="确定删除这个聊天室?" @confirm.stop="confirmDeleteChatRoom(item, index)">
                        <el-popconfirm title="确定删除这个聊天室?" @confirm.stop="confirmDeleteChatRoom(item)">
                            <template #reference>
                                <div class="ywicon invisible icon-shanchu3 visible group-hover:visible"></div>
                            </template>
@@ -53,11 +53,10 @@
<script setup lang="ts">
import { Search } from '@element-plus/icons-vue';
import { nextTick, reactive, ref, watch } from 'vue';
import { nextTick, onMounted, reactive, ref } from 'vue';
import type { ChatRoomItem } from './types';
import router from '/@/router';
import { chatRoomList } from '/@/stores/chatRoom';
import { Local } from '/@/utils/storage';
import { activeRoomId, chatRoomList } from '/@/stores/chatRoom';
let state = reactive({
    searchInput: '',
    selectDateOption: [
@@ -87,47 +86,63 @@
    state.isShowDate = !state.isShowDate;
};
const activeIndex = ref(null);
const gotoAnswerPage = (room: ChatRoomItem) => {
    if (room.isInitial) {
        router.push({
            name: 'Home',
        });
    } else {
        router.push({
            name: 'AskAnswer',
            query: {
                id: room.id,
            },
        });
    }
};
const newChatRoomClick = () => {
    const newRoom = {
        id: new Date().getTime() + '' + Math.floor(Math.random() * 1000),
        isInitial: true,
        title: 'chat room',
    };
    console.log("🚀 ~ chatRoomList.value:", chatRoomList.value)
    if (!chatRoomList.value) {
        chatRoomList.value = [newRoom];
    } else {
        chatRoomList.value.unshift(newRoom);
    }
    activeIndex.value = 0;
    activeRoomId.value = newRoom.id;
    nextTick(() => {
        router.push({
            name: 'Home',
        });
        gotoAnswerPage(newRoom);
    });
};
const roomClick = (room: ChatRoomItem, index: number) => {
    activeIndex.value = index;
    router.push({
        name: 'Home',
    });
const roomClick = (room: ChatRoomItem) => {
    activeRoomId.value = room.id;
    gotoAnswerPage(room);
};
const confirmDeleteChatRoom = (room: ChatRoomItem, index: number) => {
const confirmDeleteChatRoom = (room: ChatRoomItem) => {
    const foundIndex = chatRoomList.value.findIndex((item) => item === room);
    chatRoomList.value.splice(foundIndex, 1);
    if (chatRoomList.value.length === 0) {
        newChatRoomClick();
        return;
    }
    roomClick(chatRoomList.value[0]);
    chatRoomRef.value.firstElementChild?.scrollIntoView();
    activeIndex.value = 0;
};
watch(
    () => chatRoomList.value,
    (val) => {
        Local.set('chatRoomList', val);
onMounted(() => {
    if (router.currentRoute.value.name === 'Home') {
        if (!chatRoomList.value || chatRoomList.value.length === 0) {
            newChatRoomClick();
        } else {
            roomClick(chatRoomList.value[0]);
        }
    }
);
});
</script>
<style scoped lang="scss">
.set-input {
src/layout/component/sidebar/waterLeftAside/types.ts
@@ -1,8 +1,8 @@
export type ChatRoomItem = {
    isInitial:Boolean,
    title:String,
    content?:String
    id:string;
    isInitial:boolean,
    title:string,
    content?:string
}
src/stores/chatRoom.ts
@@ -1,13 +1,18 @@
import { computed } from 'vue';
import { computed, ref, watch } from 'vue';
import type { ChatRoomItem } from '../layout/component/sidebar/waterLeftAside/types';
import { Local } from '../utils/storage';
export const chatRoomList = computed<ChatRoomItem[]>({
    get: () => {
        return Local.get('chatRoomList') ?? [];
export const chatRoomList = ref<ChatRoomItem[]>(Local.get('chatRoomList'));
watch(
    () => chatRoomList.value,
    (val) => {
        Local.set('chatRoomList', val);
    },
    set: (value) => {
        console.log("🚀 ~ value:", value)
        Local.set('chatRoomList', value);
    },
});
    {
        deep: true,
    }
);
export const activeRoomId = ref(null);
export const activeChatRoom = computed(() => chatRoomList.value?.find((item) => item.id === activeRoomId.value));
src/views/project/ch/home/component/waterRight/top.vue
@@ -26,16 +26,16 @@
import { reactive, ref } from 'vue';
import PlayBar from '/@/components/chat/components/playBar/PlayBar.vue';
import router from '/@/router';
import { activeChatRoom } from '/@/stores/chatRoom';
const emits = defineEmits(['sendClick']);
const inputValue = ref('');
const sendClick = () => {
    if(!inputValue.value) return;
    activeChatRoom.value.title = inputValue.value;
    router.push({
        name: 'AskAnswer',
        state: {
            inputValue: inputValue.value,
        },
    });
};
let state = reactive({