VUE3 + TypeScript 仿ChatGPT前端UI

基于html5 开发的仿ChatGPT的前端UI项目,采用了VUE3 + TypeScript等技术选型开发,实现了基本的消息会话、PDF会话、新增会话、删除会话、会话历史、Token统计等新增功能。

  • 消息会话、新建会话、会话历史、删除会话、Token统计、PDF文件上传等功能代码如下:
<script setup lang='ts'>
  import { ref } from 'vue'
  import { useRoute } from 'vue-router'
  import { router } from '@/router'
  import { useScroll } from './hooks/useScroll'
  import VuePdfApp from "vue3-pdf-app"
  import "vue3-pdf-app/dist/icons/main.css"
  import { encode } from 'gpt-tokenizer'


  const { scrollRef, scrollToBottom } = useScroll()

  // Conversation and PDF preview panel toggle control
  let showTab = ref<string>("nav-tab-chat")
  let tabWidth = ref<string>("")

  // vue3-pdf-app UI configuration
  let pdfFile = ref<string>("")
  const config = ref<{}>({
    sidebar: true,
    toolbar: {
      toolbarViewerLeft: {
        findbar: true,
        previous: true,
        next: true,
        pageNumber: false,
      },
      toolbarViewerRight: {
        presentationMode: true,
        openFile: false,
        print: false,
        download: false,
        viewBookmark: false,
      },
      toolbarViewerMiddle: {
        zoomOut: true,
        zoomIn: true,
        scaleSelectContainer: true,
      }
    },
  })

  // Message input box
  const prompt = ref<string>('')

  // Loading state and button state
  const buttonDisabled = ref<boolean>(false)

  // Get uuid from URL params
  const route = useRoute()
  let { uuid } = route.params as { uuid: string }

  interface Conversation {
    title: string;
    uuid: string;
    isEdit: boolean;
    createDate: string;
    lastChatContent: string;
    active: boolean;
  }

  interface Message {
    send: {
      model: string;
      messages: {
        role: string;
        content: string;
        fileName: any;
        fileSize: number;
      }[];
      temperature: number;
    };
    loading: boolean;
    receive?: {
      model: string;
      choices: {
        message?: {
          content: string;
        };
        delta: {
          content: string;
        };
      }[];
    };
  }

  // Conversation list and message list
  var conversationList = ref<Conversation[]>([])
  var messageList = ref<Message[]>([]);
  
  let conversations = window.localStorage.getItem("chatStore")
  if(conversations){
    conversationList.value = JSON.parse(conversations)
  }

  // Check if new conversation
  if (!uuid || uuid === '0') {
    uuid = Date.now().toString()

    // Initialize empty conversation
    if(!conversations){
      conversationList.value.push({
        title: 'New Chat', 
        uuid: uuid, 
        isEdit: false, 
        createDate: new Date().toLocaleString(), 
        lastChatContent: 'Hello I am ChatGPT3.5...',
        active: true
      })
    }else{
      // If has history, get last conversation
      let lastConversation = conversationList.value[conversationList.value.length-1]
      uuid = lastConversation.uuid

      let messages = window.localStorage.getItem(uuid)
      if(messages) {
        messageList.value = JSON.parse(messages)
      }

      router.push({ name: 'Chat', params: { uuid } })
    }
  }else{
    // Load current conversation messages
    let messages = window.localStorage.getItem(uuid)
    if(messages) {
      messageList.value = JSON.parse(messages)
    }
  
    conversationList.value.forEach((item, index) => {
      if(item.uuid == uuid){
        item.active = true
      }else{
        item.active = false
      }
    })

    scrollToBottom()
  }

  // Set active conversation
  function handleAdd() {
    // Reset the message record of the new conversation
    messageList.value = []

    // Reset the active status of the conversation list
    conversationList.value.forEach((item, index) => {
      item.active = false
    })

    // Initialize an empty conversation
    uuid = Date.now().toString()

    conversationList.value.unshift({
      title: "New Chat",
      uuid: uuid,
      isEdit: false,
      createDate: new Date().toLocaleString(),
      lastChatContent: 'Hello I am ChatGPT3.5...',
      active: true
    })

    // Save the conversation to local storage
    window.localStorage.setItem("chatStore", JSON.stringify(conversationList.value))
  }

  // Menu toggle
  function handleMenu(){
    let rootbody = document.getElementById("rootbody")
    if (rootbody) {
      if(rootbody.classList.value==""){
        rootbody.classList.value="open-sidebar-menu"
      }else{
        rootbody.classList.value=""
      }
    }
  }

  // Switch conversation
  function handleSwitch(selectedUuid: string) {
    uuid = selectedUuid

    // Reset message record of the new conversation
    let messages = window.localStorage.getItem(selectedUuid)
    if(messages){
      messageList.value = JSON.parse(messages)
    }else{
      messageList.value = []
    }

    // Reset active status of the conversation list
    conversationList.value.forEach((item, index) => {
      if(item.uuid == selectedUuid){
        item.active = true
      }else{
        item.active = false
      }
    })

    router.push({ name: 'Chat', params: { uuid } })
  }

  // File upload related
  var fileName = ref()
  var fileSize = ref<number>(0)
  var formattedFileSize = ref<string>('0B')
  var fileUploadCard = ref<boolean>(false)

  var fileContent = ref()

  
  // Handle file upload
  function handleUpload(e: Event) {
    const target = e.target as HTMLInputElement;
    if(target.files && target.files[0].size >= 5 * 1024 * 1024){
      alert('Maximum file size limit is 5MB')
      return
    }else if (!target.files || target.files.length === 0) {
      alert('Please select a file')
      return
    }

    // Set file upload style
    fileName.value = target.files[0].name
    fileSize.value = target.files[0].size
    formatFileSize()

    // Preview PDF
    showTab.value = 'nav-tab-doc'
    tabWidth.value = 'width: 60%'

    pdfFile.value = URL.createObjectURL(target.files[0])

  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值