index.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. <template>
  2. <h2 style="text-align: center; margin: 18px 0;font-size: 25px;font-family: 'Source Sans Pro', 'ui-sans-serif', 'system-ui', sans-serif;">ChatGLM</h2>
  3. <div class="chatbg tool">
  4. <div
  5. style="float: left; font-size: 12px;padding: 4px 8px;border-right: 1px solid #e5e7eb;border-bottom: 1px solid #e5e7eb;border-bottom-right-radius: 7px;"
  6. >
  7. <el-icon><ChatDotRound /></el-icon>
  8. Chatbot
  9. </div>
  10. <div style="clear: both"></div>
  11. <div class="chatGptChat" ref="chatEle">
  12. <div v-for="(item, index) in chat" :key="index">
  13. <div v-if="item.type === 'robot'" class="chat">
  14. <div class="cahtText">
  15. <textShow :text="item.text" />
  16. </div>
  17. </div>
  18. <div v-if="item.type === 'user'" class="chat chatRight">
  19. <div class="cahtText" v-text="item.text"></div>
  20. </div>
  21. <div style="clear: both"></div>
  22. </div>
  23. </div>
  24. </div>
  25. <div class="tool">
  26. <el-row :gutter="15">
  27. <el-col :span="16">
  28. <el-input
  29. v-model="inputText"
  30. :rows="10"
  31. type="textarea"
  32. placeholder="请输入您的问题"
  33. />
  34. <el-button
  35. style="
  36. width: 100%;
  37. color: #ea580c;
  38. font-weight: 600;
  39. font-size: 16px;
  40. margin-top: 1em;
  41. "
  42. :loading="load"
  43. color="#fdba74"
  44. size="large"
  45. @click="saveText"
  46. >
  47. 提交
  48. </el-button>
  49. </el-col>
  50. <el-col :span="8">
  51. <el-button
  52. style="width: 100%; margin-bottom: 1em"
  53. color="#f3f4f6"
  54. size="large"
  55. @click="chat = []"
  56. >
  57. 清除历史记录
  58. </el-button>
  59. <div class="tools">
  60. <div class="toolsItem">
  61. 最大长度
  62. <el-input-number
  63. style="float: right"
  64. v-model="num"
  65. :min="0"
  66. :max="4096"
  67. @change="change"
  68. controls-position="right"
  69. size="small"
  70. />
  71. <input
  72. :value="0"
  73. type="range"
  74. id="num"
  75. style="width: 100%"
  76. @input="input"
  77. />
  78. </div>
  79. <div class="line"></div>
  80. <div class="toolsItem">
  81. Top P
  82. <el-input-number
  83. style="float: right"
  84. v-model="num1"
  85. :min="0"
  86. :max="1"
  87. :step="0.01"
  88. @change="change1"
  89. controls-position="right"
  90. size="small"
  91. />
  92. <input
  93. :value="0"
  94. type="range"
  95. id="num1"
  96. style="width: 100%"
  97. @input="input1"
  98. />
  99. </div>
  100. <div class="line"></div>
  101. <div class="toolsItem">
  102. 感情度
  103. <el-input-number
  104. style="float: right"
  105. v-model="num2"
  106. :min="0"
  107. :max="1"
  108. :step="0.01"
  109. @change="change2"
  110. controls-position="right"
  111. size="small"
  112. />
  113. <input
  114. :value="0"
  115. type="range"
  116. id="num2"
  117. style="width: 100%"
  118. @input="input2"
  119. />
  120. </div>
  121. </div>
  122. </el-col>
  123. </el-row>
  124. </div>
  125. </template>
  126. <script setup>
  127. import { createSocket } from '@/utils/socket';
  128. import { ChatDotRound } from '@element-plus/icons-vue';
  129. import { ref, nextTick, onMounted } from 'vue';
  130. import textShow from './textShow.vue';
  131. const chat = ref([]);
  132. const load = ref(false);
  133. const chatEle = ref(null);
  134. const inputText = ref('');
  135. const num = ref(2048);
  136. const num1 = ref(0.7);
  137. const num2 = ref(0.95);
  138. let chatlist = ref([]);
  139. function saveText() {
  140. load.value = true;
  141. nextTick(() => {
  142. // 滚动到最底层
  143. if (chatEle.value.scrollHeight > chatEle.value.clientHeight) {
  144. chatEle.value.scrollTop = chatEle.value.scrollHeight;
  145. }
  146. });
  147. chat.value.push({
  148. text: inputText.value,
  149. type: 'user',
  150. });
  151. chat.value.push({
  152. text: '',
  153. type: 'robot',
  154. });
  155. const idnex = chatlist.value.length === 0 ? 0 : chatlist.value.length - 1;
  156. const t = inputText.value;
  157. inputText.value = '';
  158. createSocket(ws => {
  159. const data = ws.data || {};
  160. let session_hash = Math.random().toString(36).substring(2);
  161. if (data.msg == 'send_hash')
  162. ws.ws.send(
  163. JSON.stringify({
  164. fn_index: idnex,
  165. session_hash,
  166. })
  167. );
  168. if (data.msg == 'send_data')
  169. ws.ws.send(
  170. JSON.stringify({
  171. fn_index: idnex,
  172. data: [t, chatlist.value, num.value, num1.value, num2.value, null],
  173. event_data: null,
  174. session_hash,
  175. })
  176. );
  177. if (data.msg == 'process_generating') {
  178. const li = data.output.data[0] || [];
  179. const olist = li[li.length - 1];
  180. chat.value[chat.value.length - 1].text = olist[1];
  181. }
  182. if (data.msg == 'process_completed') {
  183. chatlist.value = data.output.data[0] || [];
  184. load.value = false;
  185. }
  186. });
  187. }
  188. const input = e => {
  189. num.value = Math.floor((e.target.value / 100) * 4096);
  190. };
  191. const change = () => {
  192. document.querySelector('#num').value =
  193. ((num.value / 4096) * 100).toFixed(0) - 0;
  194. };
  195. const input1 = e => {
  196. num1.value = e.target.value / 100;
  197. };
  198. const change1 = () => {
  199. document.querySelector('#num1').value = num1.value * 100;
  200. };
  201. const input2 = e => {
  202. num2.value = e.target.value / 100;
  203. };
  204. const change2 = () => {
  205. document.querySelector('#num2').value = num2.value * 100;
  206. };
  207. onMounted(() => {
  208. change();
  209. change1();
  210. change2();
  211. });
  212. </script>
  213. <style>
  214. .chatbg {
  215. min-height: 3em;
  216. border-radius: 8px;
  217. overflow: hidden;
  218. border: 1px solid #e5e7eb;
  219. }
  220. .chatGptChat {
  221. padding-top: 5px;
  222. box-sizing: border-box;
  223. font-weight: 500;
  224. margin: 1em auto 0 auto;
  225. width: 100%;
  226. height: auto;
  227. max-height: 480px;
  228. position: relative;
  229. overflow-y: auto;
  230. padding: 0 1em;
  231. }
  232. .chatGptChat .van-field {
  233. background-color: #eee;
  234. position: fixed;
  235. padding-bottom: 1em;
  236. bottom: 0;
  237. left: 0;
  238. }
  239. .chatGptChat .van-field .van-field__control {
  240. background-color: #ffffff;
  241. padding: 0.4em;
  242. }
  243. .chatGptChat .chat {
  244. padding: 8px 12px;
  245. background-color: #f4f4f680;
  246. border-radius: 22px;
  247. border: 1px solid #e5e7eb;
  248. width: 98%;
  249. border-bottom-left-radius: 0;
  250. margin-bottom: 1em;
  251. }
  252. .chatGptChat .chat .cahtText {
  253. text-align: left;
  254. line-height: 1.5em;
  255. border-radius: 5px;
  256. padding: 0.5em;
  257. display: inline-block;
  258. max-width: calc(100% - 40px);
  259. vertical-align: middle;
  260. }
  261. .chatGptChat .chat .van-image {
  262. vertical-align: top;
  263. }
  264. .chatGptChat .chat .cahtText:not(:last-child),
  265. .chatGptChat .chat .van-image:not(:last-child) {
  266. margin-right: 5px;
  267. }
  268. .chatGptChat .chatRight {
  269. border-color: #fdba74;
  270. background-color: #fff7ed;
  271. border-bottom-right-radius: 0;
  272. border-bottom-left-radius: 22px;
  273. float: right;
  274. }
  275. .tool {
  276. width: 100%;
  277. margin: 1em auto 0 auto;
  278. }
  279. @media (min-width: 640px) {
  280. .chatGptChat,
  281. .tool {
  282. max-width: 608px;
  283. }
  284. }
  285. @media (min-width: 768px) {
  286. .chatGptChat,
  287. .tool {
  288. max-width: 736px;
  289. }
  290. }
  291. @media (min-width: 1024px) {
  292. .chatGptChat,
  293. .tool {
  294. max-width: 992px;
  295. }
  296. }
  297. @media (min-width: 1280px) {
  298. .chatGptChat,
  299. .tool {
  300. max-width: 1248px;
  301. }
  302. }
  303. @media (min-width: 1536px) {
  304. .chatGptChat,
  305. .tool {
  306. max-width: 1504px;
  307. }
  308. }
  309. .tools {
  310. border-radius: 8px;
  311. border: 1px solid #e5e7eb;
  312. line-height: 1.5em;
  313. }
  314. .toolsItem {
  315. padding: 10px 12px;
  316. font-size: 14px;
  317. font-weight: 400;
  318. color: #6b7280;
  319. }
  320. .line {
  321. height: 1px;
  322. background-color: #e5e7eb;
  323. }
  324. </style>