diff --git a/.env b/.env index 64a651d..2f0faa0 100644 --- a/.env +++ b/.env @@ -5,4 +5,4 @@ VITE_DEV_PORT = '8080' VITE_DEV_PATH = 'https://ops-api.apinb.com' # production path -VITE_PRO_PATH = 'https://ops-api.apinb.com' \ No newline at end of file +VITE_PRO_PATH = '' diff --git a/src/api/axios.ts b/src/api/axios.ts index e868d15..f079c0d 100644 --- a/src/api/axios.ts +++ b/src/api/axios.ts @@ -70,12 +70,7 @@ axiosInstance.interceptors.response.use( // 登录过期 if (code === ResultEnum.TOKEN_OVERDUE) { window['$message'].error(window['$t']('http.token_overdue_message')) - // token 过期,跳转到源站首页 - console.error('[GoView] token 已过期,即将跳转到源站首页') - setTimeout(() => { - window.location.href = window.location.origin - }, 1500) - return Promise.resolve(responseData) + return Promise.reject(new Error(message || '登录凭证已失效')) } // 固定错误码重定向 @@ -92,14 +87,11 @@ axiosInstance.interceptors.response.use( const status = err.response?.status switch (status) { case 401: - // token 失效,跳转到源站首页 - window.location.href = window.location.origin - Promise.reject(err) - break + window['$message'].error('登录凭证已失效') + return Promise.reject(err) default: - Promise.reject(err) - break + return Promise.reject(err) } } ) diff --git a/src/api/projectFiles.ts b/src/api/projectFiles.ts index 1ac9dd5..1be5092 100644 --- a/src/api/projectFiles.ts +++ b/src/api/projectFiles.ts @@ -5,7 +5,6 @@ export type ProjectImageKind = 'index' | 'background' interface PendingUpload { file_id: string - object_key: string upload: { method: string url: string @@ -14,6 +13,15 @@ interface PendingUpload { } } +/** 删除项目图片及其文件关联。 */ +export async function deleteProjectImage(projectIdentity: string, kind: ProjectImageKind): Promise { + const projectPath = `project/${encodeURIComponent(projectIdentity)}/images/${kind}` + const response = await http(RequestHttpEnum.DELETE)(projectPath) + if (response.code !== ResultEnum.SUCCESS) { + throw new Error(response.message || '删除项目图片失败') + } +} + interface CompletedUpload { file_id: string url: string diff --git a/src/api/publicScreen.ts b/src/api/publicScreen.ts new file mode 100644 index 0000000..3eb9581 --- /dev/null +++ b/src/api/publicScreen.ts @@ -0,0 +1,80 @@ +const apiBase = import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : import.meta.env.VITE_DEV_PATH + +export interface PublicScreenManifest { + id: number + name: string + description: string + width: number + height: number + dataset_code: string + built_in_code?: string + is_builtin: boolean + goview_project_id?: string + publish_version: string + project_content?: Record + carousel_order: number +} + +export interface PublicScreenData { + screen_id: number + dataset_code: string + generated_at: string + monitoring: Record + alerts: Record + partial_errors: string[] +} + +export interface PublicCarousel { + enabled: boolean + interval_seconds: number + screens: PublicScreenManifest[] +} + +const requestPublic = async (path: string): Promise => { + const response = await fetch(`${apiBase}${path}`, { method: 'GET', credentials: 'omit' }) + if (!response.ok) throw new Error(`HTTP ${response.status}`) + const body = await response.json() + const code = Number(body?.code) + if (code !== 0 && code !== 200) throw new Error(body?.message || '公开大屏接口返回失败') + return body?.details ?? body?.data +} + +export const publicScreenId = () => { + const query = window.location.hash.split('?')[1] || '' + const value = new URLSearchParams(query).get('screenId') + const id = Number(value) + return Number.isInteger(id) && id > 0 ? id : 0 +} + +export const isPublicCarousel = () => { + const query = window.location.hash.split('?')[1] || '' + return new URLSearchParams(query).get('carousel') === '1' +} + +export const fetchPublicScreenManifest = (screenId: number) => + requestPublic(`/Mgt/v1/public/big-screens/${screenId}`) + +let cachedScreenId = 0 +let cachedAt = 0 +let cachedData: PublicScreenData | null = null +let pendingData: Promise | null = null + +export const fetchPublicScreenData = (screenId: number) => { + const now = Date.now() + if (cachedData && cachedScreenId === screenId && now - cachedAt < 2000) return Promise.resolve(cachedData) + if (pendingData && cachedScreenId === screenId) return pendingData + cachedScreenId = screenId + pendingData = requestPublic(`/Mgt/v1/public/big-screens/${screenId}/data`) + .then(data => { + cachedData = data + cachedAt = Date.now() + return data + }) + .finally(() => { + pendingData = null + }) + return pendingData +} + +export const fetchPublicCarousel = () => + requestPublic('/Mgt/v1/public/big-screens/carousel') diff --git a/src/components/Pages/ChartItemSetting/GlobalSetting.vue b/src/components/Pages/ChartItemSetting/GlobalSetting.vue index 68e3fb0..f501425 100644 --- a/src/components/Pages/ChartItemSetting/GlobalSetting.vue +++ b/src/components/Pages/ChartItemSetting/GlobalSetting.vue @@ -339,7 +339,10 @@ import { PropType, computed, watch } from 'vue' import { GlobalThemeJsonType } from '@/settings/chartThemes/index' import { axisConfig, legendConfig } from '@/packages/chartConfiguration/echarts/index' -import { CollapseItem, SettingItemBox, SettingItem, GlobalSettingPosition } from '@/components/Pages/ChartItemSetting' +import CollapseItem from './CollapseItem.vue' +import SettingItemBox from './SettingItemBox.vue' +import SettingItem from './SettingItem.vue' +import GlobalSettingPosition from './GlobalSettingPosition.vue' import { icon } from '@/plugins' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import EchartsRendererSetting from './EchartsRendererSetting.vue' diff --git a/src/components/Pages/ChartItemSetting/GlobalSettingPosition.vue b/src/components/Pages/ChartItemSetting/GlobalSettingPosition.vue index 68a10ee..9f5c1c3 100644 --- a/src/components/Pages/ChartItemSetting/GlobalSettingPosition.vue +++ b/src/components/Pages/ChartItemSetting/GlobalSettingPosition.vue @@ -11,7 +11,9 @@ + + diff --git a/src/views/preview/PublicOpsScreen.vue b/src/views/preview/PublicOpsScreen.vue new file mode 100644 index 0000000..b254444 --- /dev/null +++ b/src/views/preview/PublicOpsScreen.vue @@ -0,0 +1,268 @@ + + + + + diff --git a/src/views/preview/index.vue b/src/views/preview/index.vue index 4e6bc66..25e9618 100644 --- a/src/views/preview/index.vue +++ b/src/views/preview/index.vue @@ -1,9 +1,49 @@ + + diff --git a/src/views/preview/utils/storage.ts b/src/views/preview/utils/storage.ts index 3726659..15af274 100644 --- a/src/views/preview/utils/storage.ts +++ b/src/views/preview/utils/storage.ts @@ -4,6 +4,7 @@ import { StorageEnum } from '@/enums/storageEnum' import { ChartEditStorage } from '@/store/modules/chartEditStore/chartEditStore.d' import { fetchProjectApi } from '@/api/path' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' +import { fetchPublicScreenManifest, publicScreenId } from '@/api/publicScreen' const chartEditStore = useChartEditStore() @@ -14,6 +15,22 @@ export interface ChartEditStorageType extends ChartEditStorage { // 根据路由 identity 获取存储数据的信息 export const getSessionStorageInfo = async () => { const identity = fetchRouteParamsLocation() + const screenId = publicScreenId() + if (screenId) { + const manifest = await fetchPublicScreenManifest(screenId) + if (manifest.is_builtin) return { isBuiltin: true, manifest } + const content = manifest.project_content?.content + if (typeof content !== 'string' || !content.trim()) throw new Error('大屏发布快照缺少项目内容') + const parseData = { ...JSONParse(content), identity } + if (parseData.editCanvasConfig && typeof manifest.project_content?.backgroundImage === 'string') { + parseData.editCanvasConfig.backgroundImage = manifest.project_content.backgroundImage + } + const { editCanvasConfig, requestGlobalConfig, componentList } = parseData + chartEditStore.editCanvasConfig = editCanvasConfig + chartEditStore.requestGlobalConfig = requestGlobalConfig + chartEditStore.componentList = componentList + return parseData + } const storageList: ChartEditStorageType[] = getSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST) // 是否本地预览 diff --git a/src/views/project/items/components/ProjectItemsCard/index.vue b/src/views/project/items/components/ProjectItemsCard/index.vue index 15b21d0..9d56dca 100644 --- a/src/views/project/items/components/ProjectItemsCard/index.vue +++ b/src/views/project/items/components/ProjectItemsCard/index.vue @@ -19,7 +19,7 @@ object-fit="cover" height="100%" preview-disabled - :src="`${cardData.image}?time=${new Date().getTime()}`" + :src="cardData.image" :alt="cardData.title" :fallback-src="requireErrorImg()" >