|
|
@@ -0,0 +1,153 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="en" class="h-full">
|
|
|
+ <head>
|
|
|
+ <meta charset="UTF-8" />
|
|
|
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
|
|
|
+ <title>ChatPDF(客服)</title>
|
|
|
+ <script type="text/javascript" src="https://unpkg.com/jquery@3.3.1/dist/jquery.min.js"></script>
|
|
|
+ <script src="https://unpkg.com/eruda@3.0.0/eruda.js"></script>
|
|
|
+ <script src="https://cdn.tailwindcss.com"></script>
|
|
|
+ <script>
|
|
|
+ tailwind.config = {
|
|
|
+ corePlugins: {
|
|
|
+ preflight: false
|
|
|
+ },
|
|
|
+ theme: {
|
|
|
+ extend: {
|
|
|
+ colors: {
|
|
|
+ clifford: "#da373d"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ </script>
|
|
|
+ <!-- Import style -->
|
|
|
+ <link rel="stylesheet" href="//unpkg.com/element-plus/dist/index.css" />
|
|
|
+ <!-- Import Vue 3 -->
|
|
|
+ <script src="//unpkg.com/vue@3"></script>
|
|
|
+ <!-- Import component library -->
|
|
|
+ <script src="//unpkg.com/element-plus"></script>
|
|
|
+ <script src="//unpkg.com/@element-plus/icons-vue"></script>
|
|
|
+ <style>
|
|
|
+ html,
|
|
|
+ body {
|
|
|
+ padding: 0;
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+ ::-webkit-scrollbar {
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+ <body class="h-full">
|
|
|
+ <div id="app" class="h-full">
|
|
|
+ <el-container class="h-full">
|
|
|
+ <el-main class="flex flex-col">
|
|
|
+ <el-alert v-if="name" :title="fileName" type="success" effect="dark" @close="clear"></el-alert>
|
|
|
+ <el-upload
|
|
|
+ v-else
|
|
|
+ class="upload-demo"
|
|
|
+ drag
|
|
|
+ v-model:file-list="fileList"
|
|
|
+ action="/api/chat-pdf/upload"
|
|
|
+ accept="application/pdf"
|
|
|
+ :on-success="onSuccess"
|
|
|
+ >
|
|
|
+ <el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
|
|
+ <div class="el-upload__text">请上传客服回答文档</div>
|
|
|
+ </el-upload>
|
|
|
+ <div id="list" class="flex flex-col flex-1 overflow-auto">
|
|
|
+ <div
|
|
|
+ v-for="(item,i) in conversations"
|
|
|
+ :key="i"
|
|
|
+ class="mt-4 p-3 rounded-t-xl"
|
|
|
+ :class="item.value.role==='system' ? 'mr-10 bg-slate-300 rounded-r-xl' : 'ml-10 bg-neutral-200 rounded-l-xl'"
|
|
|
+ >
|
|
|
+ <el-icon v-if="item.value.loading" class="is-loading">
|
|
|
+ <Loading />
|
|
|
+ </el-icon>
|
|
|
+ <span v-else>\{{item.value.content}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-main>
|
|
|
+ <el-footer class="py-4 flex items-end" @keyup.enter.stop.prevent="ask">
|
|
|
+ <el-input v-model="q" :disabled="!name" placeholder="提问"></el-input>
|
|
|
+ <el-button class="ml-3" type="primary" :disabled="!name" @click="ask">发送</el-button>
|
|
|
+ </el-footer>
|
|
|
+ </el-container>
|
|
|
+ </div>
|
|
|
+ </body>
|
|
|
+ <script>
|
|
|
+ var app = Vue.createApp({
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ name: "",
|
|
|
+ fileName: "",
|
|
|
+ fileList: [],
|
|
|
+ q: "",
|
|
|
+ conversations: []
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ onSuccess(res, file) {
|
|
|
+ console.log(res, file);
|
|
|
+ this.name = res.name;
|
|
|
+ this.fileName = file.name;
|
|
|
+ },
|
|
|
+ clear() {
|
|
|
+ this.fileList = [];
|
|
|
+ this.name = "";
|
|
|
+ this.fileName = "";
|
|
|
+ this.q = "";
|
|
|
+ this.conversations = [];
|
|
|
+ },
|
|
|
+ ask(e) {
|
|
|
+ console.log(this.q);
|
|
|
+ if (this.q) {
|
|
|
+ this.conversations.push(
|
|
|
+ Vue.ref({
|
|
|
+ role: "user",
|
|
|
+ content: this.q
|
|
|
+ })
|
|
|
+ );
|
|
|
+ var msg = Vue.ref({
|
|
|
+ role: "system",
|
|
|
+ loading: true,
|
|
|
+ content: ""
|
|
|
+ });
|
|
|
+ this.conversations.push(msg);
|
|
|
+
|
|
|
+ setTimeout(function () {
|
|
|
+ $("#list").scrollTop($("#list")[0].scrollHeight);
|
|
|
+ }, 50);
|
|
|
+ $.post(
|
|
|
+ "/api/chat-pdf/customerServiceAsk",
|
|
|
+ {
|
|
|
+ name: this.name,
|
|
|
+ q: this.q
|
|
|
+ },
|
|
|
+ function (res) {
|
|
|
+ console.log(res);
|
|
|
+ msg.value.loading = false;
|
|
|
+ msg.value.content = res.answer;
|
|
|
+ setTimeout(function () {
|
|
|
+ $("#list").scrollTop($("#list")[0].scrollHeight);
|
|
|
+ }, 50);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ this.q = "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ app.use(ElementPlus);
|
|
|
+ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
|
|
+ app.component(key, component);
|
|
|
+ }
|
|
|
+ app.mount("#app");
|
|
|
+ </script>
|
|
|
+</html>
|