|
|
@@ -0,0 +1,284 @@
|
|
|
+<template>
|
|
|
+ <div class="dialog-chat-answer-content">
|
|
|
+ <div v-if="is_loading && type == 'bgsc'" class="loading"><a-spin></a-spin> <span>报告生成中...</span></div>
|
|
|
+ <div v-if="is_loading && type == 'znws'" class="loading"><a-spin></a-spin> <span>正在思考中...</span></div>
|
|
|
+ <div class="answer-content-text answer-content-report" v-for="(item, index) in result_list" :key="index">
|
|
|
+ <div ref="answerRef" class="answer-content" v-if="typeof item === 'string'" v-html="renderHtml(item)"></div>
|
|
|
+ <HomeChart v-if="typeof item === 'object' && item.type != 'excel'" :origin="'home'" :data="item"></HomeChart>
|
|
|
+ </div>
|
|
|
+ <slot></slot>
|
|
|
+ <div class="report-loading" v-if="answer_status === 1">
|
|
|
+ <img src="../../assets/chat-report/report-ing.png" alt="" />
|
|
|
+ <!-- <span>报告生成中...</span> -->
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- <div v-html="html_1"></div> -->
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, computed, watch, onMounted, render, h } from 'vue';
|
|
|
+import HomeChart from '../chat_echart/HomeChart.vue';
|
|
|
+import marked from '../../3rd-libs/marked';
|
|
|
+import { Tooltip } from '@arco-design/web-vue';
|
|
|
+import { IconDownload } from '@arco-design/web-vue/es/icon';
|
|
|
+import * as XLSX from 'xlsx';
|
|
|
+// import TableHasDownload from '../chat_files/TableHasDownload.vue';
|
|
|
+// 接收markdown数据,进行一些转换
|
|
|
+const props = defineProps({
|
|
|
+ /**
|
|
|
+ * 内容类型
|
|
|
+ */
|
|
|
+ type: String,
|
|
|
+ /**
|
|
|
+ * 文本内容数组
|
|
|
+ */
|
|
|
+ result_list: Array,
|
|
|
+ /**
|
|
|
+ * 状态值
|
|
|
+ */
|
|
|
+ is_loading: Boolean,
|
|
|
+ /**
|
|
|
+ * 会话状态
|
|
|
+ * */
|
|
|
+ answer_status: Boolean
|
|
|
+});
|
|
|
+const answerRef = ref(null);
|
|
|
+const exportButtonList = ref([]);
|
|
|
+
|
|
|
+const content_style = computed(() => {
|
|
|
+ if (props.type === 'q') {
|
|
|
+ return {
|
|
|
+ background: 'var(--primary-default)',
|
|
|
+ color: '#fff'
|
|
|
+ };
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const renderHtml = (item) => {
|
|
|
+ let renderContent = marked.parse(item);
|
|
|
+ renderContent = renderContent.replace(/^ {2}/gm, ' ');
|
|
|
+ renderContent = renderContent
|
|
|
+ .replace(/<p>(.*?)<\/p>/gs, (match, content) => {
|
|
|
+ return `<p class="indented" style="text-indent: 2em;">${content}</p>`;
|
|
|
+ // return `<p>${content}</p>`
|
|
|
+ })
|
|
|
+ .replace(/<br\s*\/?>([^<]*)/g, (match, content) => {
|
|
|
+ if (content.trim() === '') return match;
|
|
|
+ return `<br/><span style="display:inline-block;text-indent:2em;">${content}</span>`;
|
|
|
+ });
|
|
|
+ renderContent = renderContent
|
|
|
+ .replace(/<pre><code>/gs, '<p style="text-indent: 2em;">')
|
|
|
+ .replace(/<\/code><\/pre>/gs, '</p>');
|
|
|
+ return renderContent;
|
|
|
+};
|
|
|
+
|
|
|
+const createSingTableExportBtn = (table, index) => {
|
|
|
+ // table.style.display = 'none';
|
|
|
+ // 创建按钮容器
|
|
|
+ const btnContainer = document.createElement('div');
|
|
|
+ btnContainer.className = 'arco-export-btn';
|
|
|
+ btnContainer.dataset.tableIndex = index; //标记表格索引
|
|
|
+ console.log(btnContainer, 112121);
|
|
|
+ // 渲染组件
|
|
|
+ render(
|
|
|
+ h(
|
|
|
+ Tooltip,
|
|
|
+ { content: `导出表格${index + 1}` },
|
|
|
+ {
|
|
|
+ default: () =>
|
|
|
+ h(IconDownload, {
|
|
|
+ size: 18,
|
|
|
+ style: { cursor: 'pointer', color: 'var(--color-primary)' },
|
|
|
+ onClick: () => handleSingleTableExport(table, index)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ btnContainer
|
|
|
+ );
|
|
|
+ // setTimeout(() => {
|
|
|
+ // console.log(table.parentNode, 99);
|
|
|
+ if (table.nextSibling) {
|
|
|
+ table.parentNode.insertBefore(btnContainer, table.nextSibling);
|
|
|
+ } else {
|
|
|
+ table.parentNode.appendChild(btnContainer);
|
|
|
+ }
|
|
|
+
|
|
|
+ // }, 30);
|
|
|
+
|
|
|
+ exportButtonList.value.push(btnContainer);
|
|
|
+};
|
|
|
+const handleSingleTableExport = (table, tableIndex) => {
|
|
|
+ const workbook = XLSX.utils.book_new();
|
|
|
+ const worksheet = XLSX.utils.table_to_sheet(table);
|
|
|
+ // 添加工作表到工作簿
|
|
|
+ XLSX.utils.book_append_sheet(workbook, worksheet, `表格${tableIndex + 1}数据`);
|
|
|
+
|
|
|
+ // 生成并下载Excel文件
|
|
|
+ XLSX.writeFile(workbook, `表格${tableIndex + 1}_数据导出.xlsx`);
|
|
|
+};
|
|
|
+watch(
|
|
|
+ () => props.answer_status,
|
|
|
+ (new_value) => {
|
|
|
+ // console.log('变化', props.answer_status);
|
|
|
+ if (props.type == 'znws' && new_value / 1 == 2) {
|
|
|
+ setTimeout(() => {
|
|
|
+ const tableContainers = document.querySelectorAll('.answer-content');
|
|
|
+ console.log(tableContainers);
|
|
|
+ const tableContainers_filter = Array.from(tableContainers).filter((item) => !item.getAttribute('data-table'));
|
|
|
+ const allTables = [];
|
|
|
+ tableContainers_filter.forEach((item) => {
|
|
|
+ item.setAttribute('data-table', '1');
|
|
|
+ if (item.querySelectorAll('table') && item.querySelectorAll('table').length) {
|
|
|
+ allTables.push(...Array.from(item.querySelectorAll('table')));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!allTables || !allTables.length) return;
|
|
|
+ Array.from(allTables).forEach((table, index) => {
|
|
|
+ createSingTableExportBtn(table, index);
|
|
|
+ });
|
|
|
+ // const tableContainer = answerRef.value;
|
|
|
+ // tableContainer.setAttribute('data-table', '1');
|
|
|
+ // const allTables = tableContainer?.querySelectorAll('table');
|
|
|
+ // console.log(allTables, 111);
|
|
|
+ // if (!allTables || !allTables.length) return;
|
|
|
+ // Array.from(allTables).forEach((table, index) => {
|
|
|
+ // createSingTableExportBtn(table, index);
|
|
|
+ // });
|
|
|
+ }, 1000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+onMounted(() => {
|
|
|
+ if (props.result_list && props.result_list.length) {
|
|
|
+ if (props.type == 'znws') {
|
|
|
+ const tableContainers = document.querySelectorAll('.answer-content');
|
|
|
+ console.log(tableContainers);
|
|
|
+ const tableContainers_filter = Array.from(tableContainers).filter((item) => !item.getAttribute('data-table'));
|
|
|
+ const allTables = [];
|
|
|
+ tableContainers_filter.forEach((item) => {
|
|
|
+ item.setAttribute('data-table', '1');
|
|
|
+ if (item.querySelectorAll('table') && item.querySelectorAll('table').length) {
|
|
|
+ allTables.push(...Array.from(item.querySelectorAll('table')));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // const allTables = tableContainer?.querySelectorAll('table');
|
|
|
+ if (!allTables || !allTables.length) return;
|
|
|
+ Array.from(allTables).forEach((table, index) => {
|
|
|
+ createSingTableExportBtn(table, index);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="css" scoped>
|
|
|
+.dialog-chat-answer-content {
|
|
|
+ position: relative;
|
|
|
+ background-color: var(--color-bg-1);
|
|
|
+ color: var(--color-text-1);
|
|
|
+ border-radius: 12px;
|
|
|
+
|
|
|
+ padding-top: 15px;
|
|
|
+ padding-bottom: 15px;
|
|
|
+ padding-left: 30px;
|
|
|
+ padding-right: 30px;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-content-report .answer-content * p {
|
|
|
+ text-indent: 2em !important;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-content * p {
|
|
|
+ text-indent: 2em !important;
|
|
|
+}
|
|
|
+
|
|
|
+p {
|
|
|
+ text-indent: 2em !important;
|
|
|
+}
|
|
|
+
|
|
|
+.dialog-chat-answer-content code {
|
|
|
+ overflow-x: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-content-text {
|
|
|
+ line-height: 24px;
|
|
|
+}
|
|
|
+
|
|
|
+.loading {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10px;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style>
|
|
|
+.refferences {
|
|
|
+ background: rgb(238, 243, 254);
|
|
|
+ border: 1px solid rgb(255, 255, 255);
|
|
|
+ box-shadow: rgba(29, 48, 91, 0.2) 0px 1px 1px 0px;
|
|
|
+
|
|
|
+ padding: 2px 6px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.refferences:hover {
|
|
|
+ background-color: var(--primary-default);
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.indented br + * {
|
|
|
+ display: inline-block;
|
|
|
+ text-indent: 2em;
|
|
|
+}
|
|
|
+.report-loading {
|
|
|
+ margin-top: 10px;
|
|
|
+}
|
|
|
+.report-loading img {
|
|
|
+ width: 32px;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style>
|
|
|
+/* 表格基础样式 */
|
|
|
+.answer-content-text table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse; /* 合并边框 */
|
|
|
+ border-spacing: 0;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 1.5;
|
|
|
+}
|
|
|
+
|
|
|
+/* 表头样式 */
|
|
|
+.answer-content-text th {
|
|
|
+ padding: 12px 16px;
|
|
|
+ background-color: #f5f5f5; /* 浅灰色背景 */
|
|
|
+ border: 1px solid #e8e8e8; /* 边框颜色 */
|
|
|
+ font-weight: 500;
|
|
|
+ text-align: center; /* 表头文字居中 */
|
|
|
+}
|
|
|
+
|
|
|
+/* 单元格样式 */
|
|
|
+.answer-content-text td {
|
|
|
+ padding: 12px 16px;
|
|
|
+ border: 1px solid #e8e8e8;
|
|
|
+ text-align: left; /* 默认左对齐,会被Markdown的对齐方式覆盖 */
|
|
|
+}
|
|
|
+
|
|
|
+/* 隔行变色(可选) */
|
|
|
+.answer-content-text tr:nth-child(even) {
|
|
|
+ background-color: #fafafa;
|
|
|
+}
|
|
|
+
|
|
|
+/* 鼠标悬停效果(可选) */
|
|
|
+.answer-content-text tr:hover {
|
|
|
+ background-color: #f0f7ff;
|
|
|
+}
|
|
|
+.arco-export-btn {
|
|
|
+ margin: 8px 0 24px 0;
|
|
|
+ display: inline-block;
|
|
|
+}
|
|
|
+.arco-export-btn :deep(.arco-icon) {
|
|
|
+ transition: color 0.2s ease;
|
|
|
+}
|
|
|
+.arco-export-btn :deep(.arco-icon:hover) {
|
|
|
+ color: var(--primary-default);
|
|
|
+}
|
|
|
+</style>
|