Commit 06bc03cd8a5ff20286945321d6354b7282155583

Authored by ww
1 parent f051a44f

feat(share): 新增分享页面

  1 +import { ViewTypeEnum } from "@/enums/external/viewEnum"
  2 +import { defHttp } from "@/utils/external/http/axios"
  3 +
  4 +enum Api {
  5 + TOKEN = '/auth/login/public',
  6 +
  7 + CHECK = '/share/check',
  8 +
  9 + SHARE_CONTENT = '/share'
  10 +}
  11 +
  12 +/**
  13 + * @description 获取token
  14 + * @param publicId string
  15 + */
  16 +export const getPublicToken = (publicId: string) => {
  17 + return defHttp.post<Record<'token' | 'refreshToken', string>>({
  18 + url: Api.TOKEN,
  19 + data: { publicId }
  20 + }, { joinPrefix: false })
  21 +}
  22 +
  23 +/**
  24 + * @description 检查时候需要访问令牌
  25 + * @param id string
  26 + */
  27 +export const checkSharePageNeedAccessToken = (id: string) => {
  28 + return defHttp.get<{data: boolean}>({
  29 + url: `${Api.CHECK}/${ViewTypeEnum.LARGE_SCREEN}/${id}`
  30 + })
  31 +}
  32 +
  33 +/**
  34 + * @description 获取分享的数据内容
  35 + * @param options
  36 + */
  37 +export const getShareContentData = (options: Record<'id' | 'accessCredentials', string>) => {
  38 + return defHttp.get<{ data: any }>({
  39 + url: `${Api.SHARE_CONTENT}/${ViewTypeEnum.LARGE_SCREEN}/share_data/${options.id}`,
  40 + params: { accessCredentials: options.accessCredentials }
  41 + })
  42 +}
@@ -9,4 +9,10 @@ export enum PageEnum { @@ -9,4 +9,10 @@ export enum PageEnum {
9 // 未发布 9 // 未发布
10 REDIRECT_UN_PUBLISH = '/redirect/unPublish', 10 REDIRECT_UN_PUBLISH = '/redirect/unPublish',
11 REDIRECT_UN_PUBLISH_NAME = 'redirect-un-publish', 11 REDIRECT_UN_PUBLISH_NAME = 'redirect-un-publish',
  12 +
  13 +}
  14 +
  15 +export enum ShareEnum {
  16 + SHARE_PATH = '/share/preview/:id/:publicId',
  17 + SHARE_PATH_NAME = 'ChartSharePreview'
12 } 18 }
  1 +export enum ViewTypeEnum {
  2 + DATA_BOARD = 'DATA_BOARD',
  3 + LARGE_SCREEN = 'LARGE_SCREEN',
  4 + SCADA = 'SCADA'
  5 +}
@@ -2,7 +2,6 @@ import { Router } from "vue-router" @@ -2,7 +2,6 @@ import { Router } from "vue-router"
2 import { createErrorGuard } from "./errorGuard" 2 import { createErrorGuard } from "./errorGuard"
3 import { createLoadingGuard } from "./loadingGuard" 3 import { createLoadingGuard } from "./loadingGuard"
4 import { createPermissionGuard } from "./permissionGuard" 4 import { createPermissionGuard } from "./permissionGuard"
5 -  
6 export const setupRouterGuard = (router: Router) => { 5 export const setupRouterGuard = (router: Router) => {
7 createPermissionGuard(router) 6 createPermissionGuard(router)
8 createErrorGuard(router) 7 createErrorGuard(router)
1 import { ProjectRuntimeEnvEnum } from "@/enums/external/envEnum"; 1 import { ProjectRuntimeEnvEnum } from "@/enums/external/envEnum";
2 -import { PageEnum } from "@/enums/external/pageEnum"; 2 +import { PageEnum, ShareEnum } from "@/enums/external/pageEnum";
3 import { useUserStoreWithOut } from "@/store/external/modules/user"; 3 import { useUserStoreWithOut } from "@/store/external/modules/user";
4 import { NavigationGuardNext, NavigationGuardWithThis, RouteLocationNormalized, RouteLocationRaw, Router } from "vue-router"; 4 import { NavigationGuardNext, NavigationGuardWithThis, RouteLocationNormalized, RouteLocationRaw, Router } from "vue-router";
5 5
6 6
7 -const whitePathList: string[] = [PageEnum.BASE_LOGIN]; 7 +const whitePathList: string[] = [PageEnum.BASE_LOGIN, ShareEnum.SHARE_PATH];
8 8
9 const isAloneMode = [ProjectRuntimeEnvEnum.DEV_ALONE, ProjectRuntimeEnvEnum.PROD_ALONE].includes(import.meta.env.MODE as ProjectRuntimeEnvEnum) 9 const isAloneMode = [ProjectRuntimeEnvEnum.DEV_ALONE, ProjectRuntimeEnvEnum.PROD_ALONE].includes(import.meta.env.MODE as ProjectRuntimeEnvEnum)
10 10
11 const toIotPlatformLogin = ({ to, from, next }: { to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext }) => { 11 const toIotPlatformLogin = ({ to, from, next }: { to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext }) => {
12 const { origin, port } = window.location 12 const { origin, port } = window.location
  13 +
13 if (Number(port) === Number(import.meta.env.VITE_DEV_PORT)) { 14 if (Number(port) === Number(import.meta.env.VITE_DEV_PORT)) {
14 - if (whitePathList.includes(to.path)) { 15 + if (to.matched.find(item => whitePathList.includes(item.path))) {
15 next() 16 next()
16 return 17 return
17 } else { 18 } else {
@@ -36,8 +37,9 @@ export function createPermissionGuard(router: Router) { @@ -36,8 +37,9 @@ export function createPermissionGuard(router: Router) {
36 } 37 }
37 38
38 const token = userStore.getJwtToken 39 const token = userStore.getJwtToken
  40 + console.log(token)
39 41
40 - if (whitePathList.includes(to.path)) { 42 + if (to.matched.find(item => whitePathList.includes(item.path))) {
41 if (to.path === PageEnum.BASE_LOGIN && token) { 43 if (to.path === PageEnum.BASE_LOGIN && token) {
42 const isSessionTimeout = userStore.getSessionTimeout 44 const isSessionTimeout = userStore.getSessionTimeout
43 try { 45 try {
@@ -47,6 +49,9 @@ export function createPermissionGuard(router: Router) { @@ -47,6 +49,9 @@ export function createPermissionGuard(router: Router) {
47 } catch (error) { 49 } catch (error) {
48 console.error(error) 50 console.error(error)
49 } 51 }
  52 + } else if (to.matched.find(item => ShareEnum.SHARE_PATH)) {
  53 + next()
  54 + return
50 } 55 }
51 else { 56 else {
52 if (!isAloneMode) { 57 if (!isAloneMode) {
  1 +import { RouteRecordRaw } from 'vue-router'
  2 +import { ShareEnum } from '@/enums/external/pageEnum'
  3 +
  4 +// 引入路径
  5 +const importPath = {
  6 + [ShareEnum.SHARE_PATH_NAME]: () => import('@/views/share/index.vue')
  7 +}
  8 +
  9 +export const shareRoutes: RouteRecordRaw = {
  10 + path: ShareEnum.SHARE_PATH,
  11 + name: ShareEnum.SHARE_PATH_NAME,
  12 + component: importPath[ShareEnum.SHARE_PATH_NAME],
  13 + meta: {
  14 + title: '分享',
  15 + isRoot: true
  16 + }
  17 +}
  18 +
@@ -7,7 +7,10 @@ import { HttpErrorPage, LoginRoute, ReloadRoute } from '@/router/base' @@ -7,7 +7,10 @@ import { HttpErrorPage, LoginRoute, ReloadRoute } from '@/router/base'
7 import { Layout } from '@/router/constant' 7 import { Layout } from '@/router/constant'
8 8
9 import modules from '@/router/modules' 9 import modules from '@/router/modules'
  10 +// THINGS_KIT 重写路由拦截逻辑
10 import { setupRouterGuard } from './external/guard' 11 import { setupRouterGuard } from './external/guard'
  12 +// THINGS_KIT 新增分享路由
  13 +import { shareRoutes } from './external/share.route'
11 14
12 const RootRoute: Array<RouteRecordRaw> = [ 15 const RootRoute: Array<RouteRecordRaw> = [
13 { 16 {
@@ -23,7 +26,9 @@ const RootRoute: Array<RouteRecordRaw> = [ @@ -23,7 +26,9 @@ const RootRoute: Array<RouteRecordRaw> = [
23 modules.projectRoutes, 26 modules.projectRoutes,
24 modules.chartRoutes, 27 modules.chartRoutes,
25 modules.previewRoutes, 28 modules.previewRoutes,
26 - modules.editRoutes 29 + modules.editRoutes,
  30 + // THINGS_KIT 新增分享路由
  31 + shareRoutes
27 ] 32 ]
28 } 33 }
29 ] 34 ]
@@ -5,7 +5,8 @@ import { DateViewConfigurationInfoType } from '@/api/external/contentSave/model/ @@ -5,7 +5,8 @@ import { DateViewConfigurationInfoType } from '@/api/external/contentSave/model/
5 export enum ProjectInfoEnum { 5 export enum ProjectInfoEnum {
6 INFO = 'info', 6 INFO = 'info',
7 SAVE_STATUS = 'saveStatus', 7 SAVE_STATUS = 'saveStatus',
8 - DATA_VIEW_NAME = 'dataViewName' 8 + DATA_VIEW_NAME = 'dataViewName',
  9 + ACCESS_CREDENTIALS = 'accessCredentials'
9 } 10 }
10 11
11 export enum EEditCanvasTypeEnum { 12 export enum EEditCanvasTypeEnum {
@@ -17,4 +18,6 @@ export interface ProjectInfoStoreType { @@ -17,4 +18,6 @@ export interface ProjectInfoStoreType {
17 [ProjectInfoEnum.INFO]: DateViewConfigurationInfoType 18 [ProjectInfoEnum.INFO]: DateViewConfigurationInfoType
18 19
19 [ProjectInfoEnum.SAVE_STATUS]: SyncEnum 20 [ProjectInfoEnum.SAVE_STATUS]: SyncEnum
  21 +
  22 + [ProjectInfoEnum.ACCESS_CREDENTIALS]: string
20 } 23 }
@@ -6,10 +6,10 @@ import { SyncEnum } from "@/enums/external/editPageEnum"; @@ -6,10 +6,10 @@ import { SyncEnum } from "@/enums/external/editPageEnum";
6 export const useProjectInfoStore = defineStore({ 6 export const useProjectInfoStore = defineStore({
7 id: 'useProjectInfoStore', 7 id: 'useProjectInfoStore',
8 state: (): ProjectInfoStoreType => ({ 8 state: (): ProjectInfoStoreType => ({
9 - info: { 9 + info: {
10 } as ProjectInfoStoreType['info'], 10 } as ProjectInfoStoreType['info'],
11 -  
12 - saveStatus: SyncEnum.FAILURE 11 + saveStatus: SyncEnum.FAILURE,
  12 + accessCredentials: ''
13 }), 13 }),
14 getters: { 14 getters: {
15 getProjectInfo(): ProjectInfoStoreType[ProjectInfoEnum.INFO] { 15 getProjectInfo(): ProjectInfoStoreType[ProjectInfoEnum.INFO] {
@@ -28,6 +28,9 @@ export const useProjectInfoStore = defineStore({ @@ -28,6 +28,9 @@ export const useProjectInfoStore = defineStore({
28 }, 28 },
29 setSaveStatus(status: SyncEnum) { 29 setSaveStatus(status: SyncEnum) {
30 this[ProjectInfoEnum.SAVE_STATUS] = status 30 this[ProjectInfoEnum.SAVE_STATUS] = status
  31 + },
  32 + setAccessCredentials(string: string) {
  33 + this[ProjectInfoEnum.ACCESS_CREDENTIALS] = string
31 } 34 }
32 } 35 }
33 }) 36 })
@@ -2,13 +2,22 @@ import { fetchRouteParamsLocation, JSONParse, } from '@/utils' @@ -2,13 +2,22 @@ import { fetchRouteParamsLocation, JSONParse, } from '@/utils'
2 import { getDataView } from '@/api/external/contentSave/content' 2 import { getDataView } from '@/api/external/contentSave/content'
3 import { ChartEditStorageType } from '..' 3 import { ChartEditStorageType } from '..'
4 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 4 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  5 +import { useRoute } from 'vue-router'
  6 +import { ShareEnum } from '@/enums/external/pageEnum'
  7 +
  8 +
  9 +const isSharePageMode = () => {
  10 + const ROUTE = useRoute()
  11 + return ROUTE.matched.find(item => item.path === ShareEnum.SHARE_PATH)
  12 +}
5 13
6 export const getSessionStorageInfo = async () => { 14 export const getSessionStorageInfo = async () => {
  15 + if (isSharePageMode()) return
7 const id = fetchRouteParamsLocation() 16 const id = fetchRouteParamsLocation()
8 const chartEditStore = useChartEditStore() 17 const chartEditStore = useChartEditStore()
9 const res = await getDataView(id) 18 const res = await getDataView(id)
10 if (res) { 19 if (res) {
11 - const { dataViewContent, dataViewName, dataViewId } = res 20 + const { dataViewContent } = res
12 const content = JSONParse(dataViewContent.content) as ChartEditStorageType 21 const content = JSONParse(dataViewContent.content) as ChartEditStorageType
13 if (content) { 22 if (content) {
14 const { editCanvasConfig, requestGlobalConfig, componentList } = content 23 const { editCanvasConfig, requestGlobalConfig, componentList } = content
1 <template> 1 <template>
2 - <!-- THINGS_KIT 预览时需要异步请求接口 改为异步加载组件 -->  
3 - <Suspense>  
4 - <preview :key="key"></preview>  
5 - </Suspense> 2 + <preview :key="key"></preview>
6 </template> 3 </template>
7 4
8 <script setup lang="ts"> 5 <script setup lang="ts">
@@ -16,13 +13,13 @@ import Preview from './index.vue' @@ -16,13 +13,13 @@ import Preview from './index.vue'
16 13
17 let key = ref(Date.now()) 14 let key = ref(Date.now())
18 15
19 -// 数据变更 -> 组件销毁重建  
20 -;[SavePageEnum.JSON, SavePageEnum.CHART].forEach((saveEvent: string) => {  
21 - if (!window.opener) return  
22 - window.opener.addEventListener(saveEvent, async (e: any) => {  
23 - const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType  
24 - setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, [{ ...e.detail, id: localStorageInfo.id }])  
25 - key.value = Date.now() 16 + // 数据变更 -> 组件销毁重建
  17 + ;[SavePageEnum.JSON, SavePageEnum.CHART].forEach((saveEvent: string) => {
  18 + if (!window.opener) return
  19 + window.opener.addEventListener(saveEvent, async (e: any) => {
  20 + const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType
  21 + setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, [{ ...e.detail, id: localStorageInfo.id }])
  22 + key.value = Date.now()
  23 + })
26 }) 24 })
27 -})  
28 </script> 25 </script>
  1 +<template>
  2 + <section>
  3 + <preview v-if="!allowLoadPreviewPage" :key="key"></preview>
  4 + <NModal :show="allowLoadPreviewPage" :maskClosable="false" :closable="false" style="width: 300px;">
  5 + <NCard>
  6 + <NForm @keyup.enter="handleSubmit">
  7 + <NFormItem label="访问令牌">
  8 + <NInput v-model:value="accessCredentials" type="password" />
  9 + </NFormItem>
  10 + <NFormItem :showLabel="false">
  11 + <NButton :loading="loading" type="primary" style="width: 100%;" @click="handleSubmit">访问</NButton>
  12 + </NFormItem>
  13 + </NForm>
  14 + </NCard>
  15 + </NModal>
  16 + </section>
  17 +</template>
  18 +
  19 +<script setup lang="ts">
  20 +import { NModal, NCard, NForm, NFormItem, NInput, NButton, } from 'naive-ui'
  21 +import { getSessionStorageInfo } from '../preview/utils'
  22 +import type { ChartEditStorageType } from '../preview/index.d'
  23 +import { SavePageEnum } from '@/enums/editPageEnum'
  24 +import { JSONParse, setSessionStorage } from '@/utils'
  25 +import { StorageEnum } from '@/enums/storageEnum'
  26 +import { onMounted, ref, unref } from 'vue'
  27 +import Preview from '../preview/index.vue'
  28 +import { useRoute } from 'vue-router'
  29 +import { useUserStore } from '@/store/external/modules/user'
  30 +import { checkSharePageNeedAccessToken, getPublicToken, getShareContentData } from '@/api/external/sys/share'
  31 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  32 +
  33 +const allowLoadPreviewPage = ref(true)
  34 +const ROUTE = useRoute()
  35 +const accessCredentials = ref('')
  36 +const loading = ref(false)
  37 +const userStore = useUserStore()
  38 +const chartEditStore = useChartEditStore()
  39 +
  40 +const getToken = async () => {
  41 + const { params } = ROUTE
  42 + const { publicId } = params as Record<'id' | 'publicId', string>
  43 + const { token, refreshToken } = await getPublicToken(publicId)
  44 + userStore.storeToken(token, refreshToken)
  45 +}
  46 +
  47 +const checkNeedAccessToken = async () => {
  48 + const { params } = ROUTE
  49 + const { id } = params as Record<'id' | 'publicId', string>
  50 + const res = await checkSharePageNeedAccessToken(id)
  51 + return res.data
  52 +}
  53 +
  54 +const sharePageHandlerProcess = async () => {
  55 + await getToken()
  56 + const flag = await checkNeedAccessToken()
  57 + if (!flag) {
  58 + allowLoadPreviewPage.value = false
  59 + }
  60 +}
  61 +
  62 +const getSharePageContentData = async () => {
  63 + try {
  64 + const { params } = ROUTE
  65 + const { id } = params as Record<'id' | 'publicId', string>
  66 + loading.value = true
  67 + const res = await getShareContentData({ id, accessCredentials: unref(accessCredentials) })
  68 + const { dataViewContent, dataViewName, dataViewId } = res.data
  69 + const content = JSONParse(dataViewContent.content) as ChartEditStorageType
  70 + if (content) {
  71 + const { editCanvasConfig, requestGlobalConfig, componentList } = content
  72 + chartEditStore.editCanvasConfig = editCanvasConfig
  73 + chartEditStore.requestGlobalConfig = requestGlobalConfig
  74 + chartEditStore.componentList = componentList
  75 + }
  76 + allowLoadPreviewPage.value = false
  77 + } catch (error) {
  78 + console.log(error)
  79 + } finally {
  80 + loading.value = false
  81 + }
  82 +
  83 +}
  84 +
  85 +const handleSubmit = () => {
  86 + getSharePageContentData()
  87 +}
  88 +
  89 +onMounted(() => {
  90 + sharePageHandlerProcess()
  91 +})
  92 +
  93 +let key = ref(Date.now())
  94 +
  95 + // 数据变更 -> 组件销毁重建
  96 + ;[SavePageEnum.JSON, SavePageEnum.CHART].forEach((saveEvent: string) => {
  97 + if (!window.opener) return
  98 + window.opener.addEventListener(saveEvent, async (e: any) => {
  99 + const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType
  100 + setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, [{ ...e.detail, id: localStorageInfo.id }])
  101 + key.value = Date.now()
  102 + })
  103 + })
  104 +</script>