From f2ddf37d690589d18adac111635844e539dd9f33 Mon Sep 17 00:00:00 2001 From: xuhongjie <1943105267@qq.com> Date: Sun, 20 Apr 2025 15:27:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=81=8A=E5=A4=A9=E5=AE=A4=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/http.ts | 1 + src/api/path/project.api.ts | 9 + src/hooks/useChartDataFetch.hook.ts | 1 + src/packages/public/publicConfig.ts | 6 +- src/store/modules/messageRoom/index.js | 12 +- src/styles/pages/index.scss | 12 ++ src/views/AI/chat/class/bar.ts | 1 + src/views/AI/chat/index.vue | 197 +++++++++++++++--- src/views/AI/chat/types/chat.ts | 8 - src/views/AI/chat/types/index.ts | 1 - src/views/AI/components/history/index.vue | 55 ++--- src/views/AI/components/index.js | 4 +- src/views/AI/index.vue | 45 +++- .../components/ChartDataDisplay/index.vue | 1 + .../components/RequestHeader/index.vue | 1 + .../components/ChartData/index.vue | 4 +- .../chart/ContentConfigurations/index.vue | 26 +-- .../chart/ContentEdit/hooks/useDrag.hook.ts | 1 + 18 files changed, 286 insertions(+), 99 deletions(-) delete mode 100644 src/views/AI/chat/types/chat.ts delete mode 100644 src/views/AI/chat/types/index.ts diff --git a/src/api/http.ts b/src/api/http.ts index 0d433a7..21e6514 100644 --- a/src/api/http.ts +++ b/src/api/http.ts @@ -113,6 +113,7 @@ export const translateStr = (target: string | Record) => { * @param globalParams 全局参数 */ export const customizeHttp = (targetParams: RequestConfigType, globalParams: RequestGlobalConfigType) => { + if (!targetParams || !globalParams) { return } diff --git a/src/api/path/project.api.ts b/src/api/path/project.api.ts index 435c297..24383a0 100644 --- a/src/api/path/project.api.ts +++ b/src/api/path/project.api.ts @@ -26,6 +26,15 @@ export const historyMessageRoom = async(data: object)=>{ } } +export const historyMessageRoomUpdata = async(data: object)=>{ + try{ + const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.MESSAGE}`, data) + return res + }catch{ + httpErrorHandle() + } +} + export const historyMessageRoomList = async(data?: object)=>{ try{ const res = await http(RequestHttpEnum.GET)(`${ModuleTypeEnum.MESSAGE}`, data) diff --git a/src/hooks/useChartDataFetch.hook.ts b/src/hooks/useChartDataFetch.hook.ts index 4ed5a1b..e83afed 100644 --- a/src/hooks/useChartDataFetch.hook.ts +++ b/src/hooks/useChartDataFetch.hook.ts @@ -73,6 +73,7 @@ export const useChartDataFetch = ( clearInterval(fetchInterval) const fetchFn = async () => { + const res = await customizeHttp(toRaw(targetComponent.request), toRaw(chartEditStore.getRequestGlobalConfig)) if (res) { try { diff --git a/src/packages/public/publicConfig.ts b/src/packages/public/publicConfig.ts index 2a21d71..4bc865c 100644 --- a/src/packages/public/publicConfig.ts +++ b/src/packages/public/publicConfig.ts @@ -20,9 +20,9 @@ import cloneDeep from 'lodash/cloneDeep' // 请求基础属性 export const requestConfig: RequestConfigType = { - requestDataType: RequestDataTypeEnum.STATIC, - requestHttpType: RequestHttpEnum.GET, - requestUrl: '', + requestDataType: RequestDataTypeEnum.AJAX, + requestHttpType: RequestHttpEnum.POST, + requestUrl: 'http://baijiahu.mynatapp.cc/', requestInterval: undefined, requestIntervalUnit: RequestHttpIntervalEnum.SECOND, requestContentType: RequestContentTypeEnum.DEFAULT, diff --git a/src/store/modules/messageRoom/index.js b/src/store/modules/messageRoom/index.js index 3cce59f..e1f9690 100644 --- a/src/store/modules/messageRoom/index.js +++ b/src/store/modules/messageRoom/index.js @@ -2,15 +2,15 @@ import { defineStore } from 'pinia' const useMessageRoomStore = defineStore('useMessageRoomStore', { state: () => ({ messageRoom: { - fristIssue:undefined, - list:[] + id:undefined, + createUserId:undefined, + content:[] } }), actions: { - setMessage(fristIssue,item) { - if (this.messageRoom.list.length >= 35) return - if(!this.messageRoom.fristIssue) this.messageRoom.fristIssue = fristIssue - this.messageRoom.list.push(item) + setMessage(item) { + if (this.messageRoom.content.length >= 35) return + this.messageRoom.content.push(item) }, resetList(obj){ this.messageRoom = obj diff --git a/src/styles/pages/index.scss b/src/styles/pages/index.scss index d35cdf5..1ec6eaf 100644 --- a/src/styles/pages/index.scss +++ b/src/styles/pages/index.scss @@ -69,9 +69,21 @@ align-items: flex-start; } .ai-hint { + display: flex; + align-items: center; + justify-content: space-between; margin-top: 6px; font-size: 12px; color: #c3cad9; + gap: 10px; + .upload-text{ + cursor: pointer; + display: flex; + align-items: center; + } + .upload-text:hover{ + color: #3F7BF8; + } } } .message-content { diff --git a/src/views/AI/chat/class/bar.ts b/src/views/AI/chat/class/bar.ts index 1f43b9d..fb1b3c2 100644 --- a/src/views/AI/chat/class/bar.ts +++ b/src/views/AI/chat/class/bar.ts @@ -181,5 +181,6 @@ export class BarChart { this.chart.dispose() this.chart = null } + console.log('清除',this.chart) } } diff --git a/src/views/AI/chat/index.vue b/src/views/AI/chat/index.vue index 7c47ccc..cd138e2 100644 --- a/src/views/AI/chat/index.vue +++ b/src/views/AI/chat/index.vue @@ -25,7 +25,7 @@
{{ item.time }}
-
+
{{ item.text }} @@ -76,7 +76,24 @@
- (注:本回答由AI生成,内容仅供参考) + 注:本回答由AI生成,内容仅供参考 +
+ + + + + + + + 下载图片 +
@@ -110,6 +127,15 @@ import { LineChart, BarChart, PieChart } from './class/index' import { AiHint } from '../components' import userIcon from '@/assets/images/ai/user-icon.png' import aiIcon from '@/assets/images/ai/ai-icon.png' +import { useMessage } from 'naive-ui' +import useMessageRoomStore from '@/store/modules/messageRoom' +import { canvasCut } from '@/utils' +import { historyMessageRoomById } from '@/api/path' +import { useRoute } from 'vue-router' + +const route = useRoute() +const useMessageRoom = useMessageRoomStore() +const messageDialog = useMessage() //输入框加载 let loading = ref(false) //搜索关键字 @@ -128,25 +154,55 @@ let stopWatch = null * 页面初始完成 */ onMounted(() => { - // bar = new PieChart('barEcharts', { - // title:'图表标题', - // unit:'元', - // data: [ - // { value: 1048, name: 'Search Engine' }, - // { value: 735, name: 'Direct' }, - // { value: 580, name: 'Email' }, - // { value: 484, name: 'Union Ads' }, - // { value: 300, name: 'Video Ads' }, - // { value: 200, name: 'qq Ads' }, - // { value: 100, name: 'vx Ads' } - // ] - // }) + startWatching() + + getMessageInfo() }) +/** + * 获取聊天详情 + */ +const getMessageInfo = async () => { + const id = checkLastPartIsTimestamp(route.path) + try { + const res = await historyMessageRoomById(id) + if (res.code == 200 && res.data) { + res.data.content = JSON.parse(res.data.content) + useMessageRoom.resetList(res.data) + res.data.content.map((item, index) => { + messageList.push(item) + initEcharts(item, index) + }) + console.log(res.data) + } + } catch { + messageDialog.error('获取聊天室记录失败!') + } +} + +const checkLastPartIsTimestamp = str => { + // 找到最后一个 / 的位置 + const lastSlashIndex = str.lastIndexOf('/') + if (lastSlashIndex === -1) { + return false + } + // 截取最后一个 / 后面的值 + const lastPart = str.slice(lastSlashIndex + 1) + return lastPart +} + /** * 问答 */ const handleSend = async () => { + if (!keyWord.value.trim()) { + messageDialog.warning('请先输入需要统计的数据!') + return + } + if (useMessageRoom.messageRoom.content.length >= 35) { + messageDialog.warning('每个聊天室上限问题为15条!') + return + } loading.value = true //存储用户回答 setMessageItem({ @@ -156,17 +212,20 @@ const handleSend = async () => { add: true }) //先存储AI回答,作为交互提示,接口响应后再做更新 - setMessageItem({ - from: 'ai', - text: '', - time: moment().format('YYYY/MM/DD HH:mm:ss'), - loading: true, //ai思考中 - chartInstanceItem: null, - chartInstanceActiveIndex: 0, - chartType: null, - xData: [], - yData: [] - }) + setMessageItem( + { + from: 'ai', + text: '', + time: moment().format('YYYY/MM/DD HH:mm:ss'), + loading: true, //ai思考中 + chartInstanceItem: null, + chartInstanceActiveIndex: 0, + chartType: null, + xData: [], + yData: [] + }, + false + ) try { const res = await getAiMsg({ prompt: keyWord.value }) if (res.type) { @@ -184,6 +243,7 @@ const handleSend = async () => { title: res.title, unit: res.unit }) + nextTick(() => { const itemData = messageList[lastIndex.value] //饼图 @@ -228,14 +288,53 @@ const handleSend = async () => { }) } } + +/** + * 同意渲染图表 + */ +const initEcharts = (item, index) => { + nextTick(() => { + //饼图 + if (item.chartType === 'pie') { + item.chartInstanceItem = new PieChart(`${item.chartType}${index}`, { + title: item.title, + unit: item.unit, + xData: item.xData, + data: item.yData + }) + } else if (item.chartType === 'bar') { + item.chartInstanceItem = new BarChart(`${item.chartType}${index}`, { + title: item.title, + unit: item.unit, + xData: item.xData, + data: item.yData + }) + } else if (item.chartType === 'line') { + item.chartInstanceItem = new LineChart(`${item.chartType}${index}`, { + title: item.title, + unit: item.unit, + xData: item.xData, + data: item.yData + }) + } + }) +} /** * 存储聊天室数据 * @param obj */ -const setMessageItem = obj => { +const setMessageItem = (obj, set = true) => { messageList.push(obj) lastIndex.value = messageList.length - 1 + if (set) { + useMessageRoom.setMessage({ + from: obj.from, + text: obj.text, + time: obj.time, + add: true + }) + } } /** @@ -246,6 +345,19 @@ const updataMessageItem = data => { messageList[lastIndex.value] = data keyWord.value = '' loading.value = false + useMessageRoom.setMessage({ + from: data.from, + text: data.text, + chartType: data.chartType, + loading: false, //ai思考中 + time: data.time, + chartInstanceItem: data.chartInstanceItem, + chartInstanceActiveIndex: 0, + xData: data.xData, + yData: data.yData, + title: data.title, + unit: data.unit + }) } /** @@ -256,10 +368,25 @@ const handlerTheme = (item, index) => { pauseWatching() item.chartInstanceActiveIndex = index item.chartInstanceItem.changeColorStyle(index) - setTimeout(()=>{ + setTimeout(() => { startWatching() - },1000) - + }, 1000) +} + +/** + * 下载AI回答为图片 + */ +const uploadImage = index => { + // 导出图片 + const range = document.getElementById(`box${index}`) + + // 隐藏边距线 + if (!range) { + window['$message'].error('下载失败!') + return + } + + canvasCut(range) } // 聊天室自动滚动条下拉 @@ -280,8 +407,14 @@ const pauseWatching = () => { stopWatch = null } } -onMounted(() => { - startWatching() +onUnmounted(() => { + //清除 + messageList.forEach(instance => { + if (instance.chartType) { + instance.chartInstanceItem.dispose() + } + }) + }) diff --git a/src/views/AI/chat/types/chat.ts b/src/views/AI/chat/types/chat.ts deleted file mode 100644 index 73a2deb..0000000 --- a/src/views/AI/chat/types/chat.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface AiChatroom { - from:string,//来自谁 - time:string,//时间 - test?:string,//纯文本 -} - - -export type AiChatroomType = AiChatroom; \ No newline at end of file diff --git a/src/views/AI/chat/types/index.ts b/src/views/AI/chat/types/index.ts deleted file mode 100644 index bdc7971..0000000 --- a/src/views/AI/chat/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -import './chat' \ No newline at end of file diff --git a/src/views/AI/components/history/index.vue b/src/views/AI/components/history/index.vue index 3efdc42..a880a56 100644 --- a/src/views/AI/components/history/index.vue +++ b/src/views/AI/components/history/index.vue @@ -1,35 +1,39 @@ diff --git a/src/views/chart/ContentEdit/hooks/useDrag.hook.ts b/src/views/chart/ContentEdit/hooks/useDrag.hook.ts index 758680f..5b7f750 100644 --- a/src/views/chart/ContentEdit/hooks/useDrag.hook.ts +++ b/src/views/chart/ContentEdit/hooks/useDrag.hook.ts @@ -321,6 +321,7 @@ export const useMouseHandle = () => { // * 进入事件 const mouseenterHandle = (e: MouseEvent, item: CreateComponentType | CreateComponentGroupType) => { + e.preventDefault() e.stopPropagation() if (!chartEditStore.getEditCanvas.isSelect) {