Commit ac94f5c310b3e37226beb2ef52c3893c200fb468

Authored by fengwotao
2 parents eae6895d dc4c118a

Merge branch 'main_dev' into ft

  1 +import type { ErrorMessageMode } from '/#/external/axios';
  2 +
  3 +export function checkStatus(
  4 + status: number,
  5 + msg: string,
  6 + errorMessageMode: ErrorMessageMode = 'message'
  7 +) {
  8 + let errMessage = msg;
  9 + switch (status) {
  10 + case 400:
  11 + errMessage = `${msg}`;
  12 + break;
  13 + // 401: Not logged in
  14 + // Jump to the login page if not logged in, and carry the path of the current page
  15 + // Return to the current page after successful login. This step needs to be operated on the login page.
  16 + case 401:
  17 + errMessage = '没有权限';
  18 + break;
  19 + case 403:
  20 + errMessage = '未授权';
  21 + break;
  22 + // 404请求不存在
  23 + case 404:
  24 + errMessage = '未找到该资源!';
  25 + break;
  26 + case 405:
  27 + errMessage = '网络请求错误,请求方法未允许!';
  28 + break;
  29 + case 408:
  30 + errMessage = '网络请求超时!';
  31 + break;
  32 + case 500:
  33 + errMessage = '服务器错误,请联系管理员!';
  34 + break;
  35 + case 501:
  36 + errMessage = '网络未实现!';
  37 + break;
  38 + case 502:
  39 + errMessage = '网络错误!';
  40 + break;
  41 + case 503:
  42 + errMessage = '服务不可用,服务器暂时过载或维护!';
  43 + break;
  44 + case 504:
  45 + errMessage = '网络超时!';
  46 + break;
  47 + case 505:
  48 + errMessage = 'http版本不支持该请求!';
  49 + break;
  50 + default:
  51 + }
  52 +
  53 + if (errMessage) {
  54 + if (errorMessageMode === 'message') {
  55 + const { error } = window['$message']
  56 + error(errMessage);
  57 + }
  58 + }
  59 + return !!errMessage
  60 +}
  1 +import type { AxiosResponse } from 'axios';
  2 +import type { RequestOptions, Result } from '/#/external/axios';
  3 +import type { AxiosTransform, CreateAxiosOptions } from '@/utils/external/http/axios/axiosTransform';
  4 +import { useGlobSetting } from '@/hooks/external/setting';
  5 +import { RequestEnum, ContentTypeEnum } from '@/enums/external/httpEnum';
  6 +import { isString } from '@/utils/external/is';
  7 +import { getJwtToken, getShareJwtToken } from '@/utils/external/auth';
  8 +import { setObjToUrlParams, deepMerge } from '@/utils/external';
  9 +import { formatRequestDate, joinTimestamp } from '@/utils/external/http/axios/helper';
  10 +import { VAxios } from '@/utils/external/http/axios/Axios';
  11 +import { checkStatus } from './checkStatus';
  12 +
  13 +const globSetting = useGlobSetting();
  14 +const urlPrefix = globSetting.urlPrefix;
  15 +
  16 +/**
  17 + * @description: 数据处理,方便区分多种处理方式
  18 + */
  19 +const transform: AxiosTransform = {
  20 + /**
  21 + * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
  22 + */
  23 + transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
  24 + const { isReturnNativeResponse } = options;
  25 + // 是否返回原生响应头 比如:需要获取响应头时使用该属性
  26 + if (isReturnNativeResponse) {
  27 + return res;
  28 + }
  29 + return res.data;
  30 + },
  31 +
  32 + // 请求之前处理config
  33 + beforeRequestHook: (config, options) => {
  34 + const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options;
  35 +
  36 + if (joinPrefix) {
  37 + config.url = `${urlPrefix}${config.url}`;
  38 + }
  39 +
  40 + if (apiUrl && isString(apiUrl)) {
  41 + config.url = `${apiUrl}${config.url}`;
  42 + }
  43 +
  44 + const params = config.params || {};
  45 + const data = config.data || false;
  46 + formatDate && data && !isString(data) && formatRequestDate(data);
  47 + if (config.method?.toUpperCase() === RequestEnum.GET) {
  48 + if (!isString(params)) {
  49 + // 给 get 请求加上时间戳参数,避免从缓存中拿数据。
  50 + config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
  51 + } else {
  52 + // 兼容restful风格
  53 + config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
  54 + config.params = undefined;
  55 + }
  56 + } else {
  57 + if (!isString(params)) {
  58 + formatDate && formatRequestDate(params);
  59 + if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
  60 + config.data = data;
  61 + config.params = params;
  62 + } else {
  63 + // 非GET请求如果没有提供data,则将params视为data
  64 + config.data = params;
  65 + config.params = undefined;
  66 + }
  67 + if (joinParamsToUrl) {
  68 + config.url = setObjToUrlParams(
  69 + config.url as string,
  70 + Object.assign({}, config.params, config.data)
  71 + );
  72 + }
  73 + } else {
  74 + // 兼容restful风格
  75 + config.url = config.url + params;
  76 + config.params = undefined;
  77 + }
  78 + }
  79 + return config;
  80 + },
  81 +
  82 + /**
  83 + * @description: 请求拦截器处理
  84 + */
  85 + requestInterceptors: (config, options) => {
  86 + // 请求之前处理config
  87 + const { requestOptions } = config;
  88 + const { withShareToken } = requestOptions || {};
  89 + const { requestOptions: { withToken } = {} } = options;
  90 + if (withToken !== false) {
  91 + const shareToken = getShareJwtToken();
  92 + if (withShareToken && shareToken) {
  93 + config.headers!['X-Authorization'] = options.authenticationScheme
  94 + ? `${options.authenticationScheme} ${shareToken}`
  95 + : shareToken;
  96 + } else {
  97 + const token = getJwtToken();
  98 + if (token) {
  99 + config.headers!['X-Authorization'] = options.authenticationScheme
  100 + ? `${options.authenticationScheme} ${token}`
  101 + : token;
  102 + }
  103 + }
  104 + }
  105 + return config
  106 + },
  107 +
  108 + /**
  109 + * @description: 响应拦截器处理
  110 + */
  111 + responseInterceptors: (res: AxiosResponse<any>) => {
  112 + return res;
  113 + },
  114 +
  115 + /**
  116 + * @description: 响应错误处理
  117 + */
  118 + responseInterceptorsCatch: (error: any) => {
  119 +
  120 + const { response, config } = error || {};
  121 + const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
  122 + const errorMsgIsObj = typeof response?.data === 'object';
  123 + const msg: string = errorMsgIsObj
  124 + ? response?.data?.message || response?.data?.msg
  125 + : response?.data;
  126 +
  127 + const flag = checkStatus(error?.response?.status, msg, errorMessageMode);
  128 + return Promise.reject(response?.data);
  129 + },
  130 +};
  131 +
  132 +function createAxios(opt?: Partial<CreateAxiosOptions>) {
  133 + return new VAxios(
  134 + deepMerge(
  135 + {
  136 + // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
  137 + // authentication schemes,e.g: Bearer
  138 + // authenticationScheme: 'Bearer',
  139 + authenticationScheme: 'Bearer',
  140 + timeout: 10 * 1000,
  141 + // 基础接口地址
  142 + // baseURL: globSetting.apiUrl,
  143 + // 接口可能会有通用的地址部分,可以统一抽取出来
  144 + urlPrefix: urlPrefix,
  145 + headers: { 'Content-Type': ContentTypeEnum.JSON },
  146 + // 如果是form-data格式
  147 + // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
  148 + // 数据处理方式
  149 + transform,
  150 + // 配置项,下面的选项都可以在独立的接口请求中覆盖
  151 + requestOptions: {
  152 + // 默认将prefix 添加到url
  153 + joinPrefix: true,
  154 + // 是否返回原生响应头 比如:需要获取响应头时使用该属性
  155 + isReturnNativeResponse: false,
  156 + // 需要对返回数据进行处理
  157 + isTransformResponse: true,
  158 + // post请求的时候添加参数到url
  159 + joinParamsToUrl: false,
  160 + // 格式化提交参数时间
  161 + formatDate: true,
  162 + // 消息提示类型
  163 + errorMessageMode: 'message',
  164 + // 接口地址
  165 + apiUrl: globSetting.apiUrl,
  166 + // 是否加入时间戳
  167 + joinTime: true,
  168 + // 忽略重复请求
  169 + ignoreCancelToken: true,
  170 + // 是否携带token
  171 + withToken: true
  172 + },
  173 + },
  174 + opt || {}
  175 + )
  176 + );
  177 +}
  178 +export const customHttp = createAxios();
  179 +
1 import { RequestBodyEnum, RequestParams } from "@/enums/httpEnum" 1 import { RequestBodyEnum, RequestParams } from "@/enums/httpEnum"
2 -import { ExternalRequestType, ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d"  
3 -import { RequestConfigType, RequestGlobalConfigType } from "@/store/modules/chartEditStore/chartEditStore.d"  
4 -import { defHttp } from "@/utils/external/http/axios" 2 +import { ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d"
  3 +import { RequestConfigType } from "@/store/modules/chartEditStore/chartEditStore.d"
  4 +import { isShareMode } from "@/views/share/hook"
  5 +import { customHttp } from "./http"
5 6
6 export enum ParamsType { 7 export enum ParamsType {
7 REQUIRED, 8 REQUIRED,
@@ -86,7 +87,7 @@ const transformBodyValue = (body: RequestParams['Body'], requestParamsBodyType: @@ -86,7 +87,7 @@ const transformBodyValue = (body: RequestParams['Body'], requestParamsBodyType:
86 87
87 const extraValue = (object: Recordable) => { 88 const extraValue = (object: Recordable) => {
88 return Object.keys(object).reduce((prev, next) => { 89 return Object.keys(object).reduce((prev, next) => {
89 - return {...prev, ...(object[next] ? {[next]: object[next]} : {} )} 90 + return { ...prev, ...(object[next] ? { [next]: object[next] } : {}) }
90 }, {}) 91 }, {})
91 } 92 }
92 93
@@ -103,8 +104,8 @@ export const customRequest = async (request: RequestConfigType) => { @@ -103,8 +104,8 @@ export const customRequest = async (request: RequestConfigType) => {
103 } 104 }
104 105
105 const body = transformBodyValue(Body, requestParamsBodyType) 106 const body = transformBodyValue(Body, requestParamsBodyType)
106 -  
107 - return defHttp.request<any>({ 107 +
  108 + return customHttp.request<any>({
108 url: requestUrl, 109 url: requestUrl,
109 baseURL: getOriginUrl(requestOriginUrl!), 110 baseURL: getOriginUrl(requestOriginUrl!),
110 method: requestHttpType, 111 method: requestHttpType,
@@ -113,6 +114,7 @@ export const customRequest = async (request: RequestConfigType) => { @@ -113,6 +114,7 @@ export const customRequest = async (request: RequestConfigType) => {
113 headers: extraValue(Header) 114 headers: extraValue(Header)
114 }, { 115 }, {
115 joinPrefix: false, 116 joinPrefix: false,
116 - apiUrl: '' 117 + apiUrl: '',
  118 + withShareToken: isShareMode()
117 }) 119 })
118 } 120 }
1 import { ViewTypeEnum } from "@/enums/external/viewEnum" 1 import { ViewTypeEnum } from "@/enums/external/viewEnum"
2 import { defHttp } from "@/utils/external/http/axios" 2 import { defHttp } from "@/utils/external/http/axios"
  3 +import { isShareMode } from "@/views/share/hook"
3 4
4 enum Api { 5 enum Api {
5 TOKEN = '/auth/login/public', 6 TOKEN = '/auth/login/public',
@@ -17,7 +18,7 @@ export const getPublicToken = (publicId: string) => { @@ -17,7 +18,7 @@ export const getPublicToken = (publicId: string) => {
17 return defHttp.post<Record<'token' | 'refreshToken', string>>({ 18 return defHttp.post<Record<'token' | 'refreshToken', string>>({
18 url: Api.TOKEN, 19 url: Api.TOKEN,
19 data: { publicId } 20 data: { publicId }
20 - }, { joinPrefix: false }) 21 + }, { joinPrefix: false, withShareToken: isShareMode() })
21 } 22 }
22 23
23 /** 24 /**
@@ -27,7 +28,7 @@ export const getPublicToken = (publicId: string) => { @@ -27,7 +28,7 @@ export const getPublicToken = (publicId: string) => {
27 export const checkSharePageNeedAccessToken = (id: string) => { 28 export const checkSharePageNeedAccessToken = (id: string) => {
28 return defHttp.get<{ data: boolean }>({ 29 return defHttp.get<{ data: boolean }>({
29 url: `${Api.CHECK}/${ViewTypeEnum.LARGE_SCREEN}/${id}` 30 url: `${Api.CHECK}/${ViewTypeEnum.LARGE_SCREEN}/${id}`
30 - }) 31 + }, { withShareToken: isShareMode() })
31 } 32 }
32 33
33 /** 34 /**
@@ -39,5 +40,5 @@ export const getShareContentData = (options: Record<'id' | 'accessCredentials', @@ -39,5 +40,5 @@ export const getShareContentData = (options: Record<'id' | 'accessCredentials',
39 return defHttp.get<{ data: any }>({ 40 return defHttp.get<{ data: any }>({
40 url: `${Api.SHARE_CONTENT}/${ViewTypeEnum.LARGE_SCREEN}/share_data/${options.id}`, 41 url: `${Api.SHARE_CONTENT}/${ViewTypeEnum.LARGE_SCREEN}/share_data/${options.id}`,
41 params: accessCredentials ? { accessCredentials } : {} 42 params: accessCredentials ? { accessCredentials } : {}
42 - }) 43 + }, { withShareToken: isShareMode() })
43 } 44 }
@@ -5,6 +5,10 @@ export const JWT_TOKEN_KEY = 'JWT_TOKEN'; @@ -5,6 +5,10 @@ export const JWT_TOKEN_KEY = 'JWT_TOKEN';
5 5
6 export const REFRESH_TOKEN_KEY = 'REFRESH_TOKEN'; 6 export const REFRESH_TOKEN_KEY = 'REFRESH_TOKEN';
7 7
  8 +export const SHARE_JWT_TOKEN_KEY = 'SHARE_JWT_TOKEN';
  9 +
  10 +export const SHARE_REFRESH_TOKEN_KEY = 'SHARE_REFRESH_TOKEN';
  11 +
8 export const LOCALE_KEY = 'LOCALE__'; 12 export const LOCALE_KEY = 'LOCALE__';
9 13
10 // user info key 14 // user info key
@@ -3,10 +3,11 @@ import { CreateComponentType } from "@/packages/index.d"; @@ -3,10 +3,11 @@ import { CreateComponentType } from "@/packages/index.d";
3 import { useSocketStore } from "@/store/external/modules/socketStore"; 3 import { useSocketStore } from "@/store/external/modules/socketStore";
4 import { SocketReceiveMessageType } from "@/store/external/modules/socketStore.d"; 4 import { SocketReceiveMessageType } from "@/store/external/modules/socketStore.d";
5 import { useChartEditStore } from "@/store/modules/chartEditStore/chartEditStore"; 5 import { useChartEditStore } from "@/store/modules/chartEditStore/chartEditStore";
6 -import { getJwtToken } from "@/utils/external/auth"; 6 +import { getJwtToken, getShareJwtToken } from "@/utils/external/auth";
7 import { useWebSocket, WebSocketResult } from "@vueuse/core"; 7 import { useWebSocket, WebSocketResult } from "@vueuse/core";
8 import { onMounted, unref } from "vue"; 8 import { onMounted, unref } from "vue";
9 import { ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d"; 9 import { ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d";
  10 +import { isShareMode } from "@/views/share/hook";
10 11
11 12
12 interface SocketConnectionPoolType { 13 interface SocketConnectionPoolType {
@@ -39,7 +40,7 @@ const getSocketInstance = (request: ExtraRequestConfigType) => { @@ -39,7 +40,7 @@ const getSocketInstance = (request: ExtraRequestConfigType) => {
39 if (~index) { 40 if (~index) {
40 return socketConnectionPool[index].ws 41 return socketConnectionPool[index].ws
41 } 42 }
42 - const token = getJwtToken() 43 + const token = isShareMode() ? getShareJwtToken() : getJwtToken()
43 const socketUrl = `${getOriginUrl(requestOriginUrl || '')}${requestUrl}?token=${token}` 44 const socketUrl = `${getOriginUrl(requestOriginUrl || '')}${requestUrl}?token=${token}`
44 45
45 const instance = useWebSocket(socketUrl, { 46 const instance = useWebSocket(socketUrl, {
@@ -3,7 +3,7 @@ import type { ErrorMessageMode } from '/#/external/axios'; @@ -3,7 +3,7 @@ import type { ErrorMessageMode } from '/#/external/axios';
3 import { defineStore } from 'pinia'; 3 import { defineStore } from 'pinia';
4 import { pinia as store } from '@/store'; 4 import { pinia as store } from '@/store';
5 import { RoleEnum } from '@/enums/external/roleEnum'; 5 import { RoleEnum } from '@/enums/external/roleEnum';
6 -import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY, ROLES_KEY, USER_INFO_KEY } from '@/enums/external/cacheEnum'; 6 +import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY, ROLES_KEY, SHARE_JWT_TOKEN_KEY, SHARE_REFRESH_TOKEN_KEY, USER_INFO_KEY } from '@/enums/external/cacheEnum';
7 import { getAuthCache, getJwtToken, getRefreshToken, setAuthCache } from '@/utils/external/auth'; 7 import { getAuthCache, getJwtToken, getRefreshToken, setAuthCache } from '@/utils/external/auth';
8 import { 8 import {
9 LoginParams, 9 LoginParams,
@@ -29,6 +29,8 @@ interface UserState { @@ -29,6 +29,8 @@ interface UserState {
29 lastUpdateTime: number; 29 lastUpdateTime: number;
30 jwtToken?: string; 30 jwtToken?: string;
31 refreshToken?: string; 31 refreshToken?: string;
  32 + shareJwtToken?: string;
  33 + shareRefreshToken?: string;
32 outTarget?: string; 34 outTarget?: string;
33 } 35 }
34 36
@@ -47,6 +49,8 @@ export const useUserStore = defineStore({ @@ -47,6 +49,8 @@ export const useUserStore = defineStore({
47 jwtToken: getJwtToken() as string || undefined, 49 jwtToken: getJwtToken() as string || undefined,
48 //refresh Token 50 //refresh Token
49 refreshToken: getRefreshToken() as string || undefined, 51 refreshToken: getRefreshToken() as string || undefined,
  52 + shareJwtToken: undefined,
  53 + shareRefreshToken: undefined,
50 // roleList 54 // roleList
51 roleList: [], 55 roleList: [],
52 // Whether the login expired 56 // Whether the login expired
@@ -96,6 +100,12 @@ export const useUserStore = defineStore({ @@ -96,6 +100,12 @@ export const useUserStore = defineStore({
96 setAuthCache(JWT_TOKEN_KEY, jwtToken); 100 setAuthCache(JWT_TOKEN_KEY, jwtToken);
97 setAuthCache(REFRESH_TOKEN_KEY, refreshToken); 101 setAuthCache(REFRESH_TOKEN_KEY, refreshToken);
98 }, 102 },
  103 + storeShareToken(jwtToken: string, refreshToken: string) {
  104 + this.shareJwtToken = jwtToken;
  105 + this.shareRefreshToken = refreshToken;
  106 + setAuthCache(SHARE_JWT_TOKEN_KEY, jwtToken);
  107 + setAuthCache(SHARE_REFRESH_TOKEN_KEY, refreshToken);
  108 + },
99 setToken(info: string | undefined) { 109 setToken(info: string | undefined) {
100 this.jwtToken = info; 110 this.jwtToken = info;
101 setAuthCache(JWT_TOKEN_KEY, info); 111 setAuthCache(JWT_TOKEN_KEY, info);
@@ -152,14 +162,6 @@ export const useUserStore = defineStore({ @@ -152,14 +162,6 @@ export const useUserStore = defineStore({
152 } 162 }
153 return userInfo; 163 return userInfo;
154 }, 164 },
155 - async smsCodelogin(  
156 - params: SmsLoginParams & {  
157 - goHome?: boolean;  
158 - mode?: ErrorMessageMode;  
159 - }  
160 - ) {  
161 -  
162 - },  
163 async getMyUserInfoAction() { 165 async getMyUserInfoAction() {
164 const userInfo = await getMyInfo(); 166 const userInfo = await getMyInfo();
165 this.setUserInfo(userInfo); 167 this.setUserInfo(userInfo);
@@ -193,6 +195,20 @@ export const useUserStore = defineStore({ @@ -193,6 +195,20 @@ export const useUserStore = defineStore({
193 }, 195 },
194 196
195 /** 197 /**
  198 + * @description 刷新分享页面的token
  199 + */
  200 + async doShareRefresh() {
  201 + try {
  202 + const req = { refreshToken: this.shareRefreshToken } as RefreshTokenParams
  203 + const { token, refreshToken } = await doRefreshToken(req)
  204 + this.storeShareToken(token, refreshToken)
  205 + } catch (error) {
  206 + window.location.reload()
  207 + throw error
  208 + }
  209 + },
  210 +
  211 + /**
196 * @description: Confirm before logging out 212 * @description: Confirm before logging out
197 */ 213 */
198 confirmLoginOut() { 214 confirmLoginOut() {
1 import { Persistent, BasicKeys } from '@/utils/external/cache/persistent'; 1 import { Persistent, BasicKeys } from '@/utils/external/cache/persistent';
2 -import { CacheTypeEnum } from '@/enums/external/cacheEnum'; 2 +import { CacheTypeEnum, SHARE_JWT_TOKEN_KEY, SHARE_REFRESH_TOKEN_KEY } from '@/enums/external/cacheEnum';
3 import projectSetting from '@/settings/external/projectSetting'; 3 import projectSetting from '@/settings/external/projectSetting';
4 import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY } from '@/enums/external/cacheEnum'; 4 import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY } from '@/enums/external/cacheEnum';
5 5
@@ -20,9 +20,17 @@ export function clearAuthCache(immediate = true) { @@ -20,9 +20,17 @@ export function clearAuthCache(immediate = true) {
20 const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession; 20 const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession;
21 return fn(immediate); 21 return fn(immediate);
22 } 22 }
23 -export function getJwtToken() { 23 +export function getJwtToken(): string {
24 return getAuthCache(JWT_TOKEN_KEY); 24 return getAuthCache(JWT_TOKEN_KEY);
25 } 25 }
26 -export function getRefreshToken() { 26 +export function getRefreshToken(): string {
27 return getAuthCache(REFRESH_TOKEN_KEY); 27 return getAuthCache(REFRESH_TOKEN_KEY);
28 } 28 }
  29 +
  30 +export function getShareJwtToken(): string {
  31 + return getAuthCache(SHARE_JWT_TOKEN_KEY);
  32 +}
  33 +export function getShareRefreshToken(): string {
  34 + return getAuthCache(SHARE_REFRESH_TOKEN_KEY);
  35 +}
  36 +
@@ -17,9 +17,11 @@ import { @@ -17,9 +17,11 @@ import {
17 APP_SESSION_CACHE_KEY, 17 APP_SESSION_CACHE_KEY,
18 MULTIPLE_TABS_KEY, 18 MULTIPLE_TABS_KEY,
19 MENU_LIST, 19 MENU_LIST,
  20 + SHARE_JWT_TOKEN_KEY,
  21 + SHARE_REFRESH_TOKEN_KEY,
20 } from '@/enums/external/cacheEnum'; 22 } from '@/enums/external/cacheEnum';
21 import { DEFAULT_CACHE_TIME } from '@/settings/external/encryptionSetting'; 23 import { DEFAULT_CACHE_TIME } from '@/settings/external/encryptionSetting';
22 -import { toRaw } from 'vue'; 24 +import { toRaw } from 'vue';
23 import omit from 'lodash/omit'; 25 import omit from 'lodash/omit';
24 import pick from 'lodash/pick'; 26 import pick from 'lodash/pick';
25 27
@@ -34,6 +36,8 @@ interface BasicStore { @@ -34,6 +36,8 @@ interface BasicStore {
34 [PROJ_CFG_KEY]: ProjectConfig; 36 [PROJ_CFG_KEY]: ProjectConfig;
35 [MULTIPLE_TABS_KEY]: RouteLocationNormalized[]; 37 [MULTIPLE_TABS_KEY]: RouteLocationNormalized[];
36 [MENU_LIST]: any[]; 38 [MENU_LIST]: any[];
  39 + [SHARE_JWT_TOKEN_KEY]: string
  40 + [SHARE_REFRESH_TOKEN_KEY]: string
37 } 41 }
38 42
39 type LocalStore = BasicStore; 43 type LocalStore = BasicStore;
1 -import type { AxiosRequestConfig, AxiosInstance, AxiosResponse, AxiosError } from 'axios';  
2 -import type { CreateAxiosOptions } from './axiosTransform'; 1 +import type { AxiosInstance, AxiosResponse, AxiosError } from 'axios';
  2 +import type { AxiosRequestConfig, CreateAxiosOptions } from './axiosTransform';
3 import axios from 'axios'; 3 import axios from 'axios';
4 import qs from 'qs'; 4 import qs from 'qs';
5 import { AxiosCanceler } from './axiosCancel'; 5 import { AxiosCanceler } from './axiosCancel';
@@ -115,13 +115,21 @@ export class VAxios { @@ -115,13 +115,21 @@ export class VAxios {
115 this.axiosInstance.interceptors.request.use(async (config: AxiosRequestConfig) => { 115 this.axiosInstance.interceptors.request.use(async (config: AxiosRequestConfig) => {
116 // If cancel repeat request is turned on, then cancel repeat request is prohibited 116 // If cancel repeat request is turned on, then cancel repeat request is prohibited
117 const userStore = useUserStore(); 117 const userStore = useUserStore();
118 - if (userStore && userStore.jwtToken) { 118 + // if (userStore && (userStore.jwtToken || userStore.shareJwtToken)) {
  119 + if (userStore) {
119 try { 120 try {
120 - const res = jwt_decode(userStore.jwtToken) as JwtModel;  
121 - const currentTime = (new Date().getTime() + (config.timeout || 0)) / 1000;  
122 - if (currentTime >= res.exp && this.isNeedTokenURL(config.url!)) {  
123 - await this.refreshTokenBeforeReq(userStore.doRefresh); 121 + const { requestOptions = {} } = config
  122 + const { withShareToken, withToken } = requestOptions
  123 + const token = withShareToken && withToken ? userStore.shareJwtToken : userStore.jwtToken
  124 + const doRefresh = withShareToken && withToken ? userStore.doShareRefresh : userStore.doRefresh
  125 + if (token) {
  126 + const res = jwt_decode(token) as JwtModel;
  127 + const currentTime = (new Date().getTime() + (config.timeout || 0)) / 1000;
  128 + if (currentTime >= res.exp && this.isNeedTokenURL(config.url!)) {
  129 + await this.refreshTokenBeforeReq(doRefresh);
  130 + }
124 } 131 }
  132 +
125 } catch (error) { 133 } catch (error) {
126 userStore.logout(); 134 userStore.logout();
127 } 135 }
1 /** 1 /**
2 * Data processing class, can be configured according to the project 2 * Data processing class, can be configured according to the project
3 */ 3 */
4 -import type { AxiosRequestConfig, AxiosResponse } from 'axios'; 4 +import type { AxiosRequestConfig as OriginAxiosRequestConfig, AxiosResponse } from 'axios';
5 import type { RequestOptions, Result } from '/#/external/axios'; 5 import type { RequestOptions, Result } from '/#/external/axios';
6 6
7 export interface CreateAxiosOptions extends AxiosRequestConfig { 7 export interface CreateAxiosOptions extends AxiosRequestConfig {
@@ -11,6 +11,8 @@ export interface CreateAxiosOptions extends AxiosRequestConfig { @@ -11,6 +11,8 @@ export interface CreateAxiosOptions extends AxiosRequestConfig {
11 requestOptions?: RequestOptions; 11 requestOptions?: RequestOptions;
12 } 12 }
13 13
  14 +export type AxiosRequestConfig = OriginAxiosRequestConfig & {requestOptions?: RequestOptions}
  15 +
14 export abstract class AxiosTransform { 16 export abstract class AxiosTransform {
15 /** 17 /**
16 * @description: Process configuration before request 18 * @description: Process configuration before request
@@ -9,7 +9,7 @@ import { checkStatus } from './checkStatus'; @@ -9,7 +9,7 @@ import { checkStatus } from './checkStatus';
9 import { useGlobSetting } from '@/hooks/external/setting'; 9 import { useGlobSetting } from '@/hooks/external/setting';
10 import { RequestEnum, ContentTypeEnum } from '@/enums/external/httpEnum'; 10 import { RequestEnum, ContentTypeEnum } from '@/enums/external/httpEnum';
11 import { isString } from '@/utils/external/is'; 11 import { isString } from '@/utils/external/is';
12 -import { getJwtToken } from '@/utils/external/auth'; 12 +import { getJwtToken, getShareJwtToken } from '@/utils/external/auth';
13 import { setObjToUrlParams, deepMerge } from '@/utils/external'; 13 import { setObjToUrlParams, deepMerge } from '@/utils/external';
14 import { joinTimestamp, formatRequestDate } from './helper'; 14 import { joinTimestamp, formatRequestDate } from './helper';
15 import { PageEnum } from '@/enums/external/pageEnum'; 15 import { PageEnum } from '@/enums/external/pageEnum';
@@ -89,14 +89,25 @@ const transform: AxiosTransform = { @@ -89,14 +89,25 @@ const transform: AxiosTransform = {
89 */ 89 */
90 requestInterceptors: (config, options) => { 90 requestInterceptors: (config, options) => {
91 // 请求之前处理config 91 // 请求之前处理config
92 - const token = getJwtToken();  
93 - if (token && (config as Recordable)?.requestOptions?.withToken !== false) {  
94 - // jwt token  
95 - config.headers!['X-Authorization'] = options.authenticationScheme  
96 - ? `${options.authenticationScheme} ${token}`  
97 - : token as string; 92 + const { requestOptions } = config;
  93 + const { withShareToken } = requestOptions || {};
  94 + const { requestOptions: { withToken } = {} } = options;
  95 + if (withToken !== false) {
  96 + const shareToken = getShareJwtToken();
  97 + if (withShareToken && shareToken) {
  98 + config.headers!['X-Authorization'] = options.authenticationScheme
  99 + ? `${options.authenticationScheme} ${shareToken}`
  100 + : shareToken;
  101 + } else {
  102 + const token = getJwtToken();
  103 + if (token) {
  104 + config.headers!['X-Authorization'] = options.authenticationScheme
  105 + ? `${options.authenticationScheme} ${token}`
  106 + : token;
  107 + }
  108 + }
98 } 109 }
99 - return config; 110 + return config
100 }, 111 },
101 112
102 /** 113 /**
  1 +export const isShareMode = () => {
  2 + const sharePageReg = /^\/share\/[^/]+\/[^/]+\/[^/]+$/;
  3 + const { hash } = location;
  4 + return sharePageReg.test(hash.substring(1));
  5 +};
@@ -5,10 +5,23 @@ @@ -5,10 +5,23 @@
5 <NCard> 5 <NCard>
6 <NForm @keyup.enter="handleSubmit"> 6 <NForm @keyup.enter="handleSubmit">
7 <NFormItem label="访问令牌"> 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> 8 + <NInputGroup>
  9 + <NInput v-model:value="accessCredentials" show-password-on="mousedown" type="password"
  10 + style="width: 70%;" />
  11 + <NButton :loading="loading" type="primary" style="width: 30%;" @click="handleSubmit">
  12 + <svg t="1682068997810" class="icon" viewBox="0 0 1024 1024" version="1.1"
  13 + xmlns="http://www.w3.org/2000/svg" p-id="79416" width="24" height="24">
  14 + <path
  15 + d="M512 928H128c-19.2 0-32-12.8-32-32V128c0-19.2 12.8-32 32-32h384c19.2 0 32 12.8 32 32s-12.8 32-32 32H160v704h352c19.2 0 32 12.8 32 32s-12.8 32-32 32z"
  16 + fill="#fff" p-id="79417" />
  17 + <path
  18 + d="M534.4 736c-9.6 0-16-3.2-22.4-9.6l-192-192c-12.8-12.8-12.8-32 0-44.8l192-192c12.8-12.8 32-12.8 44.8 0 12.8 12.8 12.8 32 0 44.8L387.2 512l169.6 169.6c12.8 12.8 12.8 32 0 44.8-6.4 6.4-16 9.6-22.4 9.6z"
  19 + fill="#fff" p-id="79418" />
  20 + <path d="M896 544H342.4c-19.2 0-32-12.8-32-32s12.8-32 32-32H896c19.2 0 32 12.8 32 32s-12.8 32-32 32z"
  21 + fill="#fff" p-id="79419" />
  22 + </svg>
  23 + </NButton>
  24 + </NInputGroup>
12 </NFormItem> 25 </NFormItem>
13 </NForm> 26 </NForm>
14 </NCard> 27 </NCard>
@@ -17,11 +30,11 @@ @@ -17,11 +30,11 @@
17 </template> 30 </template>
18 31
19 <script setup lang="ts"> 32 <script setup lang="ts">
20 -import { NModal, NCard, NForm, NFormItem, NInput, NButton, } from 'naive-ui' 33 +import { NModal, NCard, NForm, NFormItem, NInput, NButton, NInputGroup } from 'naive-ui'
21 import { getSessionStorageInfo } from '../preview/utils' 34 import { getSessionStorageInfo } from '../preview/utils'
22 import type { ChartEditStorageType } from '../preview/index.d' 35 import type { ChartEditStorageType } from '../preview/index.d'
23 import { SavePageEnum } from '@/enums/editPageEnum' 36 import { SavePageEnum } from '@/enums/editPageEnum'
24 -import { JSONParse, setSessionStorage } from '@/utils' 37 +import { JSONParse, setSessionStorage, setTitle } from '@/utils'
25 import { StorageEnum } from '@/enums/storageEnum' 38 import { StorageEnum } from '@/enums/storageEnum'
26 import { onMounted, ref, unref } from 'vue' 39 import { onMounted, ref, unref } from 'vue'
27 import Preview from '../preview/index.vue' 40 import Preview from '../preview/index.vue'
@@ -42,7 +55,7 @@ const getToken = async () => { @@ -42,7 +55,7 @@ const getToken = async () => {
42 const { params } = ROUTE 55 const { params } = ROUTE
43 const { publicId } = params as Record<'id' | 'publicId', string> 56 const { publicId } = params as Record<'id' | 'publicId', string>
44 const { token, refreshToken } = await getPublicToken(publicId) 57 const { token, refreshToken } = await getPublicToken(publicId)
45 - userStore.storeToken(token, refreshToken) 58 + userStore.storeShareToken(token, refreshToken)
46 } 59 }
47 60
48 const checkNeedAccessToken = async () => { 61 const checkNeedAccessToken = async () => {
@@ -77,6 +90,7 @@ const getSharePageContentData = async () => { @@ -77,6 +90,7 @@ const getSharePageContentData = async () => {
77 chartEditStore.requestGlobalConfig = requestGlobalConfig 90 chartEditStore.requestGlobalConfig = requestGlobalConfig
78 chartEditStore.componentList = componentList 91 chartEditStore.componentList = componentList
79 } 92 }
  93 + setTitle(dataViewName || '')
80 showModal.value = false 94 showModal.value = false
81 allowLoadPreviewPage.value = false 95 allowLoadPreviewPage.value = false
82 } catch (error) { 96 } catch (error) {
@@ -20,7 +20,8 @@ @@ -20,7 +20,8 @@
20 ], 20 ],
21 "typeRoots": [ 21 "typeRoots": [
22 "./node_modules/@types/", 22 "./node_modules/@types/",
23 - "./types" 23 + "./types",
  24 + "./types/external"
24 ], 25 ],
25 "paths": { 26 "paths": {
26 "@/*": [ 27 "@/*": [
@@ -21,6 +21,8 @@ export interface RequestOptions { @@ -21,6 +21,8 @@ export interface RequestOptions {
21 ignoreCancelToken?: boolean; 21 ignoreCancelToken?: boolean;
22 // Whether to send token in header 22 // Whether to send token in header
23 withToken?: boolean; 23 withToken?: boolean;
  24 + // Carry and share token 携带分享的访问令牌
  25 + withShareToken?: boolean
24 } 26 }
25 27
26 export interface Result<T = any> { 28 export interface Result<T = any> {