Commit e1fe720c27de33a26dcad8ec22ca2cc7225a5f8b

Authored by xp.Huang
2 parents 30a3cf57 08ab7d72

Merge branch 'main_dev'

# Conflicts:
#	src/api/external/customRequest/index.ts
#	src/api/external/dynamicRequest/index.ts
#	src/api/external/dynamicRequest/model/index.ts
#	src/api/external/sys/share.ts
#	src/hooks/external/useChartDataSocket.ts
#	src/hooks/external/useFetchTargetData.ts
#	src/packages/components/external/Composes/HeadCombinations/LeftCenterRightHead/index.vue
#	src/packages/components/external/Composes/HeadCombinations/LeftCenterRightHeadAnimat/index.vue
#	src/packages/components/external/Composes/Mores/Camera/cameraItem.vue
#	src/packages/components/external/Composes/Mores/Camera/config.ts
#	src/packages/components/external/Composes/Mores/Camera/index.vue
#	src/packages/components/external/Composes/Mores/Title1/config.ts
#	src/packages/components/external/Composes/Mores/Title1/config.vue
#	src/packages/components/external/Composes/Mores/Title1/index.vue
#	src/packages/components/external/Composes/Mores/Title2/config.ts
#	src/packages/components/external/Composes/Mores/Title2/config.vue
#	src/packages/components/external/Composes/Mores/Title2/index.vue
#	src/packages/components/external/Composes/Mores/Title3/config.ts
#	src/packages/components/external/Composes/Mores/Title3/config.vue
#	src/packages/components/external/Composes/Mores/Title3/index.vue
#	src/store/external/modules/socketStore.ts
#	src/views/chart/ContentConfigurations/components/ChartData/external/components/ChartDynamicRequest/index.vue
#	src/views/chart/ContentConfigurations/components/ChartData/external/components/DynamicForm/index.vue
#	src/views/chart/ContentConfigurations/components/ChartData/external/components/DynamicForm/useDynamicPublicForm.ts
#	src/views/chart/ContentConfigurations/components/ChartData/external/components/PublicInterfaceForm/index.vue
#	src/views/chart/ContentConfigurations/components/ChartData/external/components/RequestModal/index.vue
#	src/views/chart/ContentHeader/headerLeftBtn/external/index.vue
#	src/views/chart/hooks/external/useRemote.hook.ts
#	src/views/share/index.vue
Showing 53 changed files with 1222 additions and 238 deletions
  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"
  6 +import { SelectTimeAggregationFieldEnum } from "@/views/chart/ContentConfigurations/components/ChartData/external/components/SelectTImeAggregation"
5 7
6 export enum ParamsType { 8 export enum ParamsType {
7 REQUIRED, 9 REQUIRED,
@@ -86,10 +88,25 @@ const transformBodyValue = (body: RequestParams['Body'], requestParamsBodyType: @@ -86,10 +88,25 @@ const transformBodyValue = (body: RequestParams['Body'], requestParamsBodyType:
86 88
87 const extraValue = (object: Recordable) => { 89 const extraValue = (object: Recordable) => {
88 return Object.keys(object).reduce((prev, next) => { 90 return Object.keys(object).reduce((prev, next) => {
89 - return {...prev, ...(object[next] ? {[next]: object[next]} : {} )} 91 + return { ...prev, ...(object[next] ? { [next]: object[next] } : {}) }
90 }, {}) 92 }, {})
91 } 93 }
92 94
  95 +const handleParams = (Params: Recordable) => {
  96 + if (Params.keys && Params?.keys?.length) {
  97 + Params.keys = (Params.keys || [] as any).join(',')
  98 + }
  99 +
  100 + const timePeriod = Params[SelectTimeAggregationFieldEnum.TIME_PERIOD]
  101 + if (timePeriod) {
  102 + Params.startTs = Date.now() - timePeriod
  103 + Params.endTs = Date.now()
  104 + Reflect.deleteProperty(Params, SelectTimeAggregationFieldEnum.TIME_PERIOD)
  105 + }
  106 +
  107 + return Object.keys(Params).filter(Boolean).reduce((prev, next) => ({ ...prev, [next]: Params[next] }), {})
  108 +}
  109 +
93 export const customRequest = async (request: RequestConfigType) => { 110 export const customRequest = async (request: RequestConfigType) => {
94 const { requestHttpType, requestParams, requestParamsBodyType, requestOriginUrl } = request as ExtraRequestConfigType 111 const { requestHttpType, requestParams, requestParamsBodyType, requestOriginUrl } = request as ExtraRequestConfigType
95 let { requestUrl } = request as ExtraRequestConfigType 112 let { requestUrl } = request as ExtraRequestConfigType
@@ -104,7 +121,8 @@ export const customRequest = async (request: RequestConfigType) => { @@ -104,7 +121,8 @@ export const customRequest = async (request: RequestConfigType) => {
104 121
105 const body = transformBodyValue(Body, requestParamsBodyType) 122 const body = transformBodyValue(Body, requestParamsBodyType)
106 123
107 - return defHttp.request<any>({ 124 + Params = handleParams(Params)
  125 + return customHttp.request<any>({
108 url: requestUrl, 126 url: requestUrl,
109 baseURL: getOriginUrl(requestOriginUrl!), 127 baseURL: getOriginUrl(requestOriginUrl!),
110 method: requestHttpType, 128 method: requestHttpType,
@@ -113,6 +131,7 @@ export const customRequest = async (request: RequestConfigType) => { @@ -113,6 +131,7 @@ export const customRequest = async (request: RequestConfigType) => {
113 headers: extraValue(Header) 131 headers: extraValue(Header)
114 }, { 132 }, {
115 joinPrefix: false, 133 joinPrefix: false,
116 - apiUrl: '' 134 + apiUrl: '',
  135 + withShareToken: isShareMode()
117 }) 136 })
118 } 137 }
@@ -2,13 +2,20 @@ import { defHttp } from '@/utils/external/http/axios'; @@ -2,13 +2,20 @@ import { defHttp } from '@/utils/external/http/axios';
2 import { DeviceAttributesRecord, GetDeviceListParams, PublicInterfaceRecord, PublicInterfaceStateEnum } from './model'; 2 import { DeviceAttributesRecord, GetDeviceListParams, PublicInterfaceRecord, PublicInterfaceStateEnum } from './model';
3 import { PaginationResult } from '/#/external/axios'; 3 import { PaginationResult } from '/#/external/axios';
4 4
5 -enum Api {  
6 - PUBLIC_API = '/data_view_interface',  
7 - ORG_LISt = '/organization/me/list',  
8 - DEVICE_PROFILE_LIST = '/device_profile/me/list',  
9 - DEVICE_LIST = '/device/list',  
10 - DEVICE_ATTR_LIST = '/device/attributes',  
11 - GET_PUBLIC_INTERFACE_ALL = '/data_view_interface/find_all_interface', 5 + /**
  6 + * ft 更换接口
  7 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  8 + * 源代码 GET_PUBLIC_INTERFACE_ALL = '/data_view_interface/find_all_interface',
  9 + * 修改后代码 GET_PUBLIC_INTERFACE_ALL = '/data_view_interface/find/can_use_interfaces',
  10 + */
  11 + enum Api {
  12 + PUBLIC_API = '/data_view_interface',
  13 + ORG_LISt = '/organization/me/list',
  14 + DEVICE_PROFILE_LIST = '/device_profile/me/list',
  15 + DEVICE_LIST = '/device/list',
  16 + DEVICE_ATTR_LIST = '/device/attributes',
  17 + GET_PUBLIC_INTERFACE_ALL = '/data_view_interface/find/can_use_interfaces',
  18 + //ft
12 GET_PUBLIC_INTERFACE_DETAIL = '/data_view_interface/get_interface_details' 19 GET_PUBLIC_INTERFACE_DETAIL = '/data_view_interface/get_interface_details'
13 } 20 }
14 21
@@ -52,9 +59,15 @@ export const getDeviceInterfaceDetail = async (interfaces: string[]) => { @@ -52,9 +59,15 @@ export const getDeviceInterfaceDetail = async (interfaces: string[]) => {
52 params: interfaces 59 params: interfaces
53 }) 60 })
54 } 61 }
55 -  
56 -export const getAllPublicInterface = async (params?: { state: PublicInterfaceStateEnum }) => { 62 + /**
  63 + * ft 更换接口
  64 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  65 + * 源代码 url: `${Api.GET_PUBLIC_INTERFACE_ALL}${params?.state ? `/${params.state}` : ''}`
  66 + * 修改后代码 url: `${Api.GET_PUBLIC_INTERFACE_ALL}`
  67 + */
  68 +export const getAllPublicInterface = async () => {
57 return defHttp.get<PublicInterfaceRecord[]>({ 69 return defHttp.get<PublicInterfaceRecord[]>({
58 - url: `${Api.GET_PUBLIC_INTERFACE_ALL}${params?.state ? `/${params.state}` : ''}` 70 + url: `${Api.GET_PUBLIC_INTERFACE_ALL}`
59 }) 71 })
60 } 72 }
  73 +//ft
@@ -9,6 +9,7 @@ export interface ParamsItemType { @@ -9,6 +9,7 @@ export interface ParamsItemType {
9 key: string 9 key: string
10 required: boolean 10 required: boolean
11 value: string 11 value: string
  12 + mores: boolean
12 } 13 }
13 14
14 export interface PublicInterfaceRequestParams { 15 export interface PublicInterfaceRequestParams {
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, {
@@ -26,7 +26,7 @@ export const useFetchTargetData = () => { @@ -26,7 +26,7 @@ export const useFetchTargetData = () => {
26 } catch (error) { 26 } catch (error) {
27 loading.value = false 27 loading.value = false
28 console.error(error); 28 console.error(error);
29 - window['$message'].warning('数据异常,请检查参数!') 29 + // window['$message'].warning('数据异常,请检查参数!')
30 } 30 }
31 } 31 }
32 return { fetchTargetData, loading } 32 return { fetchTargetData, loading }
@@ -6,7 +6,7 @@ import cloneDeep from 'lodash/cloneDeep' @@ -6,7 +6,7 @@ import cloneDeep from 'lodash/cloneDeep'
6 6
7 export const option = { 7 export const option = {
8 // 网站路径 8 // 网站路径
9 - dataset: "https://www.mtruning.club/", 9 + dataset: "https://www.thingskit.com/",
10 // 圆角 10 // 圆角
11 borderRadius: 10 11 borderRadius: 10
12 } 12 }
@@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public' @@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public'
2 import { CreateComponentType } from '@/packages/index.d' 2 import { CreateComponentType } from '@/packages/index.d'
3 import { LeftCenterRightHeadConfig } from './index' 3 import { LeftCenterRightHeadConfig } from './index'
4 import cloneDeep from 'lodash/cloneDeep' 4 import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
5 6
6 export const option = { 7 export const option = {
7 dataset: '物联网平台数据统计', 8 dataset: '物联网平台数据统计',
@@ -20,6 +21,7 @@ export const option = { @@ -20,6 +21,7 @@ export const option = {
20 21
21 export default class Config extends PublicConfigClass implements CreateComponentType { 22 export default class Config extends PublicConfigClass implements CreateComponentType {
22 public key = LeftCenterRightHeadConfig.key 23 public key = LeftCenterRightHeadConfig.key
  24 + public attr = { ...chartInitConfig, zIndex: 1, w: 1920, h: 100 }
23 public chartConfig = cloneDeep(LeftCenterRightHeadConfig) 25 public chartConfig = cloneDeep(LeftCenterRightHeadConfig)
24 public option = cloneDeep(option) 26 public option = cloneDeep(option)
25 } 27 }
@@ -59,6 +59,11 @@ @@ -59,6 +59,11 @@
59 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.textColor"></n-color-picker> 59 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.textColor"></n-color-picker>
60 </setting-item> 60 </setting-item>
61 </setting-item-box> 61 </setting-item-box>
  62 + <setting-item-box name="颜色">
  63 + <SettingItem>
  64 + <n-button size="small" @click="optionData.textColor = '#00f6ff'"> 恢复默认 </n-button>
  65 + </SettingItem>
  66 + </setting-item-box>
62 <setting-item-box name="位置x轴"> 67 <setting-item-box name="位置x轴">
63 <setting-item name="字体位置x轴"> 68 <setting-item name="字体位置x轴">
64 <n-input-number v-model:value="optionData.x" size="small" placeholder="字体位置"></n-input-number> 69 <n-input-number v-model:value="optionData.x" size="small" placeholder="字体位置"></n-input-number>
@@ -96,6 +101,11 @@ @@ -96,6 +101,11 @@
96 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.textRightSizeColor"></n-color-picker> 101 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.textRightSizeColor"></n-color-picker>
97 </setting-item> 102 </setting-item>
98 </setting-item-box> 103 </setting-item-box>
  104 + <setting-item-box name="颜色">
  105 + <SettingItem>
  106 + <n-button size="small" @click="optionData.textRightSizeColor = '#ffffff'"> 恢复默认 </n-button>
  107 + </SettingItem>
  108 + </setting-item-box>
99 </collapse-item> 109 </collapse-item>
100 </template> 110 </template>
101 111
@@ -65,11 +65,8 @@ let nowData = ref('08:00:00') @@ -65,11 +65,8 @@ let nowData = ref('08:00:00')
65 let newData = ref('2021-2-3 08:00:00') 65 let newData = ref('2021-2-3 08:00:00')
66 66
67 let timer: any = null 67 let timer: any = null
68 -const { w, h } = toRefs(props.chartConfig.attr)  
69 68
70 -//修改默认宽高  
71 -props.chartConfig.attr.w = 1920  
72 -props.chartConfig.attr.h = 100 69 +const { w, h } = toRefs(props.chartConfig.attr)
73 70
74 watch( 71 watch(
75 () => props.chartConfig.option, 72 () => props.chartConfig.option,
@@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public' @@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public'
2 import { CreateComponentType } from '@/packages/index.d' 2 import { CreateComponentType } from '@/packages/index.d'
3 import { LeftCenterRightHeadAnimatConfig } from './index' 3 import { LeftCenterRightHeadAnimatConfig } from './index'
4 import cloneDeep from 'lodash/cloneDeep' 4 import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
5 6
6 export const option = { 7 export const option = {
7 dataset: '我是标题', 8 dataset: '我是标题',
@@ -26,6 +27,7 @@ export const option = { @@ -26,6 +27,7 @@ export const option = {
26 27
27 export default class Config extends PublicConfigClass implements CreateComponentType { 28 export default class Config extends PublicConfigClass implements CreateComponentType {
28 public key = LeftCenterRightHeadAnimatConfig.key 29 public key = LeftCenterRightHeadAnimatConfig.key
  30 + public attr = { ...chartInitConfig, zIndex: 1, w: 1920, h: 130 }
29 public chartConfig = cloneDeep(LeftCenterRightHeadAnimatConfig) 31 public chartConfig = cloneDeep(LeftCenterRightHeadAnimatConfig)
30 public option = cloneDeep(option) 32 public option = cloneDeep(option)
31 } 33 }
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.animat.colors[index]"></n-color-picker> 5 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.animat.colors[index]"></n-color-picker>
6 </SettingItem> 6 </SettingItem>
7 <SettingItem> 7 <SettingItem>
8 - <n-button size="small" @click="optionData.animat.colors[index] = optionData.animat.colors[index]"> 8 + <n-button size="small" @click="optionData.animat.colors[index] = option.animat.colors[index]">
9 恢复默认 9 恢复默认
10 </n-button> 10 </n-button>
11 </SettingItem> 11 </SettingItem>
@@ -47,6 +47,12 @@ @@ -47,6 +47,12 @@
47 <setting-item name="结束值"> 47 <setting-item name="结束值">
48 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.animat.gradient.to"></n-color-picker> 48 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.animat.gradient.to"></n-color-picker>
49 </setting-item> 49 </setting-item>
  50 + <SettingItem>
  51 + <n-button size="small" @click="optionData.animat.gradient.from = '#0000FFFF'"> 恢复默认1 </n-button>
  52 + </SettingItem>
  53 + <SettingItem>
  54 + <n-button size="small" @click="optionData.animat.gradient.to = '#00FF00FF'"> 恢复默认2 </n-button>
  55 + </SettingItem>
50 <setting-item name="偏移角度"> 56 <setting-item name="偏移角度">
51 <n-input-number 57 <n-input-number
52 v-model:value="optionData.animat.gradient.deg" 58 v-model:value="optionData.animat.gradient.deg"
@@ -64,10 +64,6 @@ const props = defineProps({ @@ -64,10 +64,6 @@ const props = defineProps({
64 } 64 }
65 }) 65 })
66 66
67 -//修改默认宽高  
68 -props.chartConfig.attr.w=1920  
69 -props.chartConfig.attr.h=130  
70 -  
71 const { w, h } = toRefs(props.chartConfig.attr) 67 const { w, h } = toRefs(props.chartConfig.attr)
72 68
73 const { animat, dataset } = toRefs(props.chartConfig.option) 69 const { animat, dataset } = toRefs(props.chartConfig.option)
1 <template> 1 <template>
2 <div class="go-content-box" :style="{ width: w + 'px', height: h + 'px' }"> 2 <div class="go-content-box" :style="{ width: w + 'px', height: h + 'px' }">
3 - <video :id="`my-player${index}`" ref="videoRef" class="video-js my-video vjs-theme-city vjs-big-play-centered"> 3 + <video
  4 + crossOrigin="anonymous"
  5 + :id="`my-player${index}`" ref="videoRef" class="video-js my-video vjs-theme-city vjs-big-play-centered">
4 <source :src="sourceSrc" /> 6 <source :src="sourceSrc" />
5 </video> 7 </video>
6 </div> 8 </div>
@@ -15,6 +17,12 @@ const props = defineProps({ @@ -15,6 +17,12 @@ const props = defineProps({
15 sourceSrc: { 17 sourceSrc: {
16 type: String 18 type: String
17 }, 19 },
  20 + name: {
  21 + type: String
  22 + },
  23 + avatar: {
  24 + type: String
  25 + },
18 w: { 26 w: {
19 type: Number, 27 type: Number,
20 default: 300 28 default: 300
@@ -41,7 +49,8 @@ const options: VideoJsPlayerOptions = { @@ -41,7 +49,8 @@ const options: VideoJsPlayerOptions = {
41 preload: 'auto', // 预加载 49 preload: 'auto', // 预加载
42 autoplay: true, // 是否自动播放 50 autoplay: true, // 是否自动播放
43 fluid: false, // 自适应宽高 51 fluid: false, // 自适应宽高
44 - src: props.sourceSrc, // 要嵌入的视频源的源 URL 52 + poster: props?.avatar || '',
  53 + src: props?.sourceSrc || '', // 要嵌入的视频源的源 URL
45 muted: true, 54 muted: true,
46 userActions: { 55 userActions: {
47 hotkeys: true 56 hotkeys: true
@@ -6,29 +6,8 @@ import cloneDeep from 'lodash/cloneDeep' @@ -6,29 +6,8 @@ import cloneDeep from 'lodash/cloneDeep'
6 export const option = { 6 export const option = {
7 dataset: [ 7 dataset: [
8 { 8 {
9 - url: 'https://vcsplay.scjtonline.cn:8094/live/HD_664c01b9-4b67-11eb-bf78-3cd2e55e0a36.m3u8?auth_key=1681457689-0-0-a797d264f2889a388c52ff188fedf7dc' 9 + url: ''
10 }, 10 },
11 - {  
12 - url: 'https://vcsplay.scjtonline.cn:8196/live/HD_c53fd3cb-4a6d-11eb-8edc-3cd2e55e088c.m3u8?auth_key=1681457668-0-0-7ef56e21fddd9ffb9740cbe499a1824c'  
13 - },  
14 - {  
15 - url: 'https://vcsplay.scjtonline.cn:8199/live/HD_53713154-1371-489a-a929-015cca5569fc.m3u8?auth_key=1681441451-0-0-4f1ebdcf28a71b7631c0028c099923c9'  
16 - },  
17 - {  
18 - url: 'https://vcsplay.scjtonline.cn:8195/live/HD_c54034ca-4a6d-11eb-8edc-3cd2e55e088c.m3u8?auth_key=1681457640-0-0-3a53b856ac19c09273986e8281f3d727'  
19 - },  
20 - {  
21 - url: 'https://vcsplay.scjtonline.cn:8094/live/HD_664c01b9-4b67-11eb-bf78-3cd2e55e0a36.m3u8?auth_key=1681457689-0-0-a797d264f2889a388c52ff188fedf7dc'  
22 - },  
23 - {  
24 - url: 'https://vcsplay.scjtonline.cn:8196/live/HD_c53fd3cb-4a6d-11eb-8edc-3cd2e55e088c.m3u8?auth_key=1681457668-0-0-7ef56e21fddd9ffb9740cbe499a1824c'  
25 - },  
26 - {  
27 - url: 'https://vcsplay.scjtonline.cn:8199/live/HD_53713154-1371-489a-a929-015cca5569fc.m3u8?auth_key=1681441451-0-0-4f1ebdcf28a71b7631c0028c099923c9'  
28 - },  
29 - {  
30 - url: 'https://vcsplay.scjtonline.cn:8195/live/HD_c54034ca-4a6d-11eb-8edc-3cd2e55e088c.m3u8?auth_key=1681457640-0-0-3a53b856ac19c09273986e8281f3d727'  
31 - }  
32 ] as any, 11 ] as any,
33 // 自动播放的间隔(ms) 12 // 自动播放的间隔(ms)
34 interval: 5000, 13 interval: 5000,
@@ -2,7 +2,17 @@ @@ -2,7 +2,17 @@
2 <div class="banner-box" ref="root"> 2 <div class="banner-box" ref="root">
3 <div class="wrapper"> 3 <div class="wrapper">
4 <div v-for="(item, index) in option.dataset" :key="index + item" :class="item.className" :style="item.sty"> 4 <div v-for="(item, index) in option.dataset" :key="index + item" :class="item.className" :style="item.sty">
5 - <CameraItem ref="cameraRef" :key="item + index" :sourceSrc="item.url" :w="w" :h="h" :index="index" /> 5 + <CameraItem
  6 + ref="cameraRef"
  7 + :name="item.name"
  8 + :avatar="item.avatar"
  9 + :key="item + index"
  10 + :sourceSrc="item.url"
  11 + :w="w"
  12 + :h="h"
  13 + :index="index"
  14 + />
  15 + <span class="video-title">{{ item.name }}</span>
6 </div> 16 </div>
7 </div> 17 </div>
8 <a href="javascript:;" class="left" @click="changeSlide('left')"></a> 18 <a href="javascript:;" class="left" @click="changeSlide('left')"></a>
@@ -37,53 +47,54 @@ let interval = ref(4000) @@ -37,53 +47,54 @@ let interval = ref(4000)
37 47
38 const computedFunc = (initial: number, source: any) => { 48 const computedFunc = (initial: number, source: any) => {
39 if (initial < 0) initial = 0 49 if (initial < 0) initial = 0
40 - let len = source.length,  
41 - temp1 = initial - 2 < 0 ? initial - 2 + len : initial - 2,  
42 - temp2 = initial - 1 < 0 ? initial - 1 + len : initial - 1,  
43 - temp3 = initial,  
44 - temp4 = initial + 1 >= len ? initial + 1 - len : initial + 1,  
45 - temp5 = initial + 2 >= len ? initial + 2 - len : initial + 2  
46 - return source.map((item: any, index: number) => {  
47 - let transform = `translate(-50%, -50%) scale(0.7)`,  
48 - zIndex = 0,  
49 - className = 'slide'  
50 - switch (index) {  
51 - case temp3:  
52 - transform = `translate(-50%, -50%) scale(1)`  
53 - className = ['slide', 'activate'] as any  
54 - zIndex = 3  
55 - break  
56 - case temp1:  
57 - transform = `translate(-80%, -50%) scale(0.7)`  
58 - zIndex = 1  
59 - break  
60 - case temp5:  
61 - transform = `translate(100%, -50%) scale(0.7)`  
62 - zIndex = 1  
63 - break  
64 - case temp2:  
65 - transform = `translate(-100%, -50%) scale(0.85)`  
66 - zIndex = 2  
67 - break  
68 - case temp4:  
69 - transform = `translate(58%, -50%) scale(0.85)`  
70 - zIndex = 2  
71 - break  
72 - }  
73 - item.sty = {  
74 - transform,  
75 - zIndex  
76 - }  
77 - item.className = className  
78 - return item  
79 - }) 50 + if (Array.isArray(source)) {
  51 + let len = source.length,
  52 + temp1 = initial - 2 < 0 ? initial - 2 + len : initial - 2,
  53 + temp2 = initial - 1 < 0 ? initial - 1 + len : initial - 1,
  54 + temp3 = initial,
  55 + temp4 = initial + 1 >= len ? initial + 1 - len : initial + 1,
  56 + temp5 = initial + 2 >= len ? initial + 2 - len : initial + 2
  57 + return source?.map((item: any, index: number) => {
  58 + let transform = `translate(-50%, -50%) scale(0.7)`,
  59 + zIndex = 0,
  60 + className = 'slide'
  61 + switch (index) {
  62 + case temp3:
  63 + transform = `translate(-50%, -50%) scale(1)`
  64 + className = ['slide', 'activate'] as any
  65 + zIndex = 3
  66 + break
  67 + case temp1:
  68 + transform = `translate(-80%, -50%) scale(0.7)`
  69 + zIndex = 1
  70 + break
  71 + case temp5:
  72 + transform = `translate(100%, -50%) scale(0.7)`
  73 + zIndex = 1
  74 + break
  75 + case temp2:
  76 + transform = `translate(-100%, -50%) scale(0.85)`
  77 + zIndex = 2
  78 + break
  79 + case temp4:
  80 + transform = `translate(58%, -50%) scale(0.85)`
  81 + zIndex = 2
  82 + break
  83 + }
  84 + item.sty = {
  85 + transform,
  86 + zIndex
  87 + }
  88 + item.className = className
  89 + return item
  90 + })
  91 + }
80 } 92 }
81 93
82 watch( 94 watch(
83 () => props.chartConfig.option.dataset, 95 () => props.chartConfig.option.dataset,
84 newData => { 96 newData => {
85 option.dataset = newData 97 option.dataset = newData
86 - console.log(option.dataset)  
87 }, 98 },
88 { 99 {
89 immediate: true, 100 immediate: true,
@@ -143,12 +154,6 @@ function changeSlide(dir: string) { @@ -143,12 +154,6 @@ function changeSlide(dir: string) {
143 154
144 <style lang="scss" scoped> 155 <style lang="scss" scoped>
145 .banner-box { 156 .banner-box {
146 - width: 100%;  
147 - height: 100%;  
148 - // position: absolute;  
149 - top: 50%;  
150 - left: 50%;  
151 - transform: translate(-50%, -50%);  
152 .wrapper { 157 .wrapper {
153 width: 100%; 158 width: 100%;
154 height: 100%; 159 height: 100%;
@@ -162,6 +167,15 @@ function changeSlide(dir: string) { @@ -162,6 +167,15 @@ function changeSlide(dir: string) {
162 transform: translate(-50%, -50%); 167 transform: translate(-50%, -50%);
163 transition: 0.5s; 168 transition: 0.5s;
164 box-shadow: 0 0 4px black; 169 box-shadow: 0 0 4px black;
  170 + .video-title {
  171 + width: v-bind('w+"px"');
  172 + font-size: 30px;
  173 + color: white;
  174 + position: absolute;
  175 + bottom: 6%;
  176 + left: 10%;
  177 + z-index: 999;
  178 + }
165 } 179 }
166 } 180 }
167 .arrow { 181 .arrow {
@@ -2,22 +2,25 @@ import { PublicConfigClass } from '@/packages/public' @@ -2,22 +2,25 @@ import { PublicConfigClass } from '@/packages/public'
2 import { CreateComponentType } from '@/packages/index.d' 2 import { CreateComponentType } from '@/packages/index.d'
3 import { Title1Config } from './index' 3 import { Title1Config } from './index'
4 import cloneDeep from 'lodash/cloneDeep' 4 import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
5 6
6 export const option = { 7 export const option = {
7 dataset: '我是标题', 8 dataset: '我是标题',
8 attribute: { 9 attribute: {
9 - linearColors: ['#0559A3', '#0654A3', '#2AFFFF', '#2AFFFF','#2affff',' #2affff','#16d9d9'], 10 + linearColors: ['#0559A3', '#0654A3', '#2AFFFF', '#2AFFFF', '#2affff', ' #2affff', '#16d9d9'],
10 fontSize: 20, 11 fontSize: 20,
11 fontPos: { 12 fontPos: {
12 x: 0, 13 x: 0,
13 y: 20 14 y: 20
14 }, 15 },
15 - fontColor: '#2AFFFF' 16 + fontColor: '#2AFFFF',
  17 + lineColor: '#2AFFFF'
16 } 18 }
17 } 19 }
18 20
19 export default class Config extends PublicConfigClass implements CreateComponentType { 21 export default class Config extends PublicConfigClass implements CreateComponentType {
20 public key = Title1Config.key 22 public key = Title1Config.key
  23 + public attr = { ...chartInitConfig, zIndex: 1, w: 550, h: 60 }
21 public chartConfig = cloneDeep(Title1Config) 24 public chartConfig = cloneDeep(Title1Config)
22 public option = cloneDeep(option) 25 public option = cloneDeep(option)
23 } 26 }
@@ -7,15 +7,18 @@ @@ -7,15 +7,18 @@
7 <SettingItem name="大小"> 7 <SettingItem name="大小">
8 <n-input-number v-model:value="optionData.attribute.fontSize" /> 8 <n-input-number v-model:value="optionData.attribute.fontSize" />
9 </SettingItem> 9 </SettingItem>
10 - <SettingItem name="颜色">  
11 - <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.fontColor"></n-color-picker>  
12 - </SettingItem>  
13 <SettingItem name="x轴位置"> 10 <SettingItem name="x轴位置">
14 <n-input-number v-model:value="optionData.attribute.fontPos.x" /> 11 <n-input-number v-model:value="optionData.attribute.fontPos.x" />
15 </SettingItem> 12 </SettingItem>
16 <SettingItem name="y轴位置"> 13 <SettingItem name="y轴位置">
17 <n-input-number v-model:value="optionData.attribute.fontPos.y" /> 14 <n-input-number v-model:value="optionData.attribute.fontPos.y" />
18 </SettingItem> 15 </SettingItem>
  16 + <SettingItem name="颜色">
  17 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.fontColor"></n-color-picker>
  18 + </SettingItem>
  19 + <SettingItem>
  20 + <n-button size="small" @click="optionData.attribute.fontColor = '#2AFFFF'"> 恢复默认 </n-button>
  21 + </SettingItem>
19 </SettingItemBox> 22 </SettingItemBox>
20 <SettingItemBox 23 <SettingItemBox
21 :name="`装饰颜色-${index + 1}`" 24 :name="`装饰颜色-${index + 1}`"
@@ -30,14 +33,19 @@ @@ -30,14 +33,19 @@
30 ></n-color-picker> 33 ></n-color-picker>
31 </SettingItem> 34 </SettingItem>
32 <SettingItem> 35 <SettingItem>
33 - <n-button  
34 - size="small"  
35 - @click="optionData.attribute.linearColors[index] = option.attribute.linearColors[index]"  
36 - > 36 + <n-button size="small" @click="optionData.attribute.linearColors[index] = option.attribute.linearColors[index]">
37 恢复默认 37 恢复默认
38 </n-button> 38 </n-button>
39 </SettingItem> 39 </SettingItem>
40 </SettingItemBox> 40 </SettingItemBox>
  41 + <SettingItemBox :name="`装饰颜色8`">
  42 + <SettingItem name="颜色">
  43 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.lineColor"></n-color-picker>
  44 + </SettingItem>
  45 + <SettingItem>
  46 + <n-button size="small" @click="optionData.attribute.lineColor = '#2AFFFF'"> 恢复默认 </n-button>
  47 + </SettingItem>
  48 + </SettingItemBox>
41 </CollapseItem> 49 </CollapseItem>
42 </template> 50 </template>
43 51
@@ -46,7 +54,6 @@ import { PropType } from 'vue' @@ -46,7 +54,6 @@ import { PropType } from 'vue'
46 import { option } from './config' 54 import { option } from './config'
47 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' 55 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
48 56
49 -  
50 defineProps({ 57 defineProps({
51 optionData: { 58 optionData: {
52 type: Object as PropType<typeof option>, 59 type: Object as PropType<typeof option>,
@@ -26,11 +26,7 @@ @@ -26,11 +26,7 @@
26 opacity="1" 26 opacity="1"
27 :d="`M0,${h} L${w},${h} L${w},0 L0,0 L0,${h} Z`" 27 :d="`M0,${h} L${w},${h} L${w},0 L0,0 L0,${h} Z`"
28 /> 28 />
29 - <g  
30 - opacity="1"  
31 - :transform="`translate(34 ${(h/2)-26/2  
32 - }) rotate(0 46 13)`"  
33 - > 29 + <g opacity="1" :transform="`translate(34 ${h / 2 - 26 / 2}) rotate(0 46 13)`">
34 <text> 30 <text>
35 <tspan 31 <tspan
36 :x="attribute.fontPos.x" 32 :x="attribute.fontPos.x"
@@ -49,15 +45,12 @@ @@ -49,15 +45,12 @@
49 <path 45 <path
50 id="矩形 21" 46 id="矩形 21"
51 fill-rule="evenodd" 47 fill-rule="evenodd"
52 - style="fill: #2affff" 48 + :style="{ fill: attribute.lineColor }"
53 transform="translate(0 0) rotate(0 0.5 15)" 49 transform="translate(0 0) rotate(0 0.5 15)"
54 opacity="1" 50 opacity="1"
55 - :d="`M0,${h}L1,${h }L1,0L0,0L0,${h}Z`" 51 + :d="`M0,${h}L1,${h}L1,0L0,0L0,${h}Z`"
56 /> 52 />
57 - <g  
58 - opacity="1"  
59 - :transform="`translate(14 ${(h/2)-8/2}) rotate(0 6.5 7)`"  
60 - > 53 + <g opacity="1" :transform="`translate(14 ${h / 2 - 8 / 2}) rotate(0 6.5 7)`">
61 <path 54 <path
62 id="矩形 22" 55 id="矩形 22"
63 fill-rule="evenodd" 56 fill-rule="evenodd"
@@ -83,7 +76,7 @@ @@ -83,7 +76,7 @@
83 :d="`M6,0L0,7L5,7L11,0L6,0Z `" 76 :d="`M6,0L0,7L5,7L11,0L6,0Z `"
84 /> 77 />
85 </g> 78 </g>
86 - <g opacity="1" :transform="`translate(396 ${(h/2)-2/2}) rotate(0 46.5 13.5)`"> 79 + <g opacity="1" :transform="`translate(396 ${h / 2 - 2 / 2}) rotate(0 46.5 13.5)`">
87 <path 80 <path
88 id="并集" 81 id="并集"
89 fill-rule="evenodd" 82 fill-rule="evenodd"
@@ -108,11 +101,6 @@ const props = defineProps({ @@ -108,11 +101,6 @@ const props = defineProps({
108 } 101 }
109 }) 102 })
110 103
111 -//修改默认宽高  
112 -props.chartConfig.attr.w=550  
113 -props.chartConfig.attr.h=60  
114 -  
115 -  
116 const { dataset, attribute } = toRefs(props.chartConfig.option) 104 const { dataset, attribute } = toRefs(props.chartConfig.option)
117 105
118 const { w, h } = toRefs(props.chartConfig.attr) 106 const { w, h } = toRefs(props.chartConfig.attr)
@@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public' @@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public'
2 import { CreateComponentType } from '@/packages/index.d' 2 import { CreateComponentType } from '@/packages/index.d'
3 import { Title2Config } from './index' 3 import { Title2Config } from './index'
4 import cloneDeep from 'lodash/cloneDeep' 4 import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
5 6
6 export const option = { 7 export const option = {
7 dataset: '我是标题', 8 dataset: '我是标题',
@@ -18,6 +19,7 @@ export const option = { @@ -18,6 +19,7 @@ export const option = {
18 19
19 export default class Config extends PublicConfigClass implements CreateComponentType { 20 export default class Config extends PublicConfigClass implements CreateComponentType {
20 public key = Title2Config.key 21 public key = Title2Config.key
  22 + public attr = { ...chartInitConfig, zIndex: 1, w: 550, h: 60 }
21 public chartConfig = cloneDeep(Title2Config) 23 public chartConfig = cloneDeep(Title2Config)
22 public option = cloneDeep(option) 24 public option = cloneDeep(option)
23 } 25 }
@@ -7,15 +7,18 @@ @@ -7,15 +7,18 @@
7 <SettingItem name="大小"> 7 <SettingItem name="大小">
8 <n-input-number v-model:value="optionData.attribute.fontSize" /> 8 <n-input-number v-model:value="optionData.attribute.fontSize" />
9 </SettingItem> 9 </SettingItem>
10 - <SettingItem name="颜色">  
11 - <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.fontColor"></n-color-picker>  
12 - </SettingItem>  
13 <SettingItem name="x轴位置"> 10 <SettingItem name="x轴位置">
14 <n-input-number v-model:value="optionData.attribute.fontPos.x" /> 11 <n-input-number v-model:value="optionData.attribute.fontPos.x" />
15 </SettingItem> 12 </SettingItem>
16 <SettingItem name="y轴位置"> 13 <SettingItem name="y轴位置">
17 <n-input-number v-model:value="optionData.attribute.fontPos.y" /> 14 <n-input-number v-model:value="optionData.attribute.fontPos.y" />
18 </SettingItem> 15 </SettingItem>
  16 + <SettingItem name="颜色">
  17 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.fontColor"></n-color-picker>
  18 + </SettingItem>
  19 + <SettingItem>
  20 + <n-button size="small" @click="optionData.attribute.fontColor = '#2AFFFF'"> 恢复默认 </n-button>
  21 + </SettingItem>
19 </SettingItemBox> 22 </SettingItemBox>
20 <SettingItemBox 23 <SettingItemBox
21 :name="`装饰颜色-${index + 1}`" 24 :name="`装饰颜色-${index + 1}`"
@@ -30,10 +33,7 @@ @@ -30,10 +33,7 @@
30 ></n-color-picker> 33 ></n-color-picker>
31 </SettingItem> 34 </SettingItem>
32 <SettingItem> 35 <SettingItem>
33 - <n-button  
34 - size="small"  
35 - @click="optionData.attribute.linearColors[index] = option.attribute.linearColors[index]"  
36 - > 36 + <n-button size="small" @click="optionData.attribute.linearColors[index] = option.attribute.linearColors[index]">
37 恢复默认 37 恢复默认
38 </n-button> 38 </n-button>
39 </SettingItem> 39 </SettingItem>
@@ -46,7 +46,6 @@ import { PropType } from 'vue' @@ -46,7 +46,6 @@ import { PropType } from 'vue'
46 import { option } from './config' 46 import { option } from './config'
47 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' 47 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
48 48
49 -  
50 defineProps({ 49 defineProps({
51 optionData: { 50 optionData: {
52 type: Object as PropType<typeof option>, 51 type: Object as PropType<typeof option>,
@@ -76,9 +76,7 @@ const props = defineProps({ @@ -76,9 +76,7 @@ const props = defineProps({
76 }) 76 })
77 77
78 const { dataset, attribute } = toRefs(props.chartConfig.option) 78 const { dataset, attribute } = toRefs(props.chartConfig.option)
79 -//修改默认宽高  
80 -props.chartConfig.attr.w=550  
81 -props.chartConfig.attr.h=60 79 +
82 const { w, h } = toRefs(props.chartConfig.attr) 80 const { w, h } = toRefs(props.chartConfig.attr)
83 </script> 81 </script>
84 82
@@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public' @@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public'
2 import { CreateComponentType } from '@/packages/index.d' 2 import { CreateComponentType } from '@/packages/index.d'
3 import { Title3Config } from './index' 3 import { Title3Config } from './index'
4 import cloneDeep from 'lodash/cloneDeep' 4 import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
5 6
6 export const option = { 7 export const option = {
7 dataset: '我是标题', 8 dataset: '我是标题',
@@ -31,6 +32,7 @@ export const option = { @@ -31,6 +32,7 @@ export const option = {
31 32
32 export default class Config extends PublicConfigClass implements CreateComponentType { 33 export default class Config extends PublicConfigClass implements CreateComponentType {
33 public key = Title3Config.key 34 public key = Title3Config.key
  35 + public attr = { ...chartInitConfig, zIndex: 1, w: 550, h: 60 }
34 public chartConfig = cloneDeep(Title3Config) 36 public chartConfig = cloneDeep(Title3Config)
35 public option = cloneDeep(option) 37 public option = cloneDeep(option)
36 } 38 }
@@ -7,15 +7,18 @@ @@ -7,15 +7,18 @@
7 <SettingItem name="大小"> 7 <SettingItem name="大小">
8 <n-input-number v-model:value="optionData.attribute.fontSize" /> 8 <n-input-number v-model:value="optionData.attribute.fontSize" />
9 </SettingItem> 9 </SettingItem>
10 - <SettingItem name="颜色">  
11 - <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.fontColor"></n-color-picker>  
12 - </SettingItem>  
13 <SettingItem name="x轴位置"> 10 <SettingItem name="x轴位置">
14 <n-input-number v-model:value="optionData.attribute.fontPos.x" /> 11 <n-input-number v-model:value="optionData.attribute.fontPos.x" />
15 </SettingItem> 12 </SettingItem>
16 <SettingItem name="y轴位置"> 13 <SettingItem name="y轴位置">
17 <n-input-number v-model:value="optionData.attribute.fontPos.y" /> 14 <n-input-number v-model:value="optionData.attribute.fontPos.y" />
18 </SettingItem> 15 </SettingItem>
  16 + <SettingItem name="颜色">
  17 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.fontColor"></n-color-picker>
  18 + </SettingItem>
  19 + <SettingItem name="颜色">
  20 + <n-button size="small" @click="optionData.attribute.fontColor = '#2AFFFF'"> 恢复默认 </n-button>
  21 + </SettingItem>
19 </SettingItemBox> 22 </SettingItemBox>
20 <SettingItemBox 23 <SettingItemBox
21 :name="`装饰颜色-${index + 1}`" 24 :name="`装饰颜色-${index + 1}`"
@@ -30,10 +33,7 @@ @@ -30,10 +33,7 @@
30 ></n-color-picker> 33 ></n-color-picker>
31 </SettingItem> 34 </SettingItem>
32 <SettingItem> 35 <SettingItem>
33 - <n-button  
34 - size="small"  
35 - @click="optionData.attribute.linearColors[index] = option.attribute.linearColors[index]"  
36 - > 36 + <n-button size="small" @click="optionData.attribute.linearColors[index] = option.attribute.linearColors[index]">
37 恢复默认 37 恢复默认
38 </n-button> 38 </n-button>
39 </SettingItem> 39 </SettingItem>
@@ -46,7 +46,6 @@ import { PropType } from 'vue' @@ -46,7 +46,6 @@ import { PropType } from 'vue'
46 import { option } from './config' 46 import { option } from './config'
47 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' 47 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
48 48
49 -  
50 defineProps({ 49 defineProps({
51 optionData: { 50 optionData: {
52 type: Object as PropType<typeof option>, 51 type: Object as PropType<typeof option>,
@@ -117,9 +117,6 @@ const { dataset, attribute } = toRefs(props.chartConfig.option) @@ -117,9 +117,6 @@ const { dataset, attribute } = toRefs(props.chartConfig.option)
117 117
118 const { w, h } = toRefs(props.chartConfig.attr) 118 const { w, h } = toRefs(props.chartConfig.attr)
119 119
120 -//修改默认宽高  
121 -props.chartConfig.attr.w=550  
122 -props.chartConfig.attr.h=60  
123 </script> 120 </script>
124 121
125 <style lang="scss" scoped> 122 <style lang="scss" scoped>
@@ -18,9 +18,17 @@ import { @@ -18,9 +18,17 @@ import {
18 import { chartInitConfig } from '@/settings/designSetting' 18 import { chartInitConfig } from '@/settings/designSetting'
19 import cloneDeep from 'lodash/cloneDeep' 19 import cloneDeep from 'lodash/cloneDeep'
20 20
  21 +/**
  22 + * 这里更新版本有冲突
  23 + * ft 修改在公共接口下拉框里默认选择公共接口
  24 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  25 + * 源代码 requestDataType: RequestDataTypeEnum.AJAX,
  26 + * 修改后的代码 requestDataType: RequestDataTypeEnum.Pond,
  27 + * 修改后代码在//ft之间
  28 + */
21 // 请求基础属性 29 // 请求基础属性
22 export const requestConfig: RequestConfigType = { 30 export const requestConfig: RequestConfigType = {
23 - requestDataType: RequestDataTypeEnum.STATIC, 31 + requestDataType: RequestDataTypeEnum.Pond,
24 requestHttpType: RequestHttpEnum.GET, 32 requestHttpType: RequestHttpEnum.GET,
25 requestUrl: '', 33 requestUrl: '',
26 requestInterval: undefined, 34 requestInterval: undefined,
@@ -41,6 +49,7 @@ export const requestConfig: RequestConfigType = { @@ -41,6 +49,7 @@ export const requestConfig: RequestConfigType = {
41 Params: {} 49 Params: {}
42 } 50 }
43 } 51 }
  52 +//ft之间
44 53
45 // 单实例类 54 // 单实例类
46 export class PublicConfigClass implements PublicConfigType { 55 export class PublicConfigClass implements PublicConfigType {
@@ -33,7 +33,7 @@ export const useSocketStore = defineStore({ @@ -33,7 +33,7 @@ export const useSocketStore = defineStore({
33 const { keys } = Params 33 const { keys } = Params
34 return { 34 return {
35 componentId: id, 35 componentId: id,
36 - keys: keys.split(KEYS_SEPARATOR) 36 + keys: keys as unknown as string[]
37 } 37 }
38 }) 38 })
39 }, 39 },
@@ -149,8 +149,8 @@ export const useSocketStore = defineStore({ @@ -149,8 +149,8 @@ export const useSocketStore = defineStore({
149 const { requestContentType, requestParams } = request 149 const { requestContentType, requestParams } = request
150 if ((requestContentType as RequestContentTypeEnum) === RequestContentTypeEnum.WEB_SOCKET) { 150 if ((requestContentType as RequestContentTypeEnum) === RequestContentTypeEnum.WEB_SOCKET) {
151 const { Params } = requestParams 151 const { Params } = requestParams
152 - const { entityId = '', keys = '' } = Params  
153 - return this.updateConnectionPool(entityId, keys.split(KEYS_SEPARATOR), componentId) 152 + const { entityId = '', keys = [] } = Params
  153 + return this.updateConnectionPool(entityId, keys as string[], componentId)
154 } 154 }
155 }, 155 },
156 156
@@ -197,8 +197,8 @@ export const useSocketStore = defineStore({ @@ -197,8 +197,8 @@ export const useSocketStore = defineStore({
197 getComponentValueByKeys(targetComponent: CreateComponentType, value: SocketReceiveMessageType) { 197 getComponentValueByKeys(targetComponent: CreateComponentType, value: SocketReceiveMessageType) {
198 const { request: { requestParams } } = targetComponent 198 const { request: { requestParams } } = targetComponent
199 const { Params } = requestParams 199 const { Params } = requestParams
200 - const { keys = '' } = Params  
201 - const targetComponentBindKeys = keys.split(KEYS_SEPARATOR) 200 + const { keys = [] } = Params
  201 + const targetComponentBindKeys = keys as unknown as string[]
202 202
203 const _value = cloneDeep(value) || { data: {}, latestValues: {} } 203 const _value = cloneDeep(value) || { data: {}, latestValues: {} }
204 _value.data = targetComponentBindKeys.reduce((prev, next) => { 204 _value.data = targetComponentBindKeys.reduce((prev, next) => {
@@ -238,7 +238,6 @@ export const useSocketStore = defineStore({ @@ -238,7 +238,6 @@ export const useSocketStore = defineStore({
238 const { subscriptionId, data } = value 238 const { subscriptionId, data } = value
239 const keys = Object.keys(data) 239 const keys = Object.keys(data)
240 const componentIds = this.getNeedUpdateComponentsIdBySubscribeId(subscriptionId, keys) 240 const componentIds = this.getNeedUpdateComponentsIdBySubscribeId(subscriptionId, keys)
241 - console.log(componentIds)  
242 componentIds?.forEach((targetComponentId) => { 241 componentIds?.forEach((targetComponentId) => {
243 this.updateComponentById(targetComponentId as string, value) 242 this.updateComponentById(targetComponentId as string, value)
244 }) 243 })
@@ -3,8 +3,8 @@ import type { ErrorMessageMode } from '/#/external/axios'; @@ -3,8 +3,8 @@ 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';  
7 -import { getAuthCache, getJwtToken, getRefreshToken, setAuthCache } from '@/utils/external/auth'; 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, getUserInfo, setAuthCache } from '@/utils/external/auth';
8 import { 8 import {
9 LoginParams, 9 LoginParams,
10 LoginResultModel, 10 LoginResultModel,
@@ -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
@@ -41,12 +43,14 @@ export const useUserStore = defineStore({ @@ -41,12 +43,14 @@ export const useUserStore = defineStore({
41 enterPriseInfo: storage.get('enterPriseInfo') || null, 43 enterPriseInfo: storage.get('enterPriseInfo') || null,
42 44
43 // user info 45 // user info
44 - userInfo: null, 46 + userInfo: getUserInfo() || null,
45 userUpdateInfo: null, 47 userUpdateInfo: null,
46 // token 48 // token
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, USER_INFO_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 +import { UserInfo } from '/#/external/store';
5 6
6 const { permissionCacheType } = projectSetting; 7 const { permissionCacheType } = projectSetting;
7 const isLocal = permissionCacheType === CacheTypeEnum.LOCAL; 8 const isLocal = permissionCacheType === CacheTypeEnum.LOCAL;
@@ -20,9 +21,21 @@ export function clearAuthCache(immediate = true) { @@ -20,9 +21,21 @@ export function clearAuthCache(immediate = true) {
20 const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession; 21 const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession;
21 return fn(immediate); 22 return fn(immediate);
22 } 23 }
23 -export function getJwtToken() { 24 +export function getJwtToken(): string {
24 return getAuthCache(JWT_TOKEN_KEY); 25 return getAuthCache(JWT_TOKEN_KEY);
25 } 26 }
26 -export function getRefreshToken() { 27 +export function getRefreshToken(): string {
27 return getAuthCache(REFRESH_TOKEN_KEY); 28 return getAuthCache(REFRESH_TOKEN_KEY);
28 } 29 }
  30 +
  31 +export function getShareJwtToken(): string {
  32 + return getAuthCache(SHARE_JWT_TOKEN_KEY);
  33 +}
  34 +
  35 +export function getShareRefreshToken(): string {
  36 + return getAuthCache(SHARE_REFRESH_TOKEN_KEY);
  37 +}
  38 +
  39 +export function getUserInfo(): UserInfo {
  40 + return getAuthCache(USER_INFO_KEY)
  41 +}
@@ -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 +import { excludeParseEventKeyList, excludeParseEventValueList } from "@/enums/eventEnum"
  2 +
  3 +const tryRunFunction = (v: string) => {
  4 + try {
  5 + return eval(`(function(){return ${v}})()`)
  6 + } catch (error) {
  7 + return v
  8 + }
  9 +}
  10 +
  11 +export const JSONParse = (data: string) => {
  12 + return JSON.parse(data, (k, v) => {
  13 + // 过滤函数字符串
  14 + if (excludeParseEventKeyList.includes(k)) return v
  15 + // 过滤函数值表达式
  16 + if (typeof v === 'string') {
  17 + const someValue = excludeParseEventValueList.some(excludeValue => v.indexOf(excludeValue) > -1)
  18 + if (someValue) return v
  19 + }
  20 + // 还原函数值
  21 + if (typeof v === 'string' && v.indexOf && (v.indexOf('function') > -1 || v.indexOf('=>') > -1)) {
  22 + return tryRunFunction(v)
  23 + } else if (typeof v === 'string' && v.indexOf && v.indexOf('return ') > -1) {
  24 + const baseLeftIndex = v.indexOf('(')
  25 + if (baseLeftIndex > -1) {
  26 + const newFn = `function ${v.substring(baseLeftIndex)}`
  27 + return tryRunFunction(newFn)
  28 + }
  29 + }
  30 + return v
  31 + })
  32 +}
@@ -12,6 +12,9 @@ import { RequestHttpIntervalEnum, RequestParamsObjType } from '@/enums/httpEnum' @@ -12,6 +12,9 @@ import { RequestHttpIntervalEnum, RequestParamsObjType } from '@/enums/httpEnum'
12 import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d' 12 import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
13 import { excludeParseEventKeyList, excludeParseEventValueList } from '@/enums/eventEnum' 13 import { excludeParseEventKeyList, excludeParseEventValueList } from '@/enums/eventEnum'
14 14
  15 +/// THINGS_KIT 替换JSONParse解析
  16 +export { JSONParse } from './external/utils'
  17 +
15 /** 18 /**
16 * * 判断是否是开发环境 19 * * 判断是否是开发环境
17 * @return { Boolean } 20 * @return { Boolean }
@@ -127,11 +130,11 @@ export const fileToUrl = (file: File): string => { @@ -127,11 +130,11 @@ export const fileToUrl = (file: File): string => {
127 * * file转base64 130 * * file转base64
128 */ 131 */
129 export const fileTobase64 = (file: File, callback: Function) => { 132 export const fileTobase64 = (file: File, callback: Function) => {
130 - let reader = new FileReader() 133 + const reader = new FileReader()
131 reader.readAsDataURL(file) 134 reader.readAsDataURL(file)
132 reader.onload = function (e: ProgressEvent<FileReader>) { 135 reader.onload = function (e: ProgressEvent<FileReader>) {
133 if (e.target) { 136 if (e.target) {
134 - let base64 = e.target.result 137 + const base64 = e.target.result
135 callback(base64) 138 callback(base64)
136 } 139 }
137 } 140 }
@@ -318,7 +321,8 @@ export const JSONStringify = <T>(data: T) => { @@ -318,7 +321,8 @@ export const JSONStringify = <T>(data: T) => {
318 * * JSON反序列化,支持函数和 undefined 321 * * JSON反序列化,支持函数和 undefined
319 * @param data 322 * @param data
320 */ 323 */
321 -export const JSONParse = (data: string) => { 324 +/// THINGS_KIT 重命名 JSONParse 为 JSONParseOriginal
  325 +export const JSONParseOriginal = (data: string) => {
322 return JSON.parse(data, (k, v) => { 326 return JSON.parse(data, (k, v) => {
323 // 过滤函数字符串 327 // 过滤函数字符串
324 if (excludeParseEventKeyList.includes(k)) return v 328 if (excludeParseEventKeyList.includes(k)) return v
@@ -347,4 +351,4 @@ export const JSONParse = (data: string) => { @@ -347,4 +351,4 @@ export const JSONParse = (data: string) => {
347 */ 351 */
348 export const setTitle = (title?: string) => { 352 export const setTitle = (title?: string) => {
349 title && (document.title = title) 353 title && (document.title = title)
350 -}  
  354 +}
@@ -22,7 +22,14 @@ const requestModal = ref<InstanceType<typeof RequestModal>>() @@ -22,7 +22,14 @@ const requestModal = ref<InstanceType<typeof RequestModal>>()
22 const designStore = useDesignStore() 22 const designStore = useDesignStore()
23 23
24 24
25 -const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.AJAX) 25 +/**
  26 + * ft 修改在公共接口下拉框里默认选择公共接口
  27 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  28 + * 源代码 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.AJAX)
  29 + * 修改后的代码 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.Pond)
  30 + * 修改后代码在//ft之间
  31 + */
  32 +const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.Pond)
26 33
27 const getApiRequestType: SelectOption[] = [ 34 const getApiRequestType: SelectOption[] = [
28 { label: '自定义请求', value: RequestDataTypeEnum.AJAX }, 35 { label: '自定义请求', value: RequestDataTypeEnum.AJAX },
@@ -40,7 +47,10 @@ const { fetchTargetData, } = useFetchTargetData() @@ -40,7 +47,10 @@ const { fetchTargetData, } = useFetchTargetData()
40 47
41 // 发送请求 48 // 发送请求
42 const sendHandle = async () => { 49 const sendHandle = async () => {
43 - if (!targetData.value?.request) return 50 + if (!targetData.value?.request || !targetData.value.request.requestUrl) {
  51 + window['$message'].warning('请先配置请求')
  52 + return
  53 + }
44 loading.value = true 54 loading.value = true
45 try { 55 try {
46 const res = await fetchTargetData() 56 const res = await fetchTargetData()
@@ -4,6 +4,7 @@ import { FormItemInst, NDatePicker, NForm, NFormItem, NInput, NSelect, NTreeSele @@ -4,6 +4,7 @@ import { FormItemInst, NDatePicker, NForm, NFormItem, NInput, NSelect, NTreeSele
4 import { computed, nextTick, ref, unref, watch } from 'vue'; 4 import { computed, nextTick, ref, unref, watch } from 'vue';
5 import { ComponentType, useDynamicPublicForm } from './useDynamicPublicForm'; 5 import { ComponentType, useDynamicPublicForm } from './useDynamicPublicForm';
6 import { Help } from '@vicons/ionicons5' 6 import { Help } from '@vicons/ionicons5'
  7 +import { SelectTimeAggregation } from '../SelectTImeAggregation';
7 8
8 const props = defineProps<{ 9 const props = defineProps<{
9 paramsItemList: ParamsItemType[] 10 paramsItemList: ParamsItemType[]
@@ -13,7 +14,8 @@ const componentMap: { [key in ComponentType]?: any } = { @@ -13,7 +14,8 @@ const componentMap: { [key in ComponentType]?: any } = {
13 [ComponentType.SELECT_TREE]: NTreeSelect, 14 [ComponentType.SELECT_TREE]: NTreeSelect,
14 [ComponentType.SELECT]: NSelect, 15 [ComponentType.SELECT]: NSelect,
15 [ComponentType.INPUT]: NInput, 16 [ComponentType.INPUT]: NInput,
16 - [ComponentType.DATE_PICKER]: NDatePicker 17 + [ComponentType.DATE_PICKER]: NDatePicker,
  18 + [ComponentType.SELECT_TIME_AGGREGATION]: SelectTimeAggregation
17 } 19 }
18 20
19 const getParamsItemList = computed(() => { 21 const getParamsItemList = computed(() => {
@@ -39,12 +41,16 @@ const setConfigurationData = async (params: Recordable) => { @@ -39,12 +41,16 @@ const setConfigurationData = async (params: Recordable) => {
39 setDynamicFormValue(params) 41 setDynamicFormValue(params)
40 } 42 }
41 43
  44 +const recreate = ref(false)
  45 +
42 watch( 46 watch(
43 () => props.paramsItemList, 47 () => props.paramsItemList,
44 (newValue) => { 48 (newValue) => {
45 if (newValue) { 49 if (newValue) {
  50 + recreate.value = true
46 clearParams() 51 clearParams()
47 createForm() 52 createForm()
  53 + recreate.value = false
48 } 54 }
49 } 55 }
50 ) 56 )
@@ -59,8 +65,8 @@ defineExpose({ @@ -59,8 +65,8 @@ defineExpose({
59 65
60 <template> 66 <template>
61 <NForm> 67 <NForm>
62 - <template v-for="item in getDynamicFormSchemas" :key="item.key">  
63 - <NFormItem ref="dynamicFormItemEl" :required="item.required" :rule="item.rules"> 68 + <template v-for="item in getDynamicFormSchemas" :key="item.uuid">
  69 + <NFormItem v-if="!recreate" ref="dynamicFormItemEl" :required="item.required" :rule="item.rules">
64 <template #label> 70 <template #label>
65 <div class="label-container"> 71 <div class="label-container">
66 <span>{{ item.name }}</span> 72 <span>{{ item.name }}</span>
  1 +enum TimeUnitEnum {
  2 + SECOND = 'SECOND',
  3 + MINUTE = 'MINUTE',
  4 + HOUR = 'HOUR',
  5 + DAY = 'DAY',
  6 +}
  7 +
  8 +const unitMapping = {
  9 + [TimeUnitEnum.SECOND]: '秒',
  10 + [TimeUnitEnum.MINUTE]: '分',
  11 + [TimeUnitEnum.HOUR]: '小时',
  12 + [TimeUnitEnum.DAY]: '天',
  13 +}
  14 +
  15 +const unitConversion = {
  16 + [TimeUnitEnum.SECOND]: 1 * 1000,
  17 + [TimeUnitEnum.MINUTE]: 1 * 60 * 1000,
  18 + [TimeUnitEnum.HOUR]: 1 * 60 * 60 * 1000,
  19 + [TimeUnitEnum.DAY]: 1 * 60 * 60 * 24 * 1000,
  20 +}
  21 +
  22 +export const defaultIntervalOptions = [
  23 + {
  24 + id: 1,
  25 + unit: TimeUnitEnum.SECOND,
  26 + linkage: [
  27 + { id: 1, unit: TimeUnitEnum.SECOND }
  28 + ]
  29 + },
  30 + {
  31 + id: 5,
  32 + unit: TimeUnitEnum.SECOND,
  33 + linkage: [
  34 + { id: 1, unit: TimeUnitEnum.SECOND }
  35 + ]
  36 + },
  37 + {
  38 + id: 10,
  39 + unit: TimeUnitEnum.SECOND,
  40 + linkage: [
  41 + { id: 1, unit: TimeUnitEnum.SECOND }
  42 + ]
  43 + },
  44 + {
  45 + id: 15,
  46 + unit: TimeUnitEnum.SECOND,
  47 + linkage: [
  48 + { id: 1, unit: TimeUnitEnum.SECOND }
  49 + ]
  50 + },
  51 + {
  52 + id: 30,
  53 + unit: TimeUnitEnum.SECOND,
  54 + linkage: [
  55 + { id: 1, unit: TimeUnitEnum.SECOND }
  56 + ]
  57 + },
  58 + {
  59 + id: 1,
  60 + unit: TimeUnitEnum.MINUTE,
  61 + linkage: [
  62 + { id: 1, unit: TimeUnitEnum.SECOND },
  63 + { id: 5, unit: TimeUnitEnum.SECOND },
  64 + ]
  65 + },
  66 + {
  67 + id: 2,
  68 + unit: TimeUnitEnum.MINUTE,
  69 + linkage: [
  70 + { id: 1, unit: TimeUnitEnum.SECOND },
  71 + { id: 5, unit: TimeUnitEnum.SECOND },
  72 + { id: 10, unit: TimeUnitEnum.SECOND },
  73 + { id: 15, unit: TimeUnitEnum.SECOND },
  74 + ]
  75 + },
  76 + {
  77 + id: 5,
  78 + unit: TimeUnitEnum.MINUTE,
  79 + linkage: [
  80 + { id: 1, unit: TimeUnitEnum.SECOND },
  81 + { id: 5, unit: TimeUnitEnum.SECOND },
  82 + { id: 10, unit: TimeUnitEnum.SECOND },
  83 + { id: 15, unit: TimeUnitEnum.SECOND },
  84 + { id: 30, unit: TimeUnitEnum.SECOND },
  85 + ]
  86 + },
  87 + {
  88 + id: 10,
  89 + unit: TimeUnitEnum.MINUTE,
  90 + linkage: [
  91 + { id: 5, unit: TimeUnitEnum.SECOND },
  92 + { id: 10, unit: TimeUnitEnum.SECOND },
  93 + { id: 15, unit: TimeUnitEnum.SECOND },
  94 + { id: 30, unit: TimeUnitEnum.SECOND },
  95 + { id: 1, unit: TimeUnitEnum.MINUTE },
  96 + ]
  97 + },
  98 + {
  99 + id: 15,
  100 + unit: TimeUnitEnum.MINUTE,
  101 + linkage: [
  102 + { id: 5, unit: TimeUnitEnum.SECOND },
  103 + { id: 10, unit: TimeUnitEnum.SECOND },
  104 + { id: 15, unit: TimeUnitEnum.SECOND },
  105 + { id: 30, unit: TimeUnitEnum.SECOND },
  106 + { id: 1, unit: TimeUnitEnum.MINUTE },
  107 + { id: 2, unit: TimeUnitEnum.MINUTE },
  108 + ]
  109 + },
  110 + {
  111 + id: 30,
  112 + unit: TimeUnitEnum.MINUTE,
  113 + linkage: [
  114 + { id: 5, unit: TimeUnitEnum.SECOND },
  115 + { id: 10, unit: TimeUnitEnum.SECOND },
  116 + { id: 15, unit: TimeUnitEnum.SECOND },
  117 + { id: 30, unit: TimeUnitEnum.SECOND },
  118 + { id: 1, unit: TimeUnitEnum.MINUTE },
  119 + { id: 2, unit: TimeUnitEnum.MINUTE },
  120 + ]
  121 + },
  122 + {
  123 + id: 1,
  124 + unit: TimeUnitEnum.HOUR,
  125 + linkage: [
  126 + { id: 10, unit: TimeUnitEnum.SECOND },
  127 + { id: 15, unit: TimeUnitEnum.SECOND },
  128 + { id: 30, unit: TimeUnitEnum.SECOND },
  129 + { id: 1, unit: TimeUnitEnum.MINUTE },
  130 + { id: 2, unit: TimeUnitEnum.MINUTE },
  131 + { id: 5, unit: TimeUnitEnum.MINUTE },
  132 + ]
  133 + },
  134 + {
  135 + id: 2,
  136 + unit: TimeUnitEnum.HOUR,
  137 + linkage: [
  138 + { id: 15, unit: TimeUnitEnum.SECOND },
  139 + { id: 30, unit: TimeUnitEnum.SECOND },
  140 + { id: 1, unit: TimeUnitEnum.MINUTE },
  141 + { id: 2, unit: TimeUnitEnum.MINUTE },
  142 + { id: 5, unit: TimeUnitEnum.MINUTE },
  143 + { id: 10, unit: TimeUnitEnum.MINUTE },
  144 + { id: 15, unit: TimeUnitEnum.MINUTE },
  145 + ]
  146 + },
  147 + {
  148 + id: 5,
  149 + unit: TimeUnitEnum.HOUR,
  150 + linkage: [
  151 + { id: 1, unit: TimeUnitEnum.MINUTE },
  152 + { id: 2, unit: TimeUnitEnum.MINUTE },
  153 + { id: 5, unit: TimeUnitEnum.MINUTE },
  154 + { id: 10, unit: TimeUnitEnum.MINUTE },
  155 + { id: 15, unit: TimeUnitEnum.MINUTE },
  156 + { id: 30, unit: TimeUnitEnum.MINUTE },
  157 + ]
  158 + },
  159 + {
  160 + id: 10,
  161 + unit: TimeUnitEnum.HOUR,
  162 + linkage: [
  163 + { id: 2, unit: TimeUnitEnum.MINUTE },
  164 + { id: 5, unit: TimeUnitEnum.MINUTE },
  165 + { id: 10, unit: TimeUnitEnum.MINUTE },
  166 + { id: 15, unit: TimeUnitEnum.MINUTE },
  167 + { id: 30, unit: TimeUnitEnum.MINUTE },
  168 + { id: 1, unit: TimeUnitEnum.HOUR },
  169 + ]
  170 + },
  171 + {
  172 + id: 12,
  173 + unit: TimeUnitEnum.HOUR,
  174 + linkage: [
  175 + { id: 2, unit: TimeUnitEnum.MINUTE },
  176 + { id: 5, unit: TimeUnitEnum.MINUTE },
  177 + { id: 10, unit: TimeUnitEnum.MINUTE },
  178 + { id: 15, unit: TimeUnitEnum.MINUTE },
  179 + { id: 30, unit: TimeUnitEnum.MINUTE },
  180 + { id: 1, unit: TimeUnitEnum.HOUR },
  181 + ]
  182 + },
  183 + {
  184 + id: 1,
  185 + unit: TimeUnitEnum.DAY,
  186 + linkage: [
  187 + { id: 5, unit: TimeUnitEnum.MINUTE },
  188 + { id: 10, unit: TimeUnitEnum.MINUTE },
  189 + { id: 15, unit: TimeUnitEnum.MINUTE },
  190 + { id: 30, unit: TimeUnitEnum.MINUTE },
  191 + { id: 1, unit: TimeUnitEnum.HOUR },
  192 + { id: 2, unit: TimeUnitEnum.HOUR },
  193 + ]
  194 + },
  195 + {
  196 + id: 7,
  197 + unit: TimeUnitEnum.DAY,
  198 + linkage: [
  199 + { id: 30, unit: TimeUnitEnum.MINUTE },
  200 + { id: 1, unit: TimeUnitEnum.HOUR },
  201 + { id: 2, unit: TimeUnitEnum.HOUR },
  202 + { id: 5, unit: TimeUnitEnum.HOUR },
  203 + { id: 10, unit: TimeUnitEnum.HOUR },
  204 + { id: 12, unit: TimeUnitEnum.HOUR },
  205 + { id: 1, unit: TimeUnitEnum.DAY },
  206 + ]
  207 + },
  208 + {
  209 + id: 30,
  210 + unit: TimeUnitEnum.DAY,
  211 + linkage: [
  212 + { id: 2, unit: TimeUnitEnum.HOUR },
  213 + { id: 5, unit: TimeUnitEnum.HOUR },
  214 + { id: 10, unit: TimeUnitEnum.HOUR },
  215 + { id: 12, unit: TimeUnitEnum.HOUR },
  216 + { id: 1, unit: TimeUnitEnum.DAY },
  217 + ]
  218 + },
  219 +].map(item => {
  220 + return {
  221 + id: item.id * unitConversion[item.unit],
  222 + name: item.id + unitMapping[item.unit],
  223 + linkage: item.linkage.map(item => {
  224 + return {
  225 + id: item.id * unitConversion[item.unit],
  226 + name: item.id + unitMapping[item.unit],
  227 + }
  228 + })
  229 + }
  230 +})
  231 +
  232 +export const aggergationOptions = [
  233 + { id: 'AVG', name: '平均值' },
  234 + { id: 'MIN', name: '最小值' },
  235 + { id: 'MAX', name: '最大值' },
  236 + { id: 'SUM', name: '求和' },
  237 + { id: 'COUNT', name: '计数' },
  238 + { id: 'NONE', name: '空' },
  239 +]
@@ -6,6 +6,8 @@ import { RequestConfigType } from "@/store/modules/chartEditStore/chartEditStore @@ -6,6 +6,8 @@ import { RequestConfigType } from "@/store/modules/chartEditStore/chartEditStore
6 import { DatePickerProps, FormItemRule, InputProps, SelectProps, TreeSelectProps } from "naive-ui" 6 import { DatePickerProps, FormItemRule, InputProps, SelectProps, TreeSelectProps } from "naive-ui"
7 import { computed, onMounted, reactive, Ref, ref, unref } from "vue" 7 import { computed, onMounted, reactive, Ref, ref, unref } from "vue"
8 import { DictEnum } from '@/enums/external/dictEnum' 8 import { DictEnum } from '@/enums/external/dictEnum'
  9 +import { SelectTimeAggregationFieldEnum, SelectTimeAggregationValueTypw } from "../SelectTImeAggregation"
  10 +import { isArray } from "@/utils"
9 11
10 const GROUP_SEPARATOR = ',' 12 const GROUP_SEPARATOR = ','
11 13
@@ -15,7 +17,8 @@ export enum BuiltInVariable { @@ -15,7 +17,8 @@ export enum BuiltInVariable {
15 ORGANIZATION_ID = 'organizationId', 17 ORGANIZATION_ID = 'organizationId',
16 DEVICE_PROFILE_ID = 'deviceProfileId', 18 DEVICE_PROFILE_ID = 'deviceProfileId',
17 DATE_FIXED = 'fixed_date', 19 DATE_FIXED = 'fixed_date',
18 - DATE_RANGE = 'date_range' 20 + DATE_RANGE = 'date_range',
  21 + SELECT_TIME_AGGREGATION = 'selectTimeAggregation'
19 } 22 }
20 23
21 export enum ComponentType { 24 export enum ComponentType {
@@ -23,10 +26,12 @@ export enum ComponentType { @@ -23,10 +26,12 @@ export enum ComponentType {
23 SELECT_TREE = 'selectTree', 26 SELECT_TREE = 'selectTree',
24 DATE_PICKER = 'datePicker', 27 DATE_PICKER = 'datePicker',
25 INPUT = 'input', 28 INPUT = 'input',
  29 + SELECT_TIME_AGGREGATION = 'selectTimeAggregation'
26 } 30 }
27 31
28 32
29 export interface DynamicFormSchema { 33 export interface DynamicFormSchema {
  34 + uuid?: string
30 key: string 35 key: string
31 name?: string 36 name?: string
32 component: ComponentType, 37 component: ComponentType,
@@ -57,7 +62,9 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -57,7 +62,9 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
57 62
58 const builtInVariable = ref<BuiltInVariableRecord>() 63 const builtInVariable = ref<BuiltInVariableRecord>()
59 64
60 - const params = reactive<Recordable & { [key in BuiltInVariable]?: any }>({}) 65 + const params = reactive<Recordable & { [key in BuiltInVariable]?: any }>({
  66 + [BuiltInVariable.SELECT_TIME_AGGREGATION]: {}
  67 + })
61 68
62 const optionsSet = reactive<Recordable>({}) 69 const optionsSet = reactive<Recordable>({})
63 70
@@ -107,7 +114,8 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -107,7 +114,8 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
107 114
108 const getDeviceOption = async () => { 115 const getDeviceOption = async () => {
109 if (!validIsExist(BuiltInVariable.DEVICE_PROFILE_ID) || !validIsExist(BuiltInVariable.ORGANIZATION_ID) || !params[BuiltInVariable.ORGANIZATION_ID]) return 116 if (!validIsExist(BuiltInVariable.DEVICE_PROFILE_ID) || !validIsExist(BuiltInVariable.ORGANIZATION_ID) || !params[BuiltInVariable.ORGANIZATION_ID]) return
110 - optionsSet[BuiltInVariable.ENTITY_ID] = await getDeviceList({ [BuiltInVariable.ORGANIZATION_ID]: params[BuiltInVariable.ORGANIZATION_ID], [BuiltInVariable.DEVICE_PROFILE_ID]: params[BuiltInVariable.DEVICE_PROFILE_ID] }) 117 + const result: Recordable[] = await getDeviceList({ [BuiltInVariable.ORGANIZATION_ID]: params[BuiltInVariable.ORGANIZATION_ID], [BuiltInVariable.DEVICE_PROFILE_ID]: params[BuiltInVariable.DEVICE_PROFILE_ID] })
  118 + optionsSet[BuiltInVariable.ENTITY_ID] = result.map(item => ({ ...item, alias: item.alias || item.name }))
111 } 119 }
112 120
113 const getDeviceAttrOption = async () => { 121 const getDeviceAttrOption = async () => {
@@ -119,6 +127,7 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -119,6 +127,7 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
119 127
120 const getValue = computed(() => { 128 const getValue = computed(() => {
121 const value = { ...unref(params) } 129 const value = { ...unref(params) }
  130 +
122 if (Reflect.has(value, BuiltInVariable.DATE_FIXED)) { 131 if (Reflect.has(value, BuiltInVariable.DATE_FIXED)) {
123 const fieldMapping = unref(getParams).find(item => item.key === BuiltInVariable.DATE_FIXED) 132 const fieldMapping = unref(getParams).find(item => item.key === BuiltInVariable.DATE_FIXED)
124 Reflect.set(value, fieldMapping?.value || '', value[BuiltInVariable.DATE_FIXED]) 133 Reflect.set(value, fieldMapping?.value || '', value[BuiltInVariable.DATE_FIXED])
@@ -128,13 +137,24 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -128,13 +137,24 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
128 if (Reflect.has(value, BuiltInVariable.DATE_RANGE)) { 137 if (Reflect.has(value, BuiltInVariable.DATE_RANGE)) {
129 const fieldMapping = unref(getParams).find(item => item.key === BuiltInVariable.DATE_RANGE) 138 const fieldMapping = unref(getParams).find(item => item.key === BuiltInVariable.DATE_RANGE)
130 const [start, end] = ((fieldMapping || {}).value || '').split(GROUP_SEPARATOR) 139 const [start, end] = ((fieldMapping || {}).value || '').split(GROUP_SEPARATOR)
131 - const [startValue, endValue] = value[BuiltInVariable.DATE_RANGE] || [] 140 + const dateRangeValue = value[BuiltInVariable.DATE_RANGE]
  141 + const [startValue, endValue] = isArray(dateRangeValue) ? dateRangeValue : [null, null]
132 value[start] = startValue 142 value[start] = startValue
133 value[end] = endValue 143 value[end] = endValue
134 -  
135 Reflect.deleteProperty(value, BuiltInVariable.DATE_RANGE) 144 Reflect.deleteProperty(value, BuiltInVariable.DATE_RANGE)
136 } 145 }
137 146
  147 + if (Reflect.has(value, BuiltInVariable.SELECT_TIME_AGGREGATION)) {
  148 + const fieldMapping = unref(getParams).find(item => item.key === BuiltInVariable.DATE_RANGE)
  149 + const [start, end] = ((fieldMapping || {}).value || '').split(GROUP_SEPARATOR)
  150 + const aggregation = Reflect.get(value, BuiltInVariable.SELECT_TIME_AGGREGATION) || {}
  151 + const result = { ...aggregation, [start]: aggregation.startTs, [end]: aggregation.endTs }
  152 + Reflect.deleteProperty(result, SelectTimeAggregationFieldEnum.START_TS)
  153 + Reflect.deleteProperty(result, SelectTimeAggregationFieldEnum.END_TS)
  154 + Object.assign(value, { ...result, [start]: aggregation.startTs, [end]: aggregation.endTs })
  155 + Reflect.deleteProperty(value, BuiltInVariable.SELECT_TIME_AGGREGATION)
  156 + }
  157 +
138 return value 158 return value
139 }) 159 })
140 160
@@ -168,18 +188,25 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -168,18 +188,25 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
168 } 188 }
169 }) 189 })
170 190
  191 + /**
  192 + * ft 更改设备别名
  193 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  194 + * 源代码 labelField: 'name'
  195 + * 修改后代码 labelField: 'alias' || 'name'
  196 + */
171 const getSelectDevice = computed<SelectProps>(() => { 197 const getSelectDevice = computed<SelectProps>(() => {
172 return { 198 return {
173 ...basicPreset('name'), 199 ...basicPreset('name'),
174 value: params[BuiltInVariable.ENTITY_ID], 200 value: params[BuiltInVariable.ENTITY_ID],
175 options: unref(optionsSet[BuiltInVariable.ENTITY_ID]), 201 options: unref(optionsSet[BuiltInVariable.ENTITY_ID]),
176 - labelField: 'name', 202 + labelField: 'alias',
177 valueField: 'tbDeviceId', 203 valueField: 'tbDeviceId',
178 onUpdateValue(value) { 204 onUpdateValue(value) {
179 params[BuiltInVariable.ENTITY_ID] = value 205 params[BuiltInVariable.ENTITY_ID] = value
180 } 206 }
181 } 207 }
182 }) 208 })
  209 + //ft
183 210
184 const getSelectDeviceAttr = computed<SelectProps>(() => { 211 const getSelectDeviceAttr = computed<SelectProps>(() => {
185 return { 212 return {
@@ -188,6 +215,7 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -188,6 +215,7 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
188 options: unref(optionsSet[BuiltInVariable.KEYS]), 215 options: unref(optionsSet[BuiltInVariable.KEYS]),
189 labelField: 'name', 216 labelField: 'name',
190 valueField: 'identifier', 217 valueField: 'identifier',
  218 + multiple: true,
191 onUpdateValue(value) { 219 onUpdateValue(value) {
192 params[BuiltInVariable.KEYS] = value 220 params[BuiltInVariable.KEYS] = value
193 } 221 }
@@ -230,6 +258,15 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -230,6 +258,15 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
230 } as InputProps 258 } as InputProps
231 } 259 }
232 260
  261 + const getSelectTimeAggregation = computed(() => {
  262 + return {
  263 + value: params[BuiltInVariable.SELECT_TIME_AGGREGATION],
  264 + onChange(value: SelectTimeAggregationValueTypw) {
  265 + params[BuiltInVariable.SELECT_TIME_AGGREGATION] = value
  266 + }
  267 + }
  268 + })
  269 +
233 const builtInVariableConfiguration: { [key in BuiltInVariable]?: DynamicFormSchema } = { 270 const builtInVariableConfiguration: { [key in BuiltInVariable]?: DynamicFormSchema } = {
234 [BuiltInVariable.ORGANIZATION_ID]: { 271 [BuiltInVariable.ORGANIZATION_ID]: {
235 component: ComponentType.SELECT_TREE, 272 component: ComponentType.SELECT_TREE,
@@ -260,9 +297,31 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -260,9 +297,31 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
260 component: ComponentType.DATE_PICKER, 297 component: ComponentType.DATE_PICKER,
261 key: BuiltInVariable.DATE_FIXED, 298 key: BuiltInVariable.DATE_FIXED,
262 props: getSelectDate 299 props: getSelectDate
  300 + },
  301 + }
  302 +
  303 + const moresComponentConfiguration: { [key in BuiltInVariable]?: DynamicFormSchema } = {
  304 + [BuiltInVariable.DATE_RANGE]: {
  305 + component: ComponentType.SELECT_TIME_AGGREGATION,
  306 + key: BuiltInVariable.SELECT_TIME_AGGREGATION,
  307 + props: getSelectTimeAggregation
263 } 308 }
264 } 309 }
265 310
  311 + const timePeriodRules = (required: boolean, key: string, message: string) => {
  312 + return [{
  313 + trigger: ['blur', 'change'],
  314 + validator() {
  315 + const record = params[BuiltInVariable.SELECT_TIME_AGGREGATION]
  316 + if (required && ![record[SelectTimeAggregationFieldEnum.AGG], record[SelectTimeAggregationFieldEnum.INTERVAL], record[SelectTimeAggregationFieldEnum.END_TS], record[SelectTimeAggregationFieldEnum.START_TS]].every(Boolean)) {
  317 + validFlag.value = false
  318 + return new Error(`${message}需要填写完整`)
  319 + }
  320 + validFlag.value = true
  321 + }
  322 + }] as FormItemRule
  323 + }
  324 +
266 const validFlag = ref(true) 325 const validFlag = ref(true)
267 326
268 const createRules = (required: boolean, key: string, message: string) => { 327 const createRules = (required: boolean, key: string, message: string) => {
@@ -278,23 +337,31 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -278,23 +337,31 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
278 }] as FormItemRule 337 }] as FormItemRule
279 } 338 }
280 339
281 - const toFormSchemas = (builtInVariableKey: string, required: boolean, value: any) => { 340 + const uuid = () => Number(Math.random().toString().substring(2)).toString(32)
  341 + const toFormSchemas = (builtInVariableKey: string, required: boolean, value: any, mores: boolean) => {
282 const groupList = (builtInVariableKey || '').split(GROUP_SEPARATOR) 342 const groupList = (builtInVariableKey || '').split(GROUP_SEPARATOR)
283 return groupList.reduce((prev, next) => { 343 return groupList.reduce((prev, next) => {
284 - const result = builtInVariableConfiguration[next as BuiltInVariable]  
285 - const props = unref(result?.props) 344 + let result = builtInVariableConfiguration[next as BuiltInVariable]
  345 + let props = unref(result?.props)
286 const name = (unref(builtInVariable) || {})[next as BuiltInVariable]?.itemText 346 const name = (unref(builtInVariable) || {})[next as BuiltInVariable]?.itemText
287 let schema: DynamicFormSchema 347 let schema: DynamicFormSchema
288 - if (builtInVariableConfiguration[next as BuiltInVariable]) { 348 + if (result) {
  349 + if (mores) {
  350 + result = moresComponentConfiguration[next as BuiltInVariable]
  351 + props = unref(result?.props)
  352 + }
  353 +
289 schema = { 354 schema = {
290 ...result, 355 ...result,
  356 + // uuid: uuid(),
291 props, 357 props,
292 name, 358 name,
293 required, 359 required,
294 - rules: createRules(required, next, name || next) 360 + rules: mores ? timePeriodRules(required, next, name || next) : createRules(required, next, name || next)
295 } as DynamicFormSchema 361 } as DynamicFormSchema
296 } else { 362 } else {
297 schema = { 363 schema = {
  364 + // uuid: uuid(),
298 key: value, 365 key: value,
299 name: value, 366 name: value,
300 component: ComponentType.INPUT, 367 component: ComponentType.INPUT,
@@ -303,7 +370,6 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -303,7 +370,6 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
303 rules: createRules(required, value, value) 370 rules: createRules(required, value, value)
304 } as DynamicFormSchema 371 } as DynamicFormSchema
305 } 372 }
306 -  
307 return [...prev, schema] 373 return [...prev, schema]
308 374
309 }, [] as DynamicFormSchema[]) 375 }, [] as DynamicFormSchema[])
@@ -311,10 +377,11 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -311,10 +377,11 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
311 } 377 }
312 378
313 const getDynamicFormSchemas = computed<DynamicFormSchema[]>(() => { 379 const getDynamicFormSchemas = computed<DynamicFormSchema[]>(() => {
314 - return unref(getParams).reduce((prev: DynamicFormSchema[], { key, value, required }) => {  
315 - const schemas = toFormSchemas(key, required, value) 380 + const result = unref(getParams).reduce((prev: DynamicFormSchema[], { key, value, required, mores }) => {
  381 + const schemas = toFormSchemas(key, required, value, mores)
316 return [...prev, ...schemas] 382 return [...prev, ...schemas]
317 }, [] as DynamicFormSchema[]) 383 }, [] as DynamicFormSchema[])
  384 + return result
318 }) 385 })
319 386
320 const createForm = async () => { 387 const createForm = async () => {
@@ -324,16 +391,23 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -324,16 +391,23 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
324 getDeviceOption() 391 getDeviceOption()
325 } 392 }
326 393
327 - const setParams = (Params: Recordable = {}) => {  
328 - for (const { key, value } of unref(getParams)) {  
329 - const splitKeys = value ? value.split(GROUP_SEPARATOR) : key.split(GROUP_SEPARATOR) 394 + const setParams = (Params: Recordable = {}) => {
  395 + for (const { key, value, mores } of unref(getParams)) {
  396 + const splitKeys = value ? value.split(GROUP_SEPARATOR) : (key || '').split(GROUP_SEPARATOR)
330 if (isDateComponent(key as BuiltInVariable)) { 397 if (isDateComponent(key as BuiltInVariable)) {
331 if (key as BuiltInVariable === BuiltInVariable.DATE_FIXED) { 398 if (key as BuiltInVariable === BuiltInVariable.DATE_FIXED) {
332 params[key] = Params[splitKeys[0]] || null 399 params[key] = Params[splitKeys[0]] || null
333 continue 400 continue
334 } 401 }
335 - const value = [Params[splitKeys[0]], Params[splitKeys[1]]]  
336 - params[key] = value.every(Boolean) ? value : null 402 + if (mores) {
  403 + const { agg, interval, limit } = Params
  404 + const startTs = Params[splitKeys[0]]
  405 + const endTs = Params[splitKeys[1]]
  406 + params[BuiltInVariable.SELECT_TIME_AGGREGATION] = { agg, interval, startTs, endTs, limit }
  407 + } else {
  408 + const value = [Params[splitKeys[0]], Params[splitKeys[1]]]
  409 + params[key] = value.every(Boolean) ? value : null
  410 + }
337 continue 411 continue
338 } 412 }
339 for (const temp of splitKeys) { 413 for (const temp of splitKeys) {
@@ -345,11 +419,14 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -345,11 +419,14 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
345 const clearParams = () => { 419 const clearParams = () => {
346 Object.keys(params).forEach(key => { 420 Object.keys(params).forEach(key => {
347 Reflect.deleteProperty(params, key) 421 Reflect.deleteProperty(params, key)
  422 + // params[key] = null
348 }) 423 })
  424 + // params[BuiltInVariable.SELECT_TIME_AGGREGATION] = { startTs: null, endTs: null, limit: null, interval: null }
  425 + params[BuiltInVariable.SELECT_TIME_AGGREGATION] = {}
349 } 426 }
350 427
351 const setDynamicFormValue = (params: Recordable) => { 428 const setDynamicFormValue = (params: Recordable) => {
352 - setParams(params) 429 + setParams(params)
353 getOrgOption() 430 getOrgOption()
354 getDeviceProfileOption() 431 getDeviceProfileOption()
355 getDeviceOption() 432 getDeviceOption()
@@ -2,10 +2,10 @@ @@ -2,10 +2,10 @@
2 import { getAllPublicInterface } from '@/api/external/dynamicRequest' 2 import { getAllPublicInterface } from '@/api/external/dynamicRequest'
3 import { ParamsItemType, PublicInterfaceRecord, PublicInterfaceRequestParams, PublicInterfaceStateEnum } from '@/api/external/dynamicRequest/model'; 3 import { ParamsItemType, PublicInterfaceRecord, PublicInterfaceRequestParams, PublicInterfaceStateEnum } from '@/api/external/dynamicRequest/model';
4 import { SettingItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'; 4 import { SettingItem, SettingItemBox } from '@/components/Pages/ChartItemSetting';
5 -import { RequestContentTypeEnum, RequestContentTypeNameEnum } from '@/enums/external/httpEnum'; 5 +import { RequestContentTypeEnum, RequestContentTypeNameEnum, RequestEnum } from '@/enums/external/httpEnum';
6 import { RequestBodyEnum, RequestHttpEnum, RequestHttpIntervalEnum, RequestParams, RequestParamsTypeEnum } from '@/enums/httpEnum'; 6 import { RequestBodyEnum, RequestHttpEnum, RequestHttpIntervalEnum, RequestParams, RequestParamsTypeEnum } from '@/enums/httpEnum';
7 -import { NCard, NEmpty, NInputGroup, NInputNumber, NScrollbar, NSelect, NTabPane, NTabs, SelectOption } from 'naive-ui';  
8 -import { ref, computed, unref, nextTick } from 'vue' 7 +import { NCard, NEllipsis, NEmpty, NInputGroup, NInputNumber, NScrollbar, NSelect, NSpace, NTabPane, NTabs, SelectOption } from 'naive-ui';
  8 +import { ref, computed, unref, nextTick, h } from 'vue'
9 import { selectTimeOptions, selectTypeOptions } from '../../../index.d'; 9 import { selectTimeOptions, selectTypeOptions } from '../../../index.d';
10 import ParamsTable from '../RequestModal/ParamsTable.vue'; 10 import ParamsTable from '../RequestModal/ParamsTable.vue';
11 import BodyContent from './BodyContent.vue' 11 import BodyContent from './BodyContent.vue'
@@ -43,7 +43,14 @@ const getSelectedInterfaceParams = computed(() => { @@ -43,7 +43,14 @@ const getSelectedInterfaceParams = computed(() => {
43 43
44 const getPublicInterfaceList = async () => { 44 const getPublicInterfaceList = async () => {
45 if (unref(publicInterfaceList).length) return 45 if (unref(publicInterfaceList).length) return
46 - const result = await getAllPublicInterface({ state: PublicInterfaceStateEnum.PUBLISH }) 46 + /**
  47 + * ft 更换接口
  48 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  49 + * 源代码 const result = await getAllPublicInterface({ state: PublicInterfaceStateEnum.PUBLISH })
  50 + * 修改后代码 const result = await getAllPublicInterface()
  51 + */
  52 + const result = await getAllPublicInterface()
  53 + //ft
47 publicInterfaceList.value = result 54 publicInterfaceList.value = result
48 } 55 }
49 56
@@ -141,6 +148,30 @@ const setConfigurationData = async (request: ExtraRequestConfigType) => { @@ -141,6 +148,30 @@ const setConfigurationData = async (request: ExtraRequestConfigType) => {
141 setDynamicFormValue(request) 148 setDynamicFormValue(request)
142 } 149 }
143 150
  151 + /**
  152 + * ft 修改在公共接口下拉框里加上接口类型
  153 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  154 + * 源代码 属于新增代码,源代码无
  155 + * 修改后代码在//ft之间
  156 + */
  157 +
  158 +const getHttpType = (httpType:RequestEnum, contentType:number) => {
  159 + if(contentType===0){
  160 + if (httpType === RequestEnum[httpType]) return RequestEnum[httpType]
  161 + }
  162 + else if (contentType===2) return 'WebSocket'
  163 +}
  164 +
  165 +const renderOption = (option: SelectOption) => {
  166 + const httpType = getHttpType(option?.requestHttpType as RequestEnum, option?.requestContentType as number)
  167 + const interfaceTypeName = option?.interfaceType === 'SYSTEM' ? '系统默认' :option?.interfaceType === 'CUSTOM'? '自定义':''
  168 + return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [
  169 + h(NEllipsis, null, () => `${!httpType?'':httpType+'/'}${interfaceTypeName}`),
  170 + h(NEllipsis, null, () => option.interfaceName),
  171 + ])
  172 +}
  173 +//ft
  174 +
144 defineExpose({ 175 defineExpose({
145 getConfigurationData, 176 getConfigurationData,
146 setConfigurationData, 177 setConfigurationData,
@@ -154,10 +185,19 @@ defineExpose({ @@ -154,10 +185,19 @@ defineExpose({
154 <SettingItemBox name="公共接口" :alone="true" :item-right-style="{ gridTemplateColumns: '5fr 2fr 1fr' }"> 185 <SettingItemBox name="公共接口" :alone="true" :item-right-style="{ gridTemplateColumns: '5fr 2fr 1fr' }">
155 <SettingItem name="请求方式 & URL地址"> 186 <SettingItem name="请求方式 & URL地址">
156 <NInputGroup> 187 <NInputGroup>
  188 + <!--
  189 + /**
  190 + * ft 修改在公共接口下拉框里加上接口类型
  191 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  192 + * 源代码 无
  193 + * 修改后代码 新增一句 :render-label="renderOption"
  194 + */
  195 + -->
157 <NSelect v-model:value="selectedPublicInterface" label-field="interfaceName" value-field="id" 196 <NSelect v-model:value="selectedPublicInterface" label-field="interfaceName" value-field="id"
158 :options="publicInterfaceList" :filter="handleFilter" filterable :reset-menu-on-options-change="false" 197 :options="publicInterfaceList" :filter="handleFilter" filterable :reset-menu-on-options-change="false"
159 - @update-value="handleSelectedInterfaceChange" size="small"> 198 + @update-value="handleSelectedInterfaceChange" size="small" :render-label="renderOption">
160 </NSelect> 199 </NSelect>
  200 + <!-- ft -->
161 <NSelect v-if="requestContentTypeRef !== RequestContentTypeEnum.WEB_SOCKET" v-model:value="requestHttpTypeRef" 201 <NSelect v-if="requestContentTypeRef !== RequestContentTypeEnum.WEB_SOCKET" v-model:value="requestHttpTypeRef"
162 style="width: 150px;" size="small" :options="(selectTypeOptions as SelectOption[])" :disabled="true" /> 202 style="width: 150px;" size="small" :options="(selectTypeOptions as SelectOption[])" :disabled="true" />
163 <NSelect v-if="requestContentTypeRef === RequestContentTypeEnum.WEB_SOCKET" :disabled="true" style="width: 150px;" 203 <NSelect v-if="requestContentTypeRef === RequestContentTypeEnum.WEB_SOCKET" :disabled="true" style="width: 150px;"
@@ -225,6 +265,7 @@ defineExpose({ @@ -225,6 +265,7 @@ defineExpose({
225 </NScrollbar> 265 </NScrollbar>
226 </NCard> 266 </NCard>
227 </SettingItemBox> 267 </SettingItemBox>
  268 + <!-- ft -->
228 </template> 269 </template>
229 270
230 <style scoped lang="scss"> 271 <style scoped lang="scss">
@@ -11,6 +11,9 @@ import { PublicInterfaceForm } from '../PublicInterfaceForm'; @@ -11,6 +11,9 @@ import { PublicInterfaceForm } from '../PublicInterfaceForm';
11 import ComponentConfiguration from './ComponentConfiguration.vue'; 11 import ComponentConfiguration from './ComponentConfiguration.vue';
12 import GlobalPublicConfiguration from './GlobalPublicConfiguration.vue'; 12 import GlobalPublicConfiguration from './GlobalPublicConfiguration.vue';
13 import { createRequestModalContext } from './useRequestModalContext'; 13 import { createRequestModalContext } from './useRequestModalContext';
  14 +import { useTargetData } from '../../../../hooks/useTargetData.hook';
  15 +import { useFetchTargetData } from '@/hooks/external/useFetchTargetData';
  16 +import { useFilterFn } from '@/hooks/external/useFilterFn';
14 17
15 18
16 const requestDataType = ref<RequestDataTypeEnum>(RequestDataTypeEnum.AJAX) 19 const requestDataType = ref<RequestDataTypeEnum>(RequestDataTypeEnum.AJAX)
@@ -67,9 +70,26 @@ const getResult = () => { @@ -67,9 +70,26 @@ const getResult = () => {
67 return {} as unknown as RequestConfigType 70 return {} as unknown as RequestConfigType
68 } 71 }
69 72
  73 +const { targetData } = useTargetData()
  74 +const { fetchTargetData } = useFetchTargetData()
  75 +// 发送请求
  76 +const sendHandle = async () => {
  77 + if (!targetData.value?.request || !targetData.value.request.requestUrl) {
  78 + window['$message'].warning('请先配置请求')
  79 + return
  80 + }
  81 + const res = await fetchTargetData()
  82 + if (res) {
  83 + const { value } = useFilterFn(targetData.value.filter, res)
  84 + targetData.value.option.dataset = value
  85 + return
  86 + }
  87 +
  88 +}
  89 +
70 const handleSaveAction = async () => { 90 const handleSaveAction = async () => {
71 if (!(await validate())) return 91 if (!(await validate())) return
72 - const value = getResult() 92 + const value = getResult()
73 if (unref(selectTarget)) { 93 if (unref(selectTarget)) {
74 chartEditStore.updateComponentList(chartEditStore.fetchTargetIndex(), { 94 chartEditStore.updateComponentList(chartEditStore.fetchTargetIndex(), {
75 ...unref(selectTarget)!, 95 ...unref(selectTarget)!,
@@ -77,6 +97,7 @@ const handleSaveAction = async () => { @@ -77,6 +97,7 @@ const handleSaveAction = async () => {
77 }) 97 })
78 } 98 }
79 showModal.value = false 99 showModal.value = false
  100 + sendHandle()
80 } 101 }
81 102
82 createRequestModalContext({ 103 createRequestModalContext({
  1 +export { default as SelectTimeAggregation } from './index.vue'
  2 +
  3 +export interface SelectTimeAggregationValueTypw {
  4 + timePeriod?: Nullable<number>
  5 + startTs?: Nullable<number>
  6 + endTs?: Nullable<number>
  7 + agg?: Nullable<string>
  8 + interval?: Nullable<number>
  9 +}
  10 +
  11 +
  12 +export enum SelectTimeAggregationFieldEnum {
  13 + TIME_PERIOD = 'timePeriod',
  14 + START_TS = 'startTs',
  15 + END_TS = 'endTs',
  16 + AGG = 'agg',
  17 + INTERVAL = 'interval'
  18 +}
  19 +
  1 +<script lang="ts" setup>
  2 +import { NFormItem, NGi, NGrid, NSelect, NDatePicker, NInputNumber } from 'naive-ui';
  3 +import { defaultIntervalOptions, aggergationOptions } from '../DynamicForm/timeInterval'
  4 +import { unref, computed, ref, watch } from 'vue';
  5 +import { isObject } from '@/utils/external/is';
  6 +
  7 +interface Value {
  8 + agg?: Nullable<string>
  9 + interval?: Nullable<number>
  10 + startTs?: Nullable<number>
  11 + endTs?: Nullable<number>
  12 + limit?: Nullable<number>
  13 +}
  14 +
  15 +const props = withDefaults(
  16 + defineProps<{
  17 + value?: Value
  18 + }>(),
  19 + {
  20 + value: () => ({})
  21 + }
  22 +)
  23 +
  24 +const emit = defineEmits<{
  25 + (e: 'update:value', value: Value): void
  26 + (e: 'change', value: Value): void
  27 +}>()
  28 +
  29 +
  30 +const timePeriod = ref<Nullable<[number, number]>>(null)
  31 +const agg = ref()
  32 +const interval = ref()
  33 +const limit = ref(7)
  34 +
  35 +const getRangeOptions = (number: number) => {
  36 + for (let i = 0; i < defaultIntervalOptions.length; i++) {
  37 + const option = defaultIntervalOptions[i]
  38 + if (option.id >= number || i === defaultIntervalOptions.length - 1) {
  39 + return option.linkage
  40 + }
  41 +
  42 + }
  43 +}
  44 +
  45 +const getShowLimit = computed(() => {
  46 + return unref(agg) === 'NONE'
  47 +})
  48 +
  49 +const getIntervalTimeOptions = computed(() => {
  50 + const [startTs, endTs] = unref(timePeriod) || []
  51 + if (!startTs || !endTs) return []
  52 + const diff = Math.abs(startTs - endTs)
  53 + return getRangeOptions(diff)
  54 +})
  55 +
  56 +const handleTimePerionChange = (value: number[]) => {
  57 + const [startTs, endTs] = value
  58 + emit('update:value', { ...props.value, startTs, endTs, interval: null })
  59 + emit('change', { ...props.value || {}, startTs, endTs, interval: null })
  60 +}
  61 +
  62 +const handleAggChange = (value: string) => {
  63 + const _value = { ...props.value, agg: value, ...(value === 'NONE' ? { limit: 7 } : {}) }
  64 + Reflect.deleteProperty(_value, value === 'NONE' ? 'interval' : 'limit')
  65 + emit('update:value', _value)
  66 + emit('change', _value)
  67 +}
  68 +
  69 +const handleIntervalChange = (value: number) => {
  70 + const _value = { ...props.value, interval: value }
  71 + emit('update:value', _value)
  72 + emit('change', _value)
  73 +}
  74 +
  75 +const handleLimitChange = (value: Nullable<number>) => {
  76 + const _value = { ...props.value, limit: value }
  77 + emit('update:value', _value)
  78 + emit('change', _value)
  79 +}
  80 +
  81 +watch(() => props.value, (target) => {
  82 + if (target && isObject(target)) {
  83 + const { agg: _agg, interval: _interval, startTs, endTs, limit: _limit } = target || {}
  84 + if (startTs && endTs) {
  85 + timePeriod.value = [startTs!, endTs!]
  86 + } else {
  87 + timePeriod.value = null
  88 + }
  89 + agg.value = _agg
  90 + limit.value = _limit!
  91 + interval.value = _interval
  92 + }
  93 +})
  94 +</script>
  95 +
  96 +<template>
  97 + <NGrid :cols="24">
  98 + <NGi :span="16">
  99 + <NFormItem :show-label="false">
  100 + <NDatePicker v-model:value="timePeriod" type="datetimerange" placeholder="请选择时间范围"
  101 + @update-value="handleTimePerionChange" clearable></NDatePicker>
  102 + </NFormItem>
  103 + </NGi>
  104 + <NGi :span="4">
  105 + <NFormItem :show-label="false">
  106 + <NSelect v-model:value="agg" @update:value="handleAggChange" :options="aggergationOptions" label-field="name"
  107 + value-field="id" placeholder="聚合方式" clearable></NSelect>
  108 + </NFormItem>
  109 + </NGi>
  110 + <NGi v-if="!getShowLimit" :span="4">
  111 + <NFormItem :show-label="false">
  112 + <NSelect v-model:value="interval" @update:value="handleIntervalChange" :options="getIntervalTimeOptions"
  113 + label-field="name" value-field="id" placeholder="间隔时间" clearable></NSelect>
  114 + </NFormItem>
  115 + </NGi>
  116 + <NGi v-if="getShowLimit" :span="4">
  117 + <NFormItem :show-label="false">
  118 + <NInputNumber v-model:value="limit" :default-value="7" @update:value="handleLimitChange"
  119 + :parse="(input: string) => parseInt(input)" :min="7" :max="50000" :step="1" placeholder="请输入最大条数" />
  120 + </NFormItem>
  121 + </NGi>
  122 + </NGrid>
  123 +</template>
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 </n-tooltip> 31 </n-tooltip>
32 <n-divider vertical /> 32 <n-divider vertical />
33 <!-- 保存 --> 33 <!-- 保存 -->
34 - <n-tooltip placement="bottom" trigger="hover"> 34 + <n-tooltip v-if="!isCustomerUser" placement="bottom" trigger="hover">
35 <template #trigger> 35 <template #trigger>
36 <div class="save-btn"> 36 <div class="save-btn">
37 <n-button size="small" type="primary" ghost @click="dataSyncUpdate()"> 37 <n-button size="small" type="primary" ghost @click="dataSyncUpdate()">
@@ -64,6 +64,7 @@ import { HistoryStackEnum } from '@/store/modules/chartHistoryStore/chartHistory @@ -64,6 +64,7 @@ import { HistoryStackEnum } from '@/store/modules/chartHistoryStore/chartHistory
64 import { useSyncRemote } from '../../../hooks/external/useRemote.hook' 64 import { useSyncRemote } from '../../../hooks/external/useRemote.hook'
65 import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore' 65 import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
66 import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d' 66 import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
  67 +import { useRole } from '@/views/chart/hooks/external/business/useRole'
67 68
68 const { LayersIcon, BarChartIcon, PrismIcon, HomeIcon, ArrowBackIcon, ArrowForwardIcon } = icon.ionicons5 69 const { LayersIcon, BarChartIcon, PrismIcon, HomeIcon, ArrowBackIcon, ArrowForwardIcon } = icon.ionicons5
69 const { setItem } = useChartLayoutStore() 70 const { setItem } = useChartLayoutStore()
@@ -71,6 +72,7 @@ const { getLayers, getCharts, getDetails } = toRefs(useChartLayoutStore()) @@ -71,6 +72,7 @@ const { getLayers, getCharts, getDetails } = toRefs(useChartLayoutStore())
71 const chartEditStore = useChartEditStore() 72 const chartEditStore = useChartEditStore()
72 const chartHistoryStore = useChartHistoryStore() 73 const chartHistoryStore = useChartHistoryStore()
73 const { dataSyncUpdate } = useSyncRemote() 74 const { dataSyncUpdate } = useSyncRemote()
  75 +const { isCustomerUser } = useRole()
74 76
75 interface ItemType<T> { 77 interface ItemType<T> {
76 key: T 78 key: T
  1 +import { RoleEnum } from '@/enums/external/roleEnum';
  2 +import { useUserStore } from '@/store/external/modules/user';
  3 +import { computed, unref } from 'vue';
  4 +
  5 +export const useRole = () => {
  6 + const userStore = useUserStore();
  7 +
  8 + const getRole = computed(() => {
  9 + return userStore.userInfo?.roles![0] as RoleEnum;
  10 + });
  11 +
  12 + const isPlatformAdmin = computed(() => {
  13 + return unref(getRole) === RoleEnum.PLATFORM_ADMIN;
  14 + });
  15 +
  16 + const isCustomerUser = computed(() => {
  17 + return unref(getRole) === RoleEnum.CUSTOMER_USER;
  18 + });
  19 +
  20 + const isTenantAdmin = computed(() => {
  21 + return unref(getRole) === RoleEnum.TENANT_ADMIN;
  22 + });
  23 +
  24 + const isSysadmin = computed(() => {
  25 + return unref(getRole) === RoleEnum.SYS_ADMIN;
  26 + });
  27 +
  28 + return { getRole, isPlatformAdmin, isCustomerUser, isTenantAdmin, isSysadmin };
  29 +};
1 import { fetchRouteParamsLocation, JSONStringify, JSONParse } from '@/utils' 1 import { fetchRouteParamsLocation, JSONStringify, JSONParse } from '@/utils'
2 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 2 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
3 import { ProjectInfoEnum } from '@/store/external/modules/projectInfo.d' 3 import { ProjectInfoEnum } from '@/store/external/modules/projectInfo.d'
4 -import { onUnmounted } from 'vue' 4 +import { onUnmounted, unref } from 'vue'
5 import { saveInterval } from '@/settings/designSetting' 5 import { saveInterval } from '@/settings/designSetting'
6 import throttle from 'lodash/throttle' 6 import throttle from 'lodash/throttle'
7 import html2canvas from 'html2canvas' 7 import html2canvas from 'html2canvas'
@@ -11,6 +11,7 @@ import { SyncEnum } from '@/enums/external/editPageEnum' @@ -11,6 +11,7 @@ import { SyncEnum } from '@/enums/external/editPageEnum'
11 import { useProjectInfoStore } from '@/store/external/modules/projectInfo' 11 import { useProjectInfoStore } from '@/store/external/modules/projectInfo'
12 import { useSync } from '../useSync.hook' 12 import { useSync } from '../useSync.hook'
13 import { BaseUpdateContentParams, DateViewConfigurationInfoType } from '@/api/external/contentSave/model/contentModel' 13 import { BaseUpdateContentParams, DateViewConfigurationInfoType } from '@/api/external/contentSave/model/contentModel'
  14 +import { useRole } from './business/useRole'
14 15
15 /** 16 /**
16 * * base64转file 17 * * base64转file
@@ -37,6 +38,7 @@ export const useSyncRemote = () => { @@ -37,6 +38,7 @@ export const useSyncRemote = () => {
37 const chartEditStore = useChartEditStore() 38 const chartEditStore = useChartEditStore()
38 const projectInfoStore = useProjectInfoStore() 39 const projectInfoStore = useProjectInfoStore()
39 const { updateComponent } = useSync() 40 const { updateComponent } = useSync()
  41 + const { isCustomerUser } = useRole()
40 42
41 /** 43 /**
42 * * 赋值全局数据 44 * * 赋值全局数据
@@ -71,6 +73,10 @@ export const useSyncRemote = () => { @@ -71,6 +73,10 @@ export const useSyncRemote = () => {
71 // 数据保存 73 // 数据保存
72 const dataSyncUpdate = throttle(async (updateImg = true) => { 74 const dataSyncUpdate = throttle(async (updateImg = true) => {
73 if (!fetchRouteParamsLocation()) return 75 if (!fetchRouteParamsLocation()) return
  76 +
  77 + // 客户角色只有查看权限
  78 + if (unref(isCustomerUser)) return
  79 +
74 const { dataViewId, state, organizationId, dataViewName, dataViewContent } = projectInfoStore.getProjectInfo 80 const { dataViewId, state, organizationId, dataViewName, dataViewContent } = projectInfoStore.getProjectInfo
75 81
76 if (dataViewId === null || dataViewId === '') { 82 if (dataViewId === null || dataViewId === '') {
  1 +export const isShareMode = () => {
  2 + const sharePageReg = /^\/share\/[^/]+\/[^/]+\/[^/]+$/;
  3 + const { hash } = location;
  4 + return sharePageReg.test(hash.substring(1));
  5 +};
1 <template> 1 <template>
2 <section> 2 <section>
3 <preview v-if="!allowLoadPreviewPage" :key="key"></preview> 3 <preview v-if="!allowLoadPreviewPage" :key="key"></preview>
  4 + <NEmpty v-if="isEmpty" style="position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);" />
4 <NModal :show="showModal" :maskClosable="false" :closable="false" style="width: 300px;"> 5 <NModal :show="showModal" :maskClosable="false" :closable="false" style="width: 300px;">
5 <NCard> 6 <NCard>
6 <NForm @keyup.enter="handleSubmit"> 7 <NForm @keyup.enter="handleSubmit">
7 <NFormItem label="访问令牌"> 8 <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> 9 + <NInputGroup>
  10 + <NInput v-model:value="accessCredentials" show-password-on="mousedown" type="password"
  11 + style="width: 70%;" />
  12 + <NButton :loading="loading" type="primary" style="width: 30%;" @click="handleSubmit">
  13 + <svg style="transform: rotate(180deg);" t="1682068997810" class="icon" viewBox="0 0 1024 1024"
  14 + version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="79416" width="24" height="24">
  15 + <path
  16 + 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"
  17 + fill="#fff" p-id="79417" />
  18 + <path
  19 + 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"
  20 + fill="#fff" p-id="79418" />
  21 + <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"
  22 + fill="#fff" p-id="79419" />
  23 + </svg>
  24 + </NButton>
  25 + </NInputGroup>
12 </NFormItem> 26 </NFormItem>
13 </NForm> 27 </NForm>
14 </NCard> 28 </NCard>
@@ -17,11 +31,11 @@ @@ -17,11 +31,11 @@
17 </template> 31 </template>
18 32
19 <script setup lang="ts"> 33 <script setup lang="ts">
20 -import { NModal, NCard, NForm, NFormItem, NInput, NButton, } from 'naive-ui' 34 +import { NEmpty, NCard, NForm, NFormItem, NInput, NButton, NInputGroup } from 'naive-ui'
21 import { getSessionStorageInfo } from '../preview/utils' 35 import { getSessionStorageInfo } from '../preview/utils'
22 import type { ChartEditStorageType } from '../preview/index.d' 36 import type { ChartEditStorageType } from '../preview/index.d'
23 import { SavePageEnum } from '@/enums/editPageEnum' 37 import { SavePageEnum } from '@/enums/editPageEnum'
24 -import { JSONParse, setSessionStorage } from '@/utils' 38 +import { JSONParse, setSessionStorage, setTitle } from '@/utils'
25 import { StorageEnum } from '@/enums/storageEnum' 39 import { StorageEnum } from '@/enums/storageEnum'
26 import { onMounted, ref, unref } from 'vue' 40 import { onMounted, ref, unref } from 'vue'
27 import Preview from '../preview/index.vue' 41 import Preview from '../preview/index.vue'
@@ -42,7 +56,7 @@ const getToken = async () => { @@ -42,7 +56,7 @@ const getToken = async () => {
42 const { params } = ROUTE 56 const { params } = ROUTE
43 const { publicId } = params as Record<'id' | 'publicId', string> 57 const { publicId } = params as Record<'id' | 'publicId', string>
44 const { token, refreshToken } = await getPublicToken(publicId) 58 const { token, refreshToken } = await getPublicToken(publicId)
45 - userStore.storeToken(token, refreshToken) 59 + userStore.storeShareToken(token, refreshToken)
46 } 60 }
47 61
48 const checkNeedAccessToken = async () => { 62 const checkNeedAccessToken = async () => {
@@ -63,6 +77,7 @@ const sharePageHandlerProcess = async () => { @@ -63,6 +77,7 @@ const sharePageHandlerProcess = async () => {
63 } 77 }
64 } 78 }
65 79
  80 +const isEmpty = ref(false)
66 const getSharePageContentData = async () => { 81 const getSharePageContentData = async () => {
67 try { 82 try {
68 const { params } = ROUTE 83 const { params } = ROUTE
@@ -70,15 +85,17 @@ const getSharePageContentData = async () => { @@ -70,15 +85,17 @@ const getSharePageContentData = async () => {
70 loading.value = true 85 loading.value = true
71 const res = await getShareContentData({ id, accessCredentials: unref(accessCredentials) }) 86 const res = await getShareContentData({ id, accessCredentials: unref(accessCredentials) })
72 const { dataViewContent, dataViewName, dataViewId } = res.data 87 const { dataViewContent, dataViewName, dataViewId } = res.data
73 - const content = JSONParse(dataViewContent.content) as ChartEditStorageType 88 + if (!dataViewContent.content) isEmpty.value = true
  89 + const content = JSONParse(dataViewContent.content || '{}') as ChartEditStorageType
74 if (content) { 90 if (content) {
75 const { editCanvasConfig, requestGlobalConfig, componentList } = content 91 const { editCanvasConfig, requestGlobalConfig, componentList } = content
76 chartEditStore.editCanvasConfig = editCanvasConfig 92 chartEditStore.editCanvasConfig = editCanvasConfig
77 chartEditStore.requestGlobalConfig = requestGlobalConfig 93 chartEditStore.requestGlobalConfig = requestGlobalConfig
78 chartEditStore.componentList = componentList 94 chartEditStore.componentList = componentList
79 } 95 }
  96 + setTitle(dataViewName || '')
80 showModal.value = false 97 showModal.value = false
81 - allowLoadPreviewPage.value = false 98 + allowLoadPreviewPage.value = unref(isEmpty)
82 } catch (error) { 99 } catch (error) {
83 console.log(error) 100 console.log(error)
84 } finally { 101 } finally {
@@ -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> {