feat: 处理保存各个图表最后的问题记录,历史记录待同步

main
许宏杰 1 month ago
parent ed1191a16e
commit aed250da13

@ -2,7 +2,7 @@
VITE_DEV_PORT = '8080'
# development path
VITE_DEV_PATH = 'https://demo.mtruning.club'
VITE_DEV_PATH = 'http://192.168.0.128'
# production path
VITE_PRO_PATH = 'https://demo.mtruning.club'
VITE_PRO_PATH = 'http://192.168.0.128:8083'

@ -7,6 +7,7 @@ import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/system
import { redirectErrorPage, getLocalStorage, routerTurnByName, isPreview } from '@/utils'
import { fetchAllowList } from './axios.config'
import includes from 'lodash/includes'
import { refreshToken, isRefreshRequest } from '@/api/refresh.js'
export interface MyResponseType<T> {
code: ResultEnum
@ -19,10 +20,12 @@ export interface MyRequestInstance extends Axios {
}
const axiosInstance = axios.create({
baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}${axiosPre}`,
// baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}${axiosPre}`,
baseURL:`${import.meta.env.VITE_PRO_PATH}${axiosPre}`,
timeout: ResultEnum.TIMEOUT
}) as unknown as MyRequestInstance
console.log(`${import.meta.env.PROD }`,'sssss'),
axiosInstance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 白名单校验
@ -35,7 +38,8 @@ axiosInstance.interceptors.request.use(
return config
}
const userInfo = info[SystemStoreEnum.USER_INFO]
config.headers[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] = userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
config.headers[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] =
userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
return config
},
(err: AxiosError) => {
@ -45,7 +49,7 @@ axiosInstance.interceptors.request.use(
// 响应拦截器
axiosInstance.interceptors.response.use(
(res: AxiosResponse) => {
async (res: AxiosResponse) => {
// 预览页面错误不进行处理
if (isPreview()) {
return Promise.resolve(res.data)
@ -60,21 +64,37 @@ axiosInstance.interceptors.response.use(
}
// 登录过期
if (code === ResultEnum.TOKEN_OVERDUE) {
window['$message'].error(window['$t']('http.token_overdue_message'))
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
return Promise.resolve(res.data)
}
// if (code === ResultEnum.TOKEN_OVERDUE ) {
// console.log('token过期')
// window['$message'].error(window['$t']('http.token_overdue_message'))
// routerTurnByName(PageEnum.BASE_LOGIN_NAME)
// return Promise.resolve(res.data)
// }
// 固定错误码重定向
if (ErrorPageNameMap.get(code)) {
redirectErrorPage(code)
return Promise.resolve(res.data)
//重新获取token
if (code === ResultEnum.TOKEN_OVERDUE && !isRefreshRequest(res.config)) {
const isSucceed = await refreshToken()
if (isSucceed) {
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
const userInfo = info[SystemStoreEnum.USER_INFO]
res.config.headers[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] =
userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
let result = await axiosInstance.request(res.config) //重新请求
return result
}
}
// 提示错误
window['$message'].error(window['$t']((res.data as any).msg))
return Promise.resolve(res.data)
// 固定错误码重定向
// if (ErrorPageNameMap.get(code)) {
// // redirectErrorPage(code)
// return Promise.resolve(res.data)
// }
// // 提示错误
// window['$message'].error(window['$t']((res.data as any).msg))
// return Promise.resolve(res.data)
},
(err: AxiosError) => {
const status = err.response?.status

@ -4,7 +4,7 @@ import { ContentTypeEnum, RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEn
import { ProjectItem, ProjectDetail } from './project'
// * 项目列表
export const projectListApi = async (data: object) => {
export const projectListApi = async (data?: object) => {
try {
const res = await http(RequestHttpEnum.GET)<ProjectItem[]>(`${ModuleTypeEnum.PROJECT}/list`, data)
return res

@ -0,0 +1,37 @@
import { loginApi } from '@/api/path'
import { useSystemStore } from '@/store/modules/systemStore/systemStore'
import { SystemStoreUserInfoEnum, SystemStoreEnum } from '@/store/modules/systemStore/systemStore.d'
let promise;
export async function refreshToken() {
if (promise) {
return promise;
}
const systemStore = useSystemStore()
promise = new Promise(async (resolve) => {
const res = await loginApi({username:'admin',password:'123456',__isRefreshToken: true})
if(res && res.data) {
const { tokenValue, tokenName } = res.data.token
const { nickname, username, id } = res.data.userinfo
// 存储到 pinia
systemStore.setItem(SystemStoreEnum.USER_INFO, {
[SystemStoreUserInfoEnum.USER_TOKEN]: tokenValue,
[SystemStoreUserInfoEnum.TOKEN_NAME]: tokenName,
[SystemStoreUserInfoEnum.USER_ID]: id,
[SystemStoreUserInfoEnum.USER_NAME]: username,
[SystemStoreUserInfoEnum.NICK_NAME]: nickname,
})
resolve(res.code == 200);
}
});
promise.finally(() => {
promise = null;
});
return promise;
}
export function isRefreshRequest(config) {
return !!config.__isRefreshToken; //两个取反变成boolean
}

@ -81,7 +81,9 @@ import { ref, reactive, onMounted, onUnmounted, watch, nextTick } from 'vue'
import userIcon from '@/assets/images/ai/user-icon.png'
import aiIcon from '@/assets/images/ai/ai-icon.png'
import { useMessage } from 'naive-ui'
import { useRoute } from 'vue-router'
const route = useRoute()
const messageDialog = useMessage()
const scrollContainer = ref<HTMLDivElement | null>(null)
// const chartContainer = ref<HTMLDivElement | null>(null)
@ -172,9 +174,35 @@ const hanlderStyleColor = (type: string, fatherIndex: number, childIndex: number
messagesItem.chartInstanceItem?.changeColorStyle(childIndex)
}
onMounted(() => {
// chartInstance = new LineChart('test', chartData)
// route.path
// const result = checkLastPartIsTimestamp(route.path);
// if(result){
// //
// }else{
// }
// console.log(result )
})
const checkLastPartIsTimestamp = (str:string)=> {
// /
const lastSlashIndex = str.lastIndexOf('/');
if (lastSlashIndex === -1) {
return false;
}
// /
const lastPart = str.slice(lastSlashIndex + 1);
//
const num = Number(lastPart);
//
if (isNaN(num)) {
return false;
}
// 2000 2100
const minTimestamp = new Date('2024-01-01').getTime();
const maxTimestamp = new Date('2124-01-01').getTime();
return num >= minTimestamp && num <= maxTimestamp;
}
// messages
watch(
messages,

@ -1,12 +1,115 @@
<template>
<div class="history-list">
<div class="history-box">
<div class="history-title">聊天历史记录</div>
<div class="history-list">
<div class="history-item">
<div class="history-row-title">根据2024年度业务根据2024年度业务根据2024年度业务</div>
<div class="history-row-icon">
<n-icon size="14" color="#F25D44" class="del-icon">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32">
<path d="M12 12h2v12h-2z" fill="currentColor"></path>
<path d="M18 12h2v12h-2z" fill="currentColor"></path>
<path d="M4 6v2h2v20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8h2V6zm4 22V8h16v20z" fill="currentColor"></path>
<path d="M12 2h8v2h-8z" fill="currentColor"></path>
</svg>
</n-icon>
</div>
</div>
<div class="history-item">
<div class="history-row-title">根据2024年度业务根据2024年度业务根据2024年度业务</div>
<div class="history-row-icon">
<n-icon size="14" color="#F25D44" class="del-icon">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32">
<path d="M12 12h2v12h-2z" fill="currentColor"></path>
<path d="M18 12h2v12h-2z" fill="currentColor"></path>
<path d="M4 6v2h2v20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8h2V6zm4 22V8h16v20z" fill="currentColor"></path>
<path d="M12 2h8v2h-8z" fill="currentColor"></path>
</svg>
</n-icon>
</div>
</div>
<div class="history-item">
<div class="history-row-title">根据2024年度业务根据2024年度业务根据2024年度业务</div>
<div class="history-row-icon">
<n-icon size="14" color="#F25D44" class="del-icon">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32">
<path d="M12 12h2v12h-2z" fill="currentColor"></path>
<path d="M18 12h2v12h-2z" fill="currentColor"></path>
<path d="M4 6v2h2v20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8h2V6zm4 22V8h16v20z" fill="currentColor"></path>
<path d="M12 2h8v2h-8z" fill="currentColor"></path>
</svg>
</n-icon>
</div>
</div>
</div>
<div class="history-title">看板历史记录</div>
<div class="history-list">
<div class="history-item"></div>
</div>
</div>
</template>
<script setup>
<script setup lang="ts">
import { projectListApi } from '@/api/path'
import { onMounted } from 'vue'
const fetchList = async () => {
const res = await projectListApi()
console.log(res)
}
onMounted(()=>{
fetchList()
})
defineExpose({
fetchList
});
</script>
<style scoped>
<style lang="scss" scoped>
.history-box {
padding-top: 37px;
}
.history-title {
font-size: 14px;
color: #ffffff;
font-weight: bold;
}
.history-list {
margin: 10px 0;
min-height: 5vh;
max-height: 25vh;
overflow-y: auto;
display: flex;
flex-direction: column;
.history-item {
cursor: pointer;
box-sizing: border-box;
padding: 10px;
</style>
border-radius: 4px;
display: flex;
align-items: center;
gap: 3px;
.history-row-title {
flex: 1;
font-size: 14px;
color: #cfd5e5;
font-weight: 400;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.del-icon {
display: none;
}
}
.history-item:hover {
background-color: #3d424d;
.del-icon {
display: block;
}
}
}
</style>

@ -9,7 +9,7 @@
:to="item.path"
v-for="(item, index) in menuList"
:key="index"
@click="handlerPath(item.path)"
@click="handlerPath(item.path, index)"
>
<n-icon size="20">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
@ -20,7 +20,7 @@
>新建{{ item.name }}
</div>
</div>
<ai-history></ai-history>
<ai-history ref="history"></ai-history>
</div>
<div class="right-container">
<router-view :key="route.fullPath"></router-view>
@ -29,14 +29,17 @@
</template>
<script setup>
import { useRoute,useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { createProjectApi } from '@/api/path'
import { getUUID } from '@/utils'
import { ResultEnum } from '@/enums/httpEnum'
import AiLogo from '../AI/components/logo/index.vue'
import AiHistory from '../AI/components/history/index.vue'
import { ref } from 'vue'
const router = useRouter()
const route = useRoute()
const history = ref(null)
const menuList = [
{ name: '聊天', path: '/chat' },
@ -44,13 +47,34 @@ const menuList = [
]
const getCurrentRoute = path => {
return route.path.includes(path)
return route.path.includes(path)
}
const handlerPath = (path)=>{
router.push(path + '/'+ Date.now()).catch(()=>{
const handlerPath = async (path, index) => {
if (index == 1) {
if(history.value){
// history.value.fetchList()
}
try {
//
const res = await createProjectApi({
//
projectName: getUUID(),
// remarks
remarks: null,
//
indexImage: null
})
if (res && res.code === ResultEnum.SUCCESS) {
const { id } = res.data
router.push(path + '/' + id)
}
} catch (error) {
window['$message'].error(window['$t']('project.create_failure'))
}
}else{
router.push(path + '/' + Date.now()).catch(() => {})
}
})
}
</script>

@ -22,7 +22,7 @@
</n-form-item>
</n-form>
<div class="upload-box">
<!-- <div class="upload-box">
<n-upload
v-model:file-list="uploadFileListRef"
:show-file-list="false"
@ -39,7 +39,7 @@
</div>
</n-upload-dragger>
</n-upload>
</div>
</div> -->
<n-space vertical :size="12">
<n-space>
<n-text>背景颜色</n-text>
@ -54,7 +54,7 @@
></n-color-picker>
</div>
</n-space>
<n-space>
<!-- <n-space>
<n-text>应用类型</n-text>
<n-select
size="small"
@ -64,7 +64,7 @@
:options="selectColorOptions"
@update:value="selectColorValueHandle"
/>
</n-space>
</n-space> -->
<n-space>
<n-text>背景控制</n-text>
<n-button class="clear-btn" size="small" :disabled="!canvasConfig.backgroundImage" @click="clearImage">

@ -241,9 +241,8 @@ watch(
) => {
if(newData){
messagesList = []
if(targetData.value.lastMessagesItem) messagesList.push(targetData.value.lastMessagesItem)
}
// console.log(newData,'',targetData.value.lastMessagesItem)
},
)
@ -257,7 +256,9 @@ watch(
dimensions: any
} | null
) => {
// console.log(targetData.value.option.messages,'sss')
if(targetData.value.lastMessagesItem && messagesList.length === 0){
messagesList.push(targetData.value.lastMessagesItem)
}
noData.value = false
if (newData && targetData?.value?.chartConfig?.chartFrame === ChartFrameEnum.ECHARTS) {
// DataSet

@ -171,13 +171,13 @@ const btnList = [
icon: renderIcon(BrowsersOutlineIcon),
event: previewHandle
},
{
key: 'release',
title: () => (release.value ? '已发布' : '发布'),
icon: renderIcon(SendIcon),
type: () => (release.value ? 'primary' : 'default'),
event: modelShowHandle
}
// {
// key: 'release',
// title: () => (release.value ? '' : ''),
// icon: renderIcon(SendIcon),
// type: () => (release.value ? 'primary' : 'default'),
// event: modelShowHandle
// }
]
const comBtnList = computed(() => {

Loading…
Cancel
Save