| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720 |
- <template>
- <div id="app">
- <Slider @select-nav="selectNav" :navId="navId" v-show="!closeOthers"></Slider>
- <div class="main">
- <div :class="{ 'history-wrap': true, 'history-wrap-open': !closeOthers && navId > -1 }">
- <History
- :list="historyList"
- :selectId="selectId"
- @handle-click="selectHistory"
- @set-new="handelSetNewChat"
- />
- </div>
- <div class="wrap">
- <Index :number="swiperNumber" v-if="navId === -1" @select-nav="selectNav" />
- <div :class="{ 'border-wrap': true, 'border-no-wrap': navId === -2 }" v-else>
- <div>
- <header v-if="!showDialog">
- <div>
- <img src="@/assets/other/robot.gif" width="52" />
- <p>
- {{ SYSTEM_NAME }}<span>{{ slider.find(item => item.id === navId).title }}</span>
- </p>
- <span>{{ slider.find(item => item.id === navId).dialog }}</span>
- </div>
- </header>
- <section :class="{ 'section-padding': showDialog }">
- <!-- 报告生成 -->
- <DocumentCombine v-if="navId == 0 && !showDialog" />
- <!-- 报表合并 -->
- <Document v-if="navId === 1 && !showDialog" />
- <!-- 知识问答 -->
- <DocumentInterlocution v-if="navId === 2 && !showDialog" />
- <!-- 文档智能 -->
- <DocumentAnswer v-if="navId === 3 && !showDialog" :agentId="selectId" />
- <!-- 智能问答 -->
- <Answer v-if="navId === 4 && !showDialog" />
- <!-- 智能数据 -->
- <DocumentsmartData v-if="navId === 5 && !showDialog" :agentId="selectId" />
- <!-- 小数绘图 -->
- <!-- <PicArticle v-if="navId === 6 && !showDialog" :agentId="selectId" /> -->
- <PicArticle v-if="navId === 6 && !showDialog" :agentId="selectId" />
- <!-- 文档出卷 -->
- <DocumentQuestion v-if="navId === 7 && !showDialog" :agentId="selectId" />
- <DocumentQuestion2 v-if="navId === 8 && !showDialog" :agentId="selectId" />
- <!-- 文库详情 -->
- <DocumentDetail v-if="navId === -2" @go-back="goBack" />
- <dialog-wrap
- v-if="showDialog && initDialog"
- v-show="!hideDialog"
- :type="dialogType[navId]"
- :isSetting="false"
- :readonly="readonly"
- :agentId="selectId"
- :dialogId="dialogId"
- :list="dialogList"
- @setReadonly="setReadonly"
- @changeParse="changeParse"
- @goDocument="goDocument"
- />
- </section>
- <footer v-if="navId !== -2 && navId !== 0 && navId !== 3 && navId !== 6 && !historyMode">
- <BtnIframeChujuan v-if="navId==7"/>
- <message-input :readonly="readonly" eventName="open-dialog" />
- </footer>
- <footer v-if="navId === 0 && !showDialog" class="upload-footer">
- <section v-for="(item, key) in variables" :key="key">
- <div>
- <p>
- <span>{{ item.variable_name }}</span>
- </p>
- </div>
- <div>
- <a-input :style="{ flex: '1' }" :placeholder="`请输入${item.variable_name}`" allow-clear @change="(event) => {
- customChange(event, item.node_id, item.variable_name);
- }
- " v-if="item.value_type === 1" />
- <a-upload v-else :style="{ width: '300px' }" :multiple="false" :limit="1" :custom-request="(option) => {
- customRequest(option, item.node_id, item.variable_name);
- }
- " :show-upload-button="{ showOnExceedLimit: true }" accept=".pdf,.doc,.docx,.txt,.md,.ppt.pptx" />
- </div>
- </section>
- <a-textarea :max-length="maxLength" v-model="textValue"
- :show-word-limit="textValue.length > maxLength / 2" :auto-size="{ maxRows: 6 }"
- placeholder="输入您想了解的内容,Shift+Enter换行" :style="{
- flex: 1,
- borderRadius: '12px',
- marginTop: '20px',
- padding: '0px 30px 0 16px',
- background: 'transparent',
- border: '1px solid #e3e3e3',
- minHeight: '120px',
- paddingBottom: `${textValue.length > maxLength / 2 ? '20px' : ''}`
- }">
- </a-textarea>
- <a-button :style="{ width: '500px' }" type="primary" @click="beginCombine">开始</a-button>
- </footer>
- <footer v-if="navId === 3 && !showDialog" class="upload-footer">
- <section v-for="(item, key) in variables" :key="key">
- <div>
- <p>
- <span>{{ item.variable_name }}</span>
- </p>
- </div>
- <div>
- <a-input :style="{ flex: '1' }" :placeholder="`请输入${item.variable_name}`" allow-clear @change="(event) => {
- customChange(event, item.node_id, item.variable_name);
- }
- " v-if="item.value_type === 1" />
- <a-upload v-else :style="{ width: '300px' }" :multiple="false" :limit="1" :custom-request="(option) => {
- customRequest(option, item.node_id, item.variable_name);
- }
- " :show-upload-button="{ showOnExceedLimit: true }" accept=".pdf,.doc,.docx,.txt,.md,.ppt.pptx" />
- </div>
- </section>
- <a-button :style="{ width: '500px' }" type="primary" @click="beginCombine">开始</a-button>
- </footer>
- <footer v-if="navId === 3 && showDialog && !historyMode" class="upload-footer">
- <a-textarea :max-length="maxLength" v-model="textValue" :disabled="parseStatus"
- :show-word-limit="textValue.length > maxLength / 2" :auto-size="{ maxRows: 6 }"
- placeholder="输入您想了解的内容,Shift+Enter换行" :style="{
- flex: 1,
- borderRadius: '12px',
- marginTop: '20px',
- padding: '0px 30px 0 16px',
- background: 'transparent',
- border: '1px solid #e3e3e3',
- minHeight: '120px',
- paddingBottom: `${textValue.length > maxLength / 2 ? '20px' : ''}`
- }">
- </a-textarea>
- <a-button :style="{ width: '500px' }" type="primary" @click="continueCombine">开始</a-button>
- </footer>
- <!-- <footer v-if="navId === 6 && !historyMode">
- <picture-cards />
- <MessagePicUpload />
- </footer> -->
- <PictureFooter v-if="navId === 6 && !historyMode" :agentId="selectId"/>
- <!-- <a-tooltip :content="closeOthers ? '收起' : '展开'">
- <div @click="openAll" v-if="navId !== -2">
- <img src="@/assets/other/open.svg" width="20" v-if="closeOthers" />
- <img src="@/assets/other/close.svg" width="20" v-else />
- </div>
- </a-tooltip> -->
- <ToggleBtn v-if="navId !== -2" :closeOthers="closeOthers" @toggle="openAll"/>
- </div>
- </div>
- </div>
- <!-- <right v-if="navId === 0 || navId === 2" /> -->
- </div>
- </div>
- </template>
- <script>
- import Right from "../components/Right.vue";
- import DialogWrap from "../components/DialogWrap.vue";
- import Slider from "../components/Slider.vue";
- import History from "../components/History.vue";
- import MessageInput from "../components/MessageInput.vue";
- import PictureCards from '@/components/PictureCards.vue'
- import MessagePicUpload from '../components/MessagePicUpload.vue'
- import PictureFooter from '../components/PictureFooter.vue';
- import DocumentDetail from "./DocumentDetail.vue";
- import DocumentCombine from "./DocumentCombine.vue";
- import Index from "./Index.vue";
- import Answer from "./Answer.vue";
- import Document from "./Document.vue";
- import PicArticle from "./PicArticle.vue";
- import DocumentAnswer from "./DocumentAnswer.vue";
- import DocumentsmartData from "./DocumentsmartData.vue";
- import DocumentInterlocution from './DocumentInterlocution.vue';
- import DocumentQuestion from "./DocumentQuestion.vue";
- import DocumentQuestion2 from "./DocumentQuestion2.vue";
- import Analysis from "./Analysis.vue";
- import ToggleBtn from '../components/ToggleBtn.vue';
- import BtnIframeChujuan from '../components/btn-iframe-chujuan/BtnIframeChujuan.vue'
- import { defineComponent, ref, onMounted, inject, onBeforeUnmount } from "vue";
- export default defineComponent({
- components: {
- Right,
- Slider,
- History,
- Index,
- Answer,
- MessageInput,
- PictureCards,
- MessagePicUpload,
- PictureFooter,
- DialogWrap,
- Document,
- PicArticle,
- DocumentAnswer,
- DocumentsmartData,
- DocumentInterlocution,
- DocumentQuestion,
- DocumentQuestion2,
- Analysis,
- DocumentDetail,
- DocumentCombine,
- ToggleBtn,
- BtnIframeChujuan // 文档出卷按钮
- },
- setup() {
- // NOTE: 先把4文库问答的类型改成report类型,后续再改回来
- const dialogType = [
- "report",
- "excel",
- "knowledgeQuiz",
- "report",
- "normal",
- "smartData",
- "huitu", // 小数绘图
- "question",
- "question"
- ];
- const { config, helper, ajax } = inject("$global");
- const SYSTEM_NAME = config.defaultTitle
- const closeOthers = ref(false);
- const swiperNumber = ref(5);
- const navId = ref(-1);
- const readonly = ref(false);
- const showDialog = ref(false); // 是否显示对话内容 v-if
- const initDialog = ref(false); // 对话是否初始化
- const hideDialog = ref(false); // 是否隐藏对话 v-show
- const historyMode = ref(false);
- const dialogList = ref([]);
- const selectId = ref("");
- const agentIds = ref([]);
- const dialogId = ref("");
- const historyList = ref([]);
- const variables = ref([]);
- const textValue = ref("");
- const parseStatus = ref(false);
- const maxLength = ref(6000);
- let reportData = {};
- let agents = {}
- const openAll = () => {
- closeOthers.value = !closeOthers.value;
- };
- const setReadonly = (status) => {
- readonly.value = status;
- };
- const changeParse = (status) => {
- parseStatus.value = status;
- }
- const goDocument = () => {
- navId.value = -2;
- hideDialog.value = true;
- };
- const goBack = () => {
- navId.value = 0;
- hideDialog.value = false;
- };
- /**
- * 当点击某个导航时触发的方法
- * 例如:点击 知识问答 文档智能 智能问答 智能数据 等
- * @params {object} node
- * @params {number} node.id - 例如 3 4 5
- * @params {string} node.title - 例如:文档智能 小数绘图
- */
- const selectNav = async (node) => {
- navId.value = node.id;
- textValue.value = [];
- // 关闭历史模式
- historyMode.value = false;
- readonly.value = false;
- if (node.index === -1) {
- swiperNumber.value = 5;
- } else {
- swiperNumber.value = 4;
- }
- helper.$bus.emit("stop-writing");
- showDialog.value = false;
- // 获取当前选定的agent对应的ID
- selectId.value = (agents.find(agent => agent.name === node.title) || {}).id || null;
- // 获取历史记录
- const data = await ajax.message.getDialogs(selectId.value);
- if (navId.value === 0 || navId.value === 3) {
- const result = await ajax.agent.getVariables(selectId.value);
- variables.value = result;
- reportData = {};
- }
- if (data && Array.isArray(data)) {
- historyList.value = data.map((value) => {
- return {
- content: value.name,
- id: value.id,
- time: value.update_date
- };
- });
- }
- // 每次切换功能板块时,清空sendData数据
- // helper.write('sendData', {});
- clearLocalStorageSendData();
- };
- /**
- * 选择某个历史记录
- * @params {string} id - 历史记录对应的ID
- */
- const selectHistory = async (id) => {
- showDialog.value = true;
- // 历史记录对话模式,不调用对话ID接口
- historyMode.value = true;
- readonly.value = true;
- selectId.value = id;
- helper.$bus.emit("set-loading", true);
- helper.$bus.emit("stop-writing");
- initDialog.value = false;
- // 历史记录 通过当前name取id
- const name = config.slider.find(item => item.id === navId.value).title
- const agentsId = agents.find(agent => agent.name === name).id;
- const data = await ajax.message.getHistoryLogs(agentsId, id);
- if (data && Array.isArray(data) && data.length > 0) {
- dialogList.value = data
- } else {
- dialogList.value = []
- }
- initDialog.value = true;
- helper.$bus.emit("set-loading", false);
- };
- const beginCombine = async () => {
- let report_name = "";
- let inputData = [];
- for (let key in reportData) {
- /**
- * 此部分代码于 2024/11/25日上午做了简单优化
- * 优化时,仅调整了循环体内的代码
- * 由于此功能暂时禁用,无法测试优化后的效果是否正常
- * 如果后续测试时发现代码异常,可copy此时间之前的原代码
- */
- const cur_report = reportData[key];
- const report_key = cur_report.key;
- const report_value = cur_report.value;
- const item = {
- id: key,
- name: report_key,
- };
- if (typeof report_value === "string") {
- report_name += `${report_key}:${report_value}\n`;
- item.file_path = '';
- item.value = report_value;
- } else {
- report_name += `${report_key}:${report_value.name}\n`;
- item.file_path = report_value.url;
- item.value = '';
- }
- inputData.push(item);
- }
- // 如果不是历史记录对话模式,则创建对话
- if (!historyMode.value) {
- const data = await ajax.message.createDialog(selectId.value);
- if (data) {
- dialogId.value = data.chat_id;
- }
- }
-
- dialogList.value = [];
- showDialog.value = true;
- initDialog.value = true;
- const sendData = {
- chatHistory: [],
- message: textValue.value,
- name: "报告生成",
- description: "报告生成",
- inputs: {
- report_name,
- id: "Report-PRcYL",
- data: inputData
- }
- };
- setTimeout(() => {
- helper.$bus.emit("send-message", sendData);
- }, 500);
- };
- const continueCombine = async () => {
- const sendData = {
- chatHistory: [],
- name: "报告生成",
- description: "报告生成",
- inputs: {
- report_name: textValue.value,
- id: "Report-PRcYL",
- query: textValue.value,
- }
- };
- setTimeout(() => {
- helper.$bus.emit("send-message", sendData);
- textValue.value = "";
- }, 500);
- };
- const customChange = (event, key, value) => {
- reportData[key] = {
- key: value,
- value: event
- };
- };
- const customRequest = async (option, key, value) => {
- const { onSuccess, fileItem } = option;
- const { file, uid, name } = fileItem;
- const fileList = [];
- fileList.push({
- id: uid,
- file
- });
- onSuccess();
- const formData = new FormData();
- fileList.forEach((item) => {
- formData.append("file", item.file);
- });
- const data = await ajax.file.uploadFiles(selectId.value, formData);
- reportData[key] = {
- key: value,
- value: {
- name,
- url: data.file_path
- }
- };
- };
- onMounted(async () => {
- agents = await ajax.agent.getAgents();
- agentIds.value = agents && Array.isArray(agents) && agents.map((data) => data.id) || [];
- helper.$bus.on("open-dialog", async (value) => {
- // 如果不是历史记录对话模式,则创建对话
- if (!historyMode.value) {
- const data = await ajax.message.createDialog(selectId.value);
- dialogId.value = data.chat_id;
- }
- dialogList.value = [];
- showDialog.value = true;
- initDialog.value = true;
- // TODO
- setTimeout(() => {
- helper.$bus.emit("send-message", value);
- }, 200);
- });
- });
- onBeforeUnmount(() => {
- helper.$bus.off("open-dialog");
- });
- /**
- * 点击新建对话按钮
- */
- const handelSetNewChat = () => {
- showDialog.value = false;
- // selectId = selectId;
- historyMode.value = false;
- setReadonly(false);
- // 每次新建对话时,清空sendData数据
- // helper.write('sendData', {});
- clearLocalStorageSendData();
- };
- function clearLocalStorageSendData(){
- // helper.write('sendData', {});
- }
- return {
- SYSTEM_NAME,
- customChange,
- customRequest,
- historyList,
- beginCombine,
- continueCombine,
- selectId,
- dialogId,
- navId,
- variables,
- selectNav,
- swiperNumber,
- slider: config.slider,
- readonly,
- setReadonly,
- showDialog,
- selectHistory,
- historyMode,
- closeOthers,
- openAll,
- dialogType,
- dialogList,
- initDialog,
- goDocument,
- goBack,
- changeParse,
- hideDialog,
- agentIds,
- textValue,
- parseStatus,
- maxLength,
- handelSetNewChat
- };
- }
- });
- </script>
- <style lang="scss" scoped>
- .main {
- .upload-footer {
- margin-bottom: 50px;
- padding: 20px;
- width: 540px;
- border: 1px solid #eee;
- >section {
- >div {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 500px;
- >p {
- width: 150px;
- margin-right: 10px;
- }
- }
- p {
- span {
- position: relative;
- &:after {
- content: "*";
- display: block;
- color: red;
- position: absolute;
- right: -10px;
- top: -5px;
- }
- }
- }
- >p,
- >div {
- margin: 10px 0;
- }
- }
- }
- flex: 1;
- position: relative;
- display: flex;
- .history-wrap {
- width: 0px;
- opacity: 0;
- overflow: hidden;
- transition-duration: 0.3s;
- transition-property: width;
- &-open {
- opacity: 1;
- width: 260px;
- }
- }
- .wrap {
- flex: 1;
- }
- .border-wrap {
- position: relative;
- padding: 30px 16px 30px 40px;
- flex: 1;
- height: 100%;
- &.border-no-wrap {
- padding: 0;
- >div {
- padding: 0;
- >section.section-padding {
- padding: 0;
- }
- }
- }
- >div {
- width: 100%;
- height: 100%;
- background: #fff;
- box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.03);
- border-radius: 14px;
- display: flex;
- flex-direction: column;
- padding-left: 32px;
- position: relative;
- >div {
- position: absolute;
- bottom: -10px;
- left: -10px;
- z-index: 10;
- width: 38px;
- height: 38px;
- border-radius: 20px;
- background: #fff;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- }
- >header {
- >div {
- display: inline-block;
- margin-top: 20px;
- >img {
- transform: translateX(-12px);
- }
- >p {
- font-size: 36px;
- font-weight: bold;
- color: #000;
- >span {
- font-weight: bold;
- background: linear-gradient(180deg, #41d98c, #31c4c9);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- }
- }
- >span {
- display: block;
- color: #000;
- font-size: 15px;
- margin: 5px 0 32px;
- }
- }
- }
- >section {
- flex: 1;
- overflow: hidden;
- &.section-padding {
- padding-right: 32px;
- padding-bottom: 50px;
- }
- }
- >footer {}
- }
- }
- }
- </style>
|