src/components/chat/Chat.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/chatComponents/summaryCom/SummaryCom.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/chatComponents/summaryCom/components/deviceLastValue/DeviceLastValueCom.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/chatComponents/summaryCom/components/deviceLastValue/MonitorContent.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/chatComponents/summaryCom/components/deviceLastValue/constants.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/chatComponents/summaryCom/components/deviceLastValue/types.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/chatComponents/summaryCom/components/types.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/hooks/useAssistantContentOpt.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/components/chat/Chat.vue
@@ -36,7 +36,7 @@ v-for="fixItem in item.content.origin.err_json.fix_question?.values" :key="fixItem" class="bg-gray-200 p-3 hover:bg-[#c5e0ff] hover:text-[#1c86ff] cursor-pointer rounded-lg" @click="fixQuestionClick(fixItem)" @click="fixQuestionClick(fixItem, item.content.origin)" > {{ fixItem.title }} </div> @@ -237,6 +237,11 @@ ElMessage.warning('åéå¤±è´¥ï¼æªç¡®å®åºç¨åºæ¯ï¼'); } processId.value = uuidv4(); const judgeParams = !preQuestion.value ? {} : { prev_question: preQuestion.value, }; const params = { process_id: processId.value, question: text, @@ -244,7 +249,7 @@ section_a_id: currentSectionId, history_group_id: currentRouteId, raw_mode: roomConfig.value?.[currentRouteId]?.isAnswerByLLM ?? false, next_chat: isNextChat.value, ...judgeParams, } as any; if (currentSampleId) { @@ -404,7 +409,7 @@ feedbackClick, askMoreClick, fixQuestionClick, isNextChat, preQuestion, showFixQuestion, showAskMore, } = useAssistantContentOpt({ src/components/chat/chatComponents/summaryCom/SummaryCom.vue
@@ -2,17 +2,20 @@ <div class="w-full space-y-3"> <template v-if="data && data.length > 0"> <!-- ä¸è½ä½¿ç¨ index --> <component v-for="(item, index) in data" :key="item.id" :id="item.id" :is="summaryAnswerTypeMapCom[item.type]" :data="item"></component> <component v-for="(item, index) in data" :key="item.id" :id="item.id" :is="summaryAnswerTypeMapCom[item.type]" :data="item" ></component> </template> </div> </template> <script setup lang="ts"> import { computed } from 'vue'; import { chatComProps } from '../common'; import { summaryAnswerTypeMapCom } from './components/types'; const props = defineProps(chatComProps); </script> <style scoped lang="scss"></style> src/components/chat/chatComponents/summaryCom/components/deviceLastValue/DeviceLastValueCom.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,203 @@ <template> <div ref="containerRef" class="w-full flex justify-center" v-resize="resizeHandler"> <div class="inline-block"> <div :class="`space-y-[${THICK_BORDER_WIDTH}px]`" :style="{ border: `${THICK_BORDER_WIDTH}px solid ${BORDER_COLOR}`, backgroundColor: BORDER_COLOR, }" > <div v-for="(rowChunk, index) in currentRowChunkList" :key="index" :class="`space-y-[${THIN_BORDER_WIDTH}px]`" :style="{ backgroundColor: BORDER_COLOR, }" > <!-- 表头ï¼åè¡¨æ ¼å 容第ä¸è¡ --> <div :class="`space-y-[${THICK_BORDER_WIDTH}px]`" :style="{ backgroundColor: BORDER_COLOR, }" > <div class="flex" :class="`space-x-[${THICK_BORDER_WIDTH}px]`" :style="{ backgroundColor: COL_HEADER_CELL_BG_COLOR, }" > <div v-for="(item, index) in maxColsNum" :key="item" :class="COL_HEADER_CELL_CLASS" :style="{ width: `${CELL_WIDTH}px`, height: `${CELL_HEIGHT}px`, backgroundColor: COL_HEADER_CELL_BG_COLOR, }" > {{ index === 0 ? '' : rowChunk[index - 1]?.OTITLE }} </div> </div> <MonitorContent v-if="firstRow" :title="firstRow.title" :type="firstRow.id" :values="rowChunk" /> </div> <!-- å©ä½è¡ --> <MonitorContent v-for="(row, index) in restRows" :key="index" :title="row.title" :type="row.id" :values="rowChunk" /> </div> </div> <el-pagination small hide-on-single-page v-model:current-page="pageIndex" v-model:page-size="pageSize" layout="total,prev,pager,next,jumper" :total="total" @current-change="handleCurrentChange" /> </div> </div> </template> <script setup lang="ts"> import _ from 'lodash'; import { computed, onMounted, ref } from 'vue'; import MonitorContent from './MonitorContent.vue'; import { debounce } from '/@/utils/util'; import { chatComProps } from '../../../common'; import { BORDER_COLOR, CELL_HEIGHT, CELL_WIDTH, COL_HEADER_CELL_BG_COLOR, COL_HEADER_CELL_CLASS, PAGE_HEIGHT, THICK_BORDER_WIDTH, THIN_BORDER_WIDTH, } from './constants'; import type { Monitor, MonitorValue } from './types'; const props = defineProps(chatComProps) as { data: Monitor; }; const total = props.data?.values?.length ?? 0; const pageIndex = ref(null); const pageSize = ref(null); const containerRef = ref<HTMLDivElement>(null); let maxColsNum = ref<number>(null); const resizeEvent = ({ width, height }) => { // ææå¤§å®½åº¦ç®æå¤§åæ° maxColsNum.value = Math.floor((width - THICK_BORDER_WIDTH) / (CELL_WIDTH + THICK_BORDER_WIDTH)); const groupCount = (props.data?.rows?.length ?? 0) + 1; const calcMaxRowsNum = (height, extraHeight = 0) => { return Math.floor( (height - THICK_BORDER_WIDTH - extraHeight) / (CELL_HEIGHT * groupCount + 2 * THICK_BORDER_WIDTH + THIN_BORDER_WIDTH * (groupCount - 2)) ); }; // ææå¤§é«åº¦ç®æå¤§è¡æ° let rowsNum = calcMaxRowsNum(height); // ææå¤§åæ°éº const maxColsRowsNum = Math.ceil(total / maxColsNum.value); const isNeedPage = maxColsRowsNum > rowsNum; rowsNum = isNeedPage ? calcMaxRowsNum(height, PAGE_HEIGHT) : maxColsRowsNum; // rowsNum è¡ï¼maxColsNumåï¼ç¬¬ä¸åä¸ç® pageSize.value = isNeedPage ? rowsNum * (maxColsNum.value - 1) : total; pageIndex.value = 1; // isNeedPage æ¯å¦å页ï¼rowsNum è¡æ°ï¼maxColsNum åæ°ï¼ }; const resizeHandler = debounce(resizeEvent); const handleCurrentChange = () => {}; const firstRow = computed(() => props.data?.rows?.[0]); const restRows = computed(() => props.data?.rows?.slice(1)); const pageChunkList = computed(() => { const chunkResult = _.chunk(props.data.values ?? [], pageSize.value); const last = chunkResult.at(-1); if (last) { const restNum = pageSize.value - last.length; const emptyData = _.fill(Array(restNum), { ONAME: '', OTIME: '', OTITLE: '', OTYPE: '', } as MonitorValue); const lastData = last.concat(emptyData); chunkResult[chunkResult.length - 1] = lastData; } return chunkResult; }); const currentPageChunk = computed(() => { pageChunkList.value; if (pageIndex.value == null) return []; const pageChunk = pageChunkList.value[pageIndex.value - 1]; return pageChunk; }); const currentRowChunkList = computed(() => { if (!currentPageChunk.value || currentPageChunk.value.length === 0) return []; const chunkResult = _.chunk(currentPageChunk.value, maxColsNum.value - 1); return chunkResult; }); // è®¡ç®æå¤§åæ° // x* cellWidth+thickBorderWidth*(x-1)+thickBorderWidth*2 <= width; // x*(cellWidth+thickBorderWidth)+thickBorderWidth<=width; // x<= (width-thickBorderWidth)/(cellWidth+thickBorderWidth); // const groupCount = (TEST_DATA?.rows?.length ?? 0) + 1; // è®¡ç®æå¤§è¡æ° // y * (cellHeight * groupCount) + // (y - 1) * (2 * thickBorderWidth) + // thickBorderWidth + // thickBorderWidth * 2 + // y * (groupCount - 2) * thinBorderWidth <= // height; // (cellHeight * groupCount + 2 * thickBorderWidth + thinBorderWidth(groupCount - 2) * groupCount) * y + thickBorderWidth <=height; // y<= (height-thickBorderWidth)/(cellHeight * groupCount + 2 * thickBorderWidth + thinBorderWidth(groupCount - 2) * groupCount) onMounted(() => { resizeEvent({ width: containerRef.value.clientWidth, height: 0.7 * document.body.clientHeight, }); }); </script> <style scoped lang="scss"> :deep(.space-y-\[2px\] > :not([hidden]) ~ :not([hidden])) { --tw-space-y-reverse: 0; margin-top: calc(2px * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(2px * var(--tw-space-y-reverse)); } :deep(.space-y-\[1px\] > :not([hidden]) ~ :not([hidden])) { --tw-space-y-reverse: 0; margin-top: calc(1px * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(1px * var(--tw-space-y-reverse)); } :deep(.space-x-\[2px\] > :not([hidden]) ~ :not([hidden])) { --tw-space-x-reverse: 0; margin-right: calc(2px * var(--tw-space-x-reverse)); margin-left: calc(2px * calc(1 - var(--tw-space-x-reverse))); } :deep(.space-x-\[1px\] > :not([hidden]) ~ :not([hidden])) { --tw-space-x-reverse: 0; margin-right: calc(1px * var(--tw-space-x-reverse)); margin-left: calc(1px * calc(1 - var(--tw-space-x-reverse))); } </style> src/components/chat/chatComponents/summaryCom/components/deviceLastValue/MonitorContent.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,51 @@ <template> <div class="flex cursor-none" :class="`space-x-[${THICK_BORDER_WIDTH}px]`" :style="{ backgroundColor: BORDER_COLOR, }" > <div :class="ROW_HEADER_CELL_CLASS" :style="{ width: `${CELL_WIDTH}px`, height: `${CELL_HEIGHT}px`, }" > {{ title }} </div> <div v-for="(item, index) in values" :key="index" :class="CONTENT_CELL_CLASS" :style="{ width: `${CELL_WIDTH}px`, height: `${CELL_HEIGHT}px`, }" > {{ item[type] }} </div> </div> </template> <script setup lang="ts"> import type { PropType } from 'vue'; import { BORDER_COLOR, CELL_HEIGHT, CELL_WIDTH, CONTENT_CELL_CLASS, ROW_HEADER_CELL_CLASS, THICK_BORDER_WIDTH } from './constants'; import type { MonitorValue } from './types'; const props = defineProps({ /** @description æ é¢ */ title: { type: String, }, /** @description ç±»å */ type: { type: String, }, /** @description å¼ */ values: { type: Object as PropType<MonitorValue[]>, }, }); </script> <style scoped lang="scss"></style> src/components/chat/chatComponents/summaryCom/components/deviceLastValue/constants.ts
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,13 @@ export const CONTENT_CELL_CLASS = 'bg-white flex-center flex-0 text-[#7331a5] cursor-pointer'; export const ROW_HEADER_CELL_CLASS = 'bg-white flex-center flex-0'; export const COL_HEADER_CELL_CLASS = 'font-bold flex-center flex-0'; export const COL_HEADER_CELL_BG_COLOR = '#c5d9f1' export const CELL_WIDTH = 198; export const CELL_HEIGHT = 32; export const THIN_BORDER_WIDTH = 1; export const THICK_BORDER_WIDTH = 2; export const PAGE_HEIGHT = 54; export const rowCount = 5; export const BORDER_COLOR = '#90b6e2'; src/components/chat/chatComponents/summaryCom/components/deviceLastValue/types.ts
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ import type { SummaryAnswerType } from '../types'; export type MonitorRow = { id: string; title: string; }; export type MonitorValue = { OTYPE: string; ONAME: string; OTITLE: string; OTIME: string; ZD: number; YL: number; }; export type Monitor = { type: SummaryAnswerType.DeviceLastValue; rows: MonitorRow[]; values: MonitorValue[]; }; src/components/chat/chatComponents/summaryCom/components/types.ts
@@ -2,12 +2,14 @@ import MapCom from '../../mapCom/MapCom.vue'; import RecordSet from './recordSet/RecordSet.vue'; import Summary from './summary/Summary.vue'; import DeviceLastValueCom from './deviceLastValue/DeviceLastValueCom.vue'; export const enum SummaryAnswerType { RecordSet = 'recordset', Summary = 'summary', Url = 'url', Map = 'map', DeviceLastValue='device_last_value' } export const summaryAnswerTypeMapCom = { @@ -15,4 +17,5 @@ [SummaryAnswerType.Summary]: Summary, [SummaryAnswerType.Url]: HTMLCom, [SummaryAnswerType.Map]: MapCom, [SummaryAnswerType.DeviceLastValue]:DeviceLastValueCom }; src/components/chat/hooks/useAssistantContentOpt.ts
@@ -16,7 +16,7 @@ export const useAssistantContentOpt = (option: AssistantContentOptOption) => { const { forbidScroll, sendChatMessage, displayMessageList } = option; const { toClipboard } = useClipboard(); const isNextChat = ref(false); const preQuestion = ref(null); const copyClick = (item) => { const type = item.content.type; @@ -103,16 +103,16 @@ sendChatMessage({ type: AnswerType.Text, values: item.question }); }; const fixQuestionClick = (item) => { const fixQuestionClick = (item,originData) => { if (!item.question) return; isNextChat.value = true; preQuestion.value = originData?.question; try { sendChatMessage({ type: AnswerType.Text, values: item.question, }); } finally { isNextChat.value = false; preQuestion.value = null; } }; @@ -129,7 +129,7 @@ feedbackClick, askMoreClick, fixQuestionClick, isNextChat, preQuestion, showAskMore, showFixQuestion, };