Home.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. <template>
  2. <div id="app">
  3. <Slider @select-nav="selectNav" :agent_list="agentList" :navId="navId" v-show="!closeOthers"></Slider>
  4. <div class="main">
  5. <div :class="{ 'history-wrap': true, 'history-wrap-open': !closeOthers && navId > -1 }">
  6. <History :list="historyList" :selectId="selectId" @handle-click="selectHistory"
  7. @set-new="handelSetNewChat" />
  8. </div>
  9. <div class="wrap">
  10. <Index v-if="navId === -1" :number="swiperNumber" @select-nav="selectNav" />
  11. <div :class="{ 'border-wrap': true, 'border-no-wrap': navId === -2 }" v-else>
  12. <div :key="dialog_uniq_key">
  13. <!-- 项目与功能特色介绍 -->
  14. <ProjectIntro v-if="!showDialog" :navId="navId" />
  15. <section :class="{ 'section-padding': showDialog }">
  16. <!-- 报告生成 -->
  17. <DocumentCombine v-if="navId == 0 && !showDialog" />
  18. <!-- 报表合并 -->
  19. <Document v-if="navId === 1 && !showDialog" />
  20. <!-- 知识问答 -->
  21. <DocumentInterlocution v-if="navId === 2 && !showDialog" />
  22. <!-- 文档智能 -->
  23. <DocumentAnswer v-if="navId === 3 && !showDialog" :agentId="selectId" />
  24. <!-- 智能问答 -->
  25. <Answer v-if="navId === 4 && !showDialog" />
  26. <!-- 智能数据 -->
  27. <DocumentsmartData v-if="navId === 5 && !showDialog" :agentId="selectId" />
  28. <!-- 小数绘图 -->
  29. <PicArticle v-if="navId === 6 && !showDialog" :agentId="selectId" />
  30. <!-- 文档出卷 -->
  31. <DocumentQuestion v-if="navId === 7 && !showDialog" :agentId="selectId" />
  32. <!-- 出题组卷 -->
  33. <DocumentQuestion2 v-if="navId === 8 && !showDialog" :agentId="selectId" />
  34. <!-- 文库详情 -->
  35. <DocumentDetail v-if="navId === -2" :targetDocument="targetDocument"
  36. :dialogList="dialogList" @go-back="goBack" />
  37. <dialog-wrap v-if="showDialog && initDialog" v-show="!hideDialog" :type="dialogType[navId]"
  38. :isSetting="false" :readonly="readonly" :agentId="selectId" :dialogId="dialogId"
  39. :list="dialogList" @setReadonly="setReadonly" @changeParse="changeParse"
  40. @goDocument="goDocument" />
  41. </section>
  42. <footer
  43. v-if="navId !== -2 && navId !== 0 && navId !== 3 && navId !== 6 && navId !== 1 && navId !== 9 && !historyMode">
  44. <BtnIframeChujuan v-if="navId == 7" />
  45. <message-input :readonly="readonly" eventName="open-dialog" />
  46. </footer>
  47. <footer v-if="navId === 0 && !showDialog" class="upload-footer baogaoshengcheng">
  48. <BtnMangeDoc />
  49. <section v-for="(item, key) in variables" :key="key">
  50. <div>
  51. <p>
  52. <span>{{ item.variable_name }}</span>
  53. </p>
  54. </div>
  55. <div>
  56. <a-input :style="{ flex: '1' }" :placeholder="`请输入${item.variable_name}`"
  57. allow-clear @change="(event) => {
  58. customChange(event, item.node_id, item.variable_name);
  59. }" v-if="item.value_type === 1" />
  60. <a-upload v-else :style="{ width: '300px' }" :multiple="false" :limit="1"
  61. :custom-request="(option) => {
  62. customRequest(option, item.node_id, item.variable_name);
  63. }" :show-upload-button="{ showOnExceedLimit: true }"
  64. accept=".pdf,.doc,.docx,.txt,.md,.ppt.pptx" />
  65. </div>
  66. </section>
  67. <a-textarea :max-length="maxLength" v-model="textValue"
  68. :show-word-limit="textValue.length > maxLength / 2" :auto-size="{ maxRows: 6 }"
  69. placeholder="输入您想了解的内容,Shift+Enter换行" :style="text_area_style">
  70. </a-textarea>
  71. <a-button :style="{ width: '500px' }" type="primary" @click="beginCombine">开始</a-button>
  72. </footer>
  73. <template v-if="navId === 3">
  74. <footer v-if="!showDialog" class="upload-footer wendangzhinengformarea-footer">
  75. <a-upload :file-list="wendangzhineng_file_list" :multiple="true"
  76. :limit="MAX_ACCEPT_FILE" :auto-upload="false"
  77. :show-upload-button="{ showOnExceedLimit: false }"
  78. accept=".pdf,.doc,.docx,.txt,.md,.ppt.pptx" @change="handleFileChange">
  79. <template #upload-button>
  80. <a-tooltip :content="upload_warning_text">
  81. <a-button class="upload-button">
  82. <template #icon>
  83. <icon-upload />
  84. </template>
  85. <template #default>点击上传</template>
  86. </a-button>
  87. </a-tooltip>
  88. </template>
  89. <template #file-name="{ fileItem }">
  90. <a-tooltip :content="fileItem.name">
  91. <span>{{ fileItem.name }}</span>
  92. </a-tooltip>
  93. </template>
  94. </a-upload>
  95. <a-textarea :max-length="maxLength" v-model="wendangzhineng_text_input"
  96. :disabled="parseStatus"
  97. :show-word-limit="wendangzhineng_text_input.length > maxLength / 2"
  98. :auto-size="{ maxRows: 6 }" placeholder="输入您想了解的内容,Shift+Enter换行"
  99. :style="text_area_style" @keyup="handleTextKeyUp">
  100. </a-textarea>
  101. <a-button :style="{ width: '500px' }" type="primary"
  102. @click="beginWendangzhinengCombine">开始</a-button>
  103. </footer>
  104. <footer v-if="showDialog && !historyMode" class="upload-footer">
  105. <a-textarea :max-length="maxLength" v-model="wendangzhineng_text_input"
  106. :disabled="parseStatus"
  107. :show-word-limit="wendangzhineng_text_input.length > maxLength / 2"
  108. :auto-size="{ maxRows: 6 }" placeholder="输入您想了解的内容,Shift+Enter换行"
  109. :style="text_area_style" @keyup="handleTextKeyUp">
  110. </a-textarea>
  111. <a-button :style="{ width: '500px' }" type="primary"
  112. @click="beginWendangzhinengCombine">开始</a-button>
  113. </footer>
  114. </template>
  115. <!-- 小数绘图底部输入栏 -->
  116. <PictureFooter v-if="navId === 6 && !historyMode" :agentId="selectId" />
  117. <!-- 文档报告 -->
  118. <DocumentReportFooter v-if="navId === 9 && !historyMode" :agentId="selectId" />
  119. <!-- 侧边栏切换按钮 -->
  120. <ToggleBtn v-if="navId !== -2" :closeOthers="closeOthers" @toggle="openAll" />
  121. </div>
  122. </div>
  123. </div>
  124. <!-- <right v-if="navId === 0 || navId === 2" /> -->
  125. </div>
  126. </div>
  127. </template>
  128. <script setup>
  129. import { Message } from '@arco-design/web-vue';
  130. import Right from "../components/Right.vue";
  131. import DialogWrap from "../components/DialogWrap.vue";
  132. import Slider from "../components/Slider.vue";
  133. import ProjectIntro from '../components/ProjectIntro.vue';
  134. import History from "../components/History.vue";
  135. import MessageInput from "../components/MessageInput.vue";
  136. import PictureFooter from '../components/PictureFooter.vue';
  137. import DocumentDetail from "./DocumentDetail.vue";
  138. import DocumentCombine from "./DocumentCombine.vue";
  139. import Index from "./Index.vue";
  140. import Answer from "./Answer.vue";
  141. import Document from "./Document.vue";
  142. import PicArticle from "./PicArticle.vue";
  143. import DocumentAnswer from "./DocumentAnswer.vue";
  144. import DocumentsmartData from "./DocumentsmartData.vue";
  145. import DocumentInterlocution from './DocumentInterlocution.vue';
  146. import DocumentQuestion from "./DocumentQuestion.vue";
  147. import DocumentQuestion2 from "./DocumentQuestion2.vue";
  148. import Analysis from "./Analysis.vue";
  149. import ToggleBtn from '../components/ToggleBtn.vue';
  150. import BtnMangeDoc from '../components/btn-manage-doc/BtnMangeDoc.vue';
  151. import DocumentReportFooter from '../components/DocumentReportFooter.vue'
  152. import BtnIframeChujuan from '../components/btn-iframe-chujuan/BtnIframeChujuan.vue'
  153. import { defineComponent, ref, onMounted, inject, onBeforeUnmount, computed } from "vue";
  154. import { wendangzhinengSetTempDocFile, wendangzhinengClearDocFile } from '../components/dialog-wrap/temp-wendangzhineng-docs';
  155. // NOTE: 先把4文库问答的类型改成report类型,后续再改回来
  156. const dialogType = [
  157. "report",
  158. "excel",
  159. "knowledgeQuiz",
  160. // "report",
  161. "wendangzhineng",
  162. "normal",
  163. "smartData",
  164. "huitu", // 小数绘图
  165. "question",
  166. "question",
  167. 'document_report', // 文档报告生成
  168. ];
  169. const { config, helper, ajax } = inject("$global");
  170. const SYSTEM_NAME = config.defaultTitle
  171. const closeOthers = ref(false);
  172. const swiperNumber = ref(5);
  173. const navId = ref(-1);
  174. const readonly = ref(false);
  175. const showDialog = ref(false); // 是否显示对话内容 v-if
  176. const initDialog = ref(false); // 对话是否初始化
  177. const hideDialog = ref(false); // 是否隐藏对话 v-show
  178. const historyMode = ref(false);
  179. const dialogList = ref([]);
  180. const selectId = ref(""); // 当前选择的 agent_id 或者 历史记录的 ID
  181. const real_agent_id = ref(""); // 实际的agent_id,此值仅在 点击侧边栏具体功能时更改,例如点击 知识问答、文档智能按钮时更改
  182. const agentIds = ref([]); // agent ID的列表
  183. const agentList = ref([]);
  184. const dialogId = ref("");
  185. const historyList = ref([]);
  186. const variables = ref([]);
  187. const textValue = ref("");
  188. const parseStatus = ref(false);
  189. const maxLength = ref(6000); // 允许输入的最大长度
  190. const targetDocument = ref(null); // 当前查看详情的文档
  191. const transNavId = ref() //查看详情时记录之前的navId
  192. /**
  193. * 记录各按钮点击时的次数
  194. * 侧边栏,菜单点击
  195. * 历史记录每一项被点击
  196. * 新建对话按钮被点击
  197. * 对应按钮,每点击一下,此处对应数据新增1
  198. * 以此可以维护一个唯一的key
  199. */
  200. const count_menu_nav_click = ref(0);
  201. const count_his_item_click = ref(0);
  202. const count_btn_create_click = ref(0);
  203. /**
  204. * 会话区域唯一的key
  205. */
  206. const dialog_uniq_key = computed(() => {
  207. return count_menu_nav_click.value + count_his_item_click.value + count_btn_create_click.value;
  208. });
  209. /**
  210. * 更新按钮点击的次数
  211. * @param {String} type - menu/create/history
  212. */
  213. const updateClickCount = (type) => {
  214. if (type === 'ct_menu') {
  215. count_menu_nav_click.value = count_menu_nav_click.value + 1;
  216. }
  217. if (type === 'ct_create') {
  218. count_btn_create_click.value = count_btn_create_click.value + 1;
  219. }
  220. if (type === 'ct_history') {
  221. count_his_item_click.value = count_his_item_click.value + 1;
  222. }
  223. }
  224. let reportData = {};
  225. let agents = {}
  226. const openAll = () => {
  227. closeOthers.value = !closeOthers.value;
  228. };
  229. const setReadonly = (status) => {
  230. readonly.value = status;
  231. };
  232. const changeParse = (status) => {
  233. parseStatus.value = status;
  234. }
  235. const goDocument = (targetDoc) => {
  236. transNavId.value = navId.value
  237. navId.value = -2;
  238. hideDialog.value = true;
  239. targetDocument.value = {...targetDoc };
  240. };
  241. const goBack = () => {
  242. navId.value = transNavId.value;
  243. hideDialog.value = false;
  244. };
  245. /**
  246. * 当点击某个导航时触发的方法
  247. * 例如:点击 知识问答 文档智能 智能问答 智能数据 等
  248. * @params {object} node
  249. * @params {number} node.id - 例如 3 4 5
  250. * @params {string} node.title - 例如:文档智能 小数绘图
  251. */
  252. const selectNav = async (node) => {
  253. navId.value = node.id;
  254. textValue.value = [];
  255. // 关闭历史模式
  256. historyMode.value = false;
  257. readonly.value = false;
  258. if (node.index === -1) {
  259. swiperNumber.value = 5;
  260. } else {
  261. swiperNumber.value = 4;
  262. }
  263. helper.$bus.emit("stop-writing");
  264. showDialog.value = false;
  265. // 获取当前选定的agent对应的ID
  266. selectId.value = (agents.find(agent => agent.name === node.title) || {}).id || null;
  267. real_agent_id.value = selectId.value; // 记录agent_id值
  268. /**
  269. * 导航切换
  270. * 清空文档智能的数据
  271. */
  272. wendangzhineng_file_uploaded.value = false;
  273. wendangzhineng_text_input.value = '';
  274. wendangzhineng_file_list.value = [];
  275. wendangzhinengClearDocFile();
  276. // 获取历史记录
  277. const data = await ajax.message.getDialogs(selectId.value);
  278. // if (navId.value === 0 || navId.value === 3) {
  279. // const result = await ajax.agent.getVariables(selectId.value);
  280. // variables.value = result;
  281. // reportData = {};
  282. // }
  283. if (data && Array.isArray(data)) {
  284. historyList.value = data.map((value) => {
  285. return {
  286. content: value.name,
  287. id: value.id,
  288. time: value.update_date,
  289. workflow: value.workflow
  290. };
  291. });
  292. }
  293. // 每次切换功能板块时,清空sendData数据
  294. // helper.write('sendData', {});
  295. clearLocalStorageSendData();
  296. updateClickCount('ct_menu');
  297. };
  298. /**
  299. * 选择某个历史记录
  300. * @params {string} id - 历史记录对应的ID
  301. */
  302. const selectHistory = async (id) => {
  303. showDialog.value = true;
  304. // 历史记录对话模式,不调用对话ID接口
  305. historyMode.value = true;
  306. readonly.value = true;
  307. selectId.value = id;
  308. helper.$bus.emit("set-loading", true);
  309. helper.$bus.emit("stop-writing");
  310. initDialog.value = false;
  311. // 历史记录 通过当前name取id
  312. const name = config.slider.find(item => item.id === navId.value).title
  313. const agentsId = agents.find(agent => agent.name === name).id;
  314. const data = await ajax.message.getHistoryLogs(agentsId, id);
  315. if (data && Array.isArray(data) && data.length > 0) {
  316. dialogList.value = data
  317. } else {
  318. dialogList.value = []
  319. }
  320. initDialog.value = true;
  321. helper.$bus.emit("set-loading", false);
  322. updateClickCount('ct_history');
  323. };
  324. const beginCombine = async () => {
  325. let report_name = "";
  326. let inputData = [];
  327. for (let key in reportData) {
  328. /**
  329. * 此部分代码于 2024/11/25日上午做了简单优化
  330. * 优化时,仅调整了循环体内的代码
  331. * 由于此功能暂时禁用,无法测试优化后的效果是否正常
  332. * 如果后续测试时发现代码异常,可copy此时间之前的原代码
  333. */
  334. const cur_report = reportData[key];
  335. const report_key = cur_report.key;
  336. const report_value = cur_report.value;
  337. const item = {
  338. id: key,
  339. name: report_key,
  340. };
  341. if (typeof report_value === "string") {
  342. report_name += `${report_key}:${report_value}\n`;
  343. item.file_path = '';
  344. item.value = report_value;
  345. } else {
  346. report_name += `${report_key}:${report_value.name}\n`;
  347. item.file_path = report_value.url;
  348. item.value = '';
  349. }
  350. inputData.push(item);
  351. }
  352. // 如果不是历史记录对话模式,则创建对话
  353. if (!historyMode.value) {
  354. const data = await ajax.message.createDialog(selectId.value);
  355. if (data) {
  356. dialogId.value = data.chat_id;
  357. }
  358. }
  359. dialogList.value = [];
  360. showDialog.value = true;
  361. initDialog.value = true;
  362. const sendData = {
  363. chatHistory: [],
  364. message: textValue.value,
  365. name: "报告生成",
  366. description: "报告生成",
  367. inputs: {
  368. report_name,
  369. id: "Report-PRcYL",
  370. data: inputData
  371. }
  372. };
  373. setTimeout(() => {
  374. helper.$bus.emit("send-message", sendData);
  375. }, 500);
  376. };
  377. const continueCombine = async () => {
  378. const sendData = {
  379. chatHistory: [],
  380. name: "报告生成",
  381. description: "报告生成",
  382. inputs: {
  383. report_name: textValue.value,
  384. id: "Report-PRcYL",
  385. query: textValue.value,
  386. }
  387. };
  388. setTimeout(() => {
  389. helper.$bus.emit("send-message", sendData);
  390. textValue.value = "";
  391. }, 500);
  392. };
  393. const customChange = (event, key, value) => {
  394. reportData[key] = {
  395. key: value,
  396. value: event
  397. };
  398. };
  399. /**
  400. * 文档智能上传文件
  401. * @param option
  402. * @param key
  403. * @param value
  404. */
  405. const customRequest = async (option, key, value) => {
  406. const { onSuccess, fileItem } = option;
  407. const { file, uid, name } = fileItem;
  408. const fileList = [];
  409. fileList.push({
  410. id: uid,
  411. file
  412. });
  413. onSuccess();
  414. const formData = new FormData();
  415. fileList.forEach((item) => {
  416. formData.append("file", item.file);
  417. });
  418. const data = await ajax.file.uploadFiles(selectId.value, formData);
  419. reportData[key] = {
  420. key: value,
  421. value: {
  422. name,
  423. url: data.file_path
  424. }
  425. };
  426. };
  427. onMounted(async () => {
  428. agents = await ajax.agent.getAgents();
  429. agentList.value = agents;
  430. agentIds.value = agents && Array.isArray(agents) && agents.map((data) => data.id) || [];
  431. helper.$bus.on("open-dialog", async (value) => {
  432. // 如果不是历史记录对话模式,则创建对话
  433. if (!historyMode.value) {
  434. const data = await ajax.message.createDialog(selectId.value);
  435. dialogId.value = data.chat_id;
  436. }
  437. dialogList.value = [];
  438. showDialog.value = true;
  439. initDialog.value = true;
  440. // TODO
  441. setTimeout(() => {
  442. helper.$bus.emit("send-message", value);
  443. }, 200);
  444. });
  445. });
  446. onBeforeUnmount(() => {
  447. helper.$bus.off("open-dialog");
  448. });
  449. /**
  450. * 点击新建对话按钮
  451. */
  452. const handelSetNewChat = () => {
  453. selectId.value = real_agent_id.value;
  454. showDialog.value = false;
  455. historyMode.value = false;
  456. setReadonly(false);
  457. // 清空文档智能相关的数据
  458. wendangzhineng_file_uploaded.value = false;
  459. wendangzhineng_text_input.value = '';
  460. wendangzhineng_file_list.value = [];
  461. wendangzhinengClearDocFile();
  462. // 每次新建对话时,清空sendData数据
  463. clearLocalStorageSendData();
  464. updateClickCount('ct_create');
  465. };
  466. function clearLocalStorageSendData() {
  467. // helper.write('sendData', {});
  468. }
  469. const text_area_style = {
  470. flex: 1,
  471. borderRadius: '12px',
  472. marginTop: '20px',
  473. padding: '0px 30px 0 16px',
  474. background: 'transparent',
  475. border: '1px solid #e3e3e3',
  476. minHeight: '120px',
  477. paddingBottom: `${textValue.value.length > maxLength.value / 2 ? '20px' : ''}`
  478. };
  479. /**
  480. * 文档智能相关内容处理
  481. */
  482. /**
  483. * 文件上传操作
  484. */
  485. const MAX_ACCEPT_FILE = 5;
  486. const upload_warning_text = `支持上传文件pdf、docx文档(最多${MAX_ACCEPT_FILE}个,每个大小不超过10MB)`;
  487. const wendangzhineng_file_list = ref([]);
  488. const wendangzhineng_text_input = ref('');
  489. const wendangzhineng_file_uploaded = ref(false);
  490. const wendangzhineng_is_loading = ref(false);
  491. /**
  492. * 文件数据变化
  493. * @param fileList
  494. */
  495. const handleFileChange = (fileList) => {
  496. wendangzhineng_file_list.value = fileList;
  497. }
  498. const getFIleParams = () => {
  499. const formData = new FormData();
  500. const f_list = wendangzhineng_file_list.value;
  501. f_list.forEach((item) => {
  502. const file = item.file;
  503. formData.append("file", file);
  504. });
  505. return formData;
  506. }
  507. const showMsg = (msg) => {
  508. Message.error({ content: msg, position: 'bottom' });
  509. }
  510. const beginWendangzhinengCombine = async () => {
  511. if (wendangzhineng_is_loading.value) {
  512. return;
  513. }
  514. wendangzhineng_is_loading.value = true;
  515. // 文档智能
  516. const title = wendangzhineng_text_input.value; // 标题
  517. const f_list = wendangzhineng_file_list.value;
  518. let sendData = null;
  519. if (!wendangzhineng_file_uploaded.value) {
  520. // 文件未上传
  521. if (f_list.length === 0) {
  522. showMsg('请选择文件');
  523. return;
  524. }
  525. if (!title) {
  526. showMsg('请输入内容');
  527. return;
  528. }
  529. showDialog.value = true;
  530. // 创建会话
  531. const data = await ajax.message.createDialog(selectId.value);
  532. if (data) {
  533. dialogId.value = data.chat_id;
  534. }
  535. // 上传文件
  536. const fm_data = getFIleParams();
  537. const uploadResult1 = await ajax.file.uploadFiles(real_agent_id.value, fm_data);
  538. const files_info = uploadResult1.files; // 数组
  539. const file_id_list = files_info.map(item => item.id);
  540. sendData = {
  541. message: title,
  542. upload_file_id: file_id_list
  543. }
  544. /**
  545. * 在内存中保存上传的文件
  546. * 供对话时界面上显示
  547. */
  548. wendangzhinengSetTempDocFile({
  549. client_files: f_list,
  550. server_files: files_info
  551. });
  552. } else {
  553. // 已上传,无需再上传
  554. // 再次提问
  555. if (!title) {
  556. showMsg('请输入内容');
  557. return;
  558. }
  559. showDialog.value = true;
  560. // 创建会话
  561. const data = await ajax.message.createDialog(selectId.value);
  562. if (data) {
  563. dialogId.value = data.chat_id;
  564. }
  565. sendData = {
  566. message: title,
  567. }
  568. }
  569. wendangzhineng_file_uploaded.value = true;
  570. // wendangzhineng_text_input.value = '';
  571. // wendangzhineng_file_list.value = [];
  572. dialogList.value = [];
  573. // showDialog.value = true;
  574. initDialog.value = true;
  575. setTimeout(() => {
  576. helper.$bus.emit("send-message", sendData);
  577. wendangzhineng_text_input.value = '';
  578. wendangzhineng_is_loading.value = false;
  579. }, 500);
  580. };
  581. /**
  582. * 移除文本中的换行符
  583. */
  584. const removeBreakLineFlag = () => {
  585. wendangzhineng_text_input.value = wendangzhineng_text_input.value.replace(/\n/, '');
  586. };
  587. /**
  588. * 用户按键事件
  589. * @param e
  590. */
  591. const handleTextKeyUp = (e) => {
  592. if (e.keyCode === 13) {
  593. if (e.ctrlKey) {
  594. // 此时也按下Ctrl:换行处理
  595. } else {
  596. // 此时没有按下Ctrl
  597. removeBreakLineFlag();
  598. beginWendangzhinengCombine();
  599. }
  600. }
  601. };
  602. </script>
  603. <style lang="scss" scoped>
  604. .main {
  605. .upload-footer {
  606. margin-bottom: 50px;
  607. padding: 20px;
  608. width: 540px;
  609. border: 1px solid #eee;
  610. >section {
  611. >div {
  612. display: flex;
  613. align-items: center;
  614. justify-content: space-between;
  615. width: 500px;
  616. >p {
  617. width: 150px;
  618. margin-right: 10px;
  619. }
  620. }
  621. p {
  622. span {
  623. position: relative;
  624. &:after {
  625. content: "*";
  626. display: block;
  627. color: red;
  628. position: absolute;
  629. right: -10px;
  630. top: -5px;
  631. }
  632. }
  633. }
  634. >p,
  635. >div {
  636. margin: 10px 0;
  637. }
  638. }
  639. }
  640. flex: 1;
  641. position: relative;
  642. display: flex;
  643. .history-wrap {
  644. width: 0px;
  645. opacity: 0;
  646. overflow: hidden;
  647. transition-duration: 0.3s;
  648. transition-property: width;
  649. &-open {
  650. opacity: 1;
  651. width: 260px;
  652. }
  653. }
  654. .wrap {
  655. flex: 1;
  656. }
  657. .border-wrap {
  658. position: relative;
  659. padding: 30px 16px 30px 40px;
  660. flex: 1;
  661. height: 100%;
  662. &.border-no-wrap {
  663. padding: 0;
  664. >div {
  665. padding: 0;
  666. >section.section-padding {
  667. padding: 0;
  668. }
  669. }
  670. }
  671. >div {
  672. width: 100%;
  673. height: 100%;
  674. background: #fff;
  675. box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.03);
  676. border-radius: 14px;
  677. display: flex;
  678. flex-direction: column;
  679. padding-left: 32px;
  680. position: relative;
  681. >div {
  682. position: absolute;
  683. bottom: -10px;
  684. left: -10px;
  685. z-index: 10;
  686. width: 38px;
  687. height: 38px;
  688. border-radius: 20px;
  689. background: #fff;
  690. display: flex;
  691. align-items: center;
  692. justify-content: center;
  693. cursor: pointer;
  694. }
  695. // >header {
  696. // >div {
  697. // display: inline-block;
  698. // margin-top: 20px;
  699. // >img {
  700. // transform: translateX(-12px);
  701. // }
  702. // >p {
  703. // font-size: 36px;
  704. // font-weight: bold;
  705. // color: #000;
  706. // >span {
  707. // font-weight: bold;
  708. // background: linear-gradient(180deg, #41d98c, #31c4c9);
  709. // -webkit-background-clip: text;
  710. // -webkit-text-fill-color: transparent;
  711. // }
  712. // }
  713. // >span {
  714. // display: block;
  715. // color: #000;
  716. // font-size: 15px;
  717. // margin: 5px 0 32px;
  718. // }
  719. // }
  720. // }
  721. >section {
  722. flex: 1;
  723. overflow: hidden;
  724. &.section-padding {
  725. padding-right: 32px;
  726. padding-bottom: 50px;
  727. }
  728. }
  729. >footer {}
  730. }
  731. }
  732. }
  733. footer.baogaoshengcheng{
  734. position: relative;
  735. }
  736. </style>
  737. <style>
  738. .wendangzhinengformarea-footer .arco-upload-icon.arco-upload-icon-start {
  739. display: none;
  740. }
  741. .wendangzhinengformarea-footer .arco-upload-progress {
  742. display: none;
  743. }
  744. .wendangzhinengformarea-footer .arco-upload-list.arco-upload-list-type-text,
  745. .wendangzhinengformarea-footer .arco-upload-list.arco-upload-list-type-picture {
  746. width: 100%;
  747. max-height: 400px;
  748. overflow-y: auto;
  749. padding-right: 5px;
  750. }
  751. </style>