customerChatPdf.hbs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <!DOCTYPE html>
  2. <html lang="en" class="h-full">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
  7. <title>ChatPDF(客服)</title>
  8. <script type="text/javascript" src="https://unpkg.com/jquery@3.3.1/dist/jquery.min.js"></script>
  9. <script src="https://unpkg.com/eruda@3.0.0/eruda.js"></script>
  10. <script src="https://cdn.tailwindcss.com"></script>
  11. <script>
  12. tailwind.config = {
  13. corePlugins: {
  14. preflight: false
  15. },
  16. theme: {
  17. extend: {
  18. colors: {
  19. clifford: "#da373d"
  20. }
  21. }
  22. }
  23. };
  24. </script>
  25. <!-- Import style -->
  26. <link rel="stylesheet" href="//unpkg.com/element-plus/dist/index.css" />
  27. <!-- Import Vue 3 -->
  28. <script src="//unpkg.com/vue@3"></script>
  29. <!-- Import component library -->
  30. <script src="//unpkg.com/element-plus"></script>
  31. <script src="//unpkg.com/@element-plus/icons-vue"></script>
  32. <style>
  33. html,
  34. body {
  35. padding: 0;
  36. margin: 0;
  37. }
  38. ::-webkit-scrollbar {
  39. width: 0;
  40. height: 0;
  41. display: none;
  42. }
  43. </style>
  44. </head>
  45. <body class="h-full">
  46. <div id="app" class="h-full">
  47. <el-container class="h-full">
  48. <el-main class="flex flex-col">
  49. <el-alert v-if="name" :title="fileName" type="success" effect="dark" @close="clear"></el-alert>
  50. <el-upload
  51. v-else
  52. class="upload-demo"
  53. drag
  54. v-model:file-list="fileList"
  55. action="/api/chat-pdf/upload"
  56. accept="application/pdf"
  57. :on-success="onSuccess"
  58. >
  59. <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  60. <div class="el-upload__text">请上传客服回答文档</div>
  61. </el-upload>
  62. <div id="list" class="flex flex-col flex-1 overflow-auto">
  63. <div
  64. v-for="(item,i) in conversations"
  65. :key="i"
  66. class="mt-4 p-3 rounded-t-xl"
  67. :class="item.value.role==='system' ? 'mr-10 bg-slate-300 rounded-r-xl' : 'ml-10 bg-neutral-200 rounded-l-xl'"
  68. >
  69. <el-icon v-if="item.value.loading" class="is-loading">
  70. <Loading />
  71. </el-icon>
  72. <span v-else>\{{item.value.content}}</span>
  73. </div>
  74. </div>
  75. </el-main>
  76. <el-footer class="py-4 flex items-end" @keyup.enter.stop.prevent="ask">
  77. <el-input v-model="q" :disabled="!name" placeholder="提问"></el-input>
  78. <el-button class="ml-3" type="primary" :disabled="!name" @click="ask">发送</el-button>
  79. </el-footer>
  80. </el-container>
  81. </div>
  82. </body>
  83. <script>
  84. var app = Vue.createApp({
  85. data() {
  86. return {
  87. name: "",
  88. fileName: "",
  89. fileList: [],
  90. q: "",
  91. conversations: []
  92. };
  93. },
  94. methods: {
  95. onSuccess(res, file) {
  96. console.log(res, file);
  97. this.name = res.name;
  98. this.fileName = file.name;
  99. },
  100. clear() {
  101. this.fileList = [];
  102. this.name = "";
  103. this.fileName = "";
  104. this.q = "";
  105. this.conversations = [];
  106. },
  107. ask(e) {
  108. console.log(this.q);
  109. if (this.q) {
  110. this.conversations.push(
  111. Vue.ref({
  112. role: "user",
  113. content: this.q
  114. })
  115. );
  116. var msg = Vue.ref({
  117. role: "system",
  118. loading: true,
  119. content: ""
  120. });
  121. this.conversations.push(msg);
  122. setTimeout(function () {
  123. $("#list").scrollTop($("#list")[0].scrollHeight);
  124. }, 50);
  125. $.post(
  126. "/api/chat-pdf/customerServiceAsk",
  127. {
  128. name: this.name,
  129. q: this.q
  130. },
  131. function (res) {
  132. console.log(res);
  133. msg.value.loading = false;
  134. msg.value.content = res.answer;
  135. setTimeout(function () {
  136. $("#list").scrollTop($("#list")[0].scrollHeight);
  137. }, 50);
  138. }
  139. );
  140. this.q = "";
  141. }
  142. }
  143. }
  144. });
  145. app.use(ElementPlus);
  146. for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  147. app.component(key, component);
  148. }
  149. app.mount("#app");
  150. </script>
  151. </html>