Commit fec47c39ba4e008caedd1f9800e2064e38eff1ed

Authored by xp.Huang
2 parents c2ad5966 caaa8306

Merge branch 'feat/tripartite-interface-token' into 'main_dev'

feat(src/packages): 大屏自定义请求新增第三方接口动态获取Token功能

See merge request yunteng/thingskit-view!255
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'; 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 12
13 -const globSetting = useGlobSetting();  
14 -const urlPrefix = globSetting.urlPrefix; 13 +const globSetting = useGlobSetting()
  14 +const urlPrefix = globSetting.urlPrefix
15 15
16 /** 16 /**
17 * @description: 数据处理,方便区分多种处理方式 17 * @description: 数据处理,方便区分多种处理方式
@@ -21,62 +21,59 @@ const transform: AxiosTransform = { @@ -21,62 +21,59 @@ const transform: AxiosTransform = {
21 * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误 21 * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
22 */ 22 */
23 transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => { 23 transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
24 - const { isReturnNativeResponse } = options; 24 + const { isReturnNativeResponse } = options
25 // 是否返回原生响应头 比如:需要获取响应头时使用该属性 25 // 是否返回原生响应头 比如:需要获取响应头时使用该属性
26 if (isReturnNativeResponse) { 26 if (isReturnNativeResponse) {
27 - return res; 27 + return res
28 } 28 }
29 - return res.data; 29 + return res.data
30 }, 30 },
31 31
32 // 请求之前处理config 32 // 请求之前处理config
33 beforeRequestHook: (config, options) => { 33 beforeRequestHook: (config, options) => {
34 - const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options; 34 + const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options
35 35
36 if (joinPrefix) { 36 if (joinPrefix) {
37 - config.url = `${urlPrefix}${config.url}`; 37 + config.url = `${urlPrefix}${config.url}`
38 } 38 }
39 39
40 if (apiUrl && isString(apiUrl)) { 40 if (apiUrl && isString(apiUrl)) {
41 - config.url = `${apiUrl}${config.url}`; 41 + config.url = `${apiUrl}${config.url}`
42 } 42 }
43 43
44 - const params = config.params || {};  
45 - const data = config.data || false;  
46 - formatDate && data && !isString(data) && formatRequestDate(data); 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) { 47 if (config.method?.toUpperCase() === RequestEnum.GET) {
48 if (!isString(params)) { 48 if (!isString(params)) {
49 // 给 get 请求加上时间戳参数,避免从缓存中拿数据。 49 // 给 get 请求加上时间戳参数,避免从缓存中拿数据。
50 - config.params = Object.assign(params || {}, joinTimestamp(joinTime, false)); 50 + config.params = Object.assign(params || {}, joinTimestamp(joinTime, false))
51 } else { 51 } else {
52 // 兼容restful风格 52 // 兼容restful风格
53 - config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;  
54 - config.params = undefined; 53 + config.url = config.url + params + `${joinTimestamp(joinTime, true)}`
  54 + config.params = undefined
55 } 55 }
56 } else { 56 } else {
57 if (!isString(params)) { 57 if (!isString(params)) {
58 - formatDate && formatRequestDate(params); 58 + formatDate && formatRequestDate(params)
59 if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) { 59 if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
60 - config.data = data;  
61 - config.params = params; 60 + config.data = data
  61 + config.params = params
62 } else { 62 } else {
63 // 非GET请求如果没有提供data,则将params视为data 63 // 非GET请求如果没有提供data,则将params视为data
64 - config.data = params;  
65 - config.params = undefined; 64 + config.data = params
  65 + config.params = undefined
66 } 66 }
67 if (joinParamsToUrl) { 67 if (joinParamsToUrl) {
68 - config.url = setObjToUrlParams(  
69 - config.url as string,  
70 - Object.assign({}, config.params, config.data)  
71 - ); 68 + config.url = setObjToUrlParams(config.url as string, Object.assign({}, config.params, config.data))
72 } 69 }
73 } else { 70 } else {
74 // 兼容restful风格 71 // 兼容restful风格
75 - config.url = config.url + params;  
76 - config.params = undefined; 72 + config.url = config.url + params
  73 + config.params = undefined
77 } 74 }
78 } 75 }
79 - return config; 76 + return config
80 }, 77 },
81 78
82 /** 79 /**
@@ -84,21 +81,32 @@ const transform: AxiosTransform = { @@ -84,21 +81,32 @@ const transform: AxiosTransform = {
84 */ 81 */
85 requestInterceptors: (config, options) => { 82 requestInterceptors: (config, options) => {
86 // 请求之前处理config 83 // 请求之前处理config
87 - const { requestOptions } = config;  
88 - const { withShareToken } = requestOptions || {};  
89 - const { requestOptions: { withToken } = {} } = options; 84 + const { requestOptions } = config
  85 + const { withShareToken } = requestOptions || {}
  86 + const { requestOptions: { withToken } = {} } = options
  87 + const { withThirdTokenPrefix, withThirdTokenKey, withThirdTokenString } = config.requestOptions as Recordable
90 if (withToken !== false) { 88 if (withToken !== false) {
91 - const shareToken = getShareJwtToken(); 89 + const shareToken = getShareJwtToken()
92 if (withShareToken && shareToken) { 90 if (withShareToken && shareToken) {
93 config.headers!['X-Authorization'] = options.authenticationScheme 91 config.headers!['X-Authorization'] = options.authenticationScheme
94 ? `${options.authenticationScheme} ${shareToken}` 92 ? `${options.authenticationScheme} ${shareToken}`
95 - : shareToken; 93 + : shareToken
96 } else { 94 } else {
97 - const token = getJwtToken();  
98 - if (token) {  
99 - config.headers!['X-Authorization'] = options.authenticationScheme  
100 - ? `${options.authenticationScheme} ${token}`  
101 - : token; 95 + const token = getJwtToken()
  96 + if (!withThirdTokenString) {
  97 + // 则是此平台
  98 + if (token) {
  99 + config.headers!['X-Authorization'] = options.authenticationScheme
  100 + ? `${options.authenticationScheme} ${token}`
  101 + : token
  102 + }
  103 + } else {
  104 + // 第三方接口
  105 + const authenticationScheme = withThirdTokenPrefix ? withThirdTokenPrefix : null
  106 + const tokenKey = withThirdTokenKey ? withThirdTokenKey : null
  107 + config.headers![tokenKey!] = withThirdTokenPrefix
  108 + ? `${authenticationScheme} ${withThirdTokenString}`
  109 + : `${withThirdTokenString}`
102 } 110 }
103 } 111 }
104 } 112 }
@@ -109,25 +117,22 @@ const transform: AxiosTransform = { @@ -109,25 +117,22 @@ const transform: AxiosTransform = {
109 * @description: 响应拦截器处理 117 * @description: 响应拦截器处理
110 */ 118 */
111 responseInterceptors: (res: AxiosResponse<any>) => { 119 responseInterceptors: (res: AxiosResponse<any>) => {
112 - return res; 120 + return res
113 }, 121 },
114 122
115 /** 123 /**
116 * @description: 响应错误处理 124 * @description: 响应错误处理
117 */ 125 */
118 responseInterceptorsCatch: (error: any) => { 126 responseInterceptorsCatch: (error: any) => {
  127 + const { response, config } = error || {}
  128 + const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none'
  129 + const errorMsgIsObj = typeof response?.data === 'object'
  130 + const msg: string = errorMsgIsObj ? response?.data?.message || response?.data?.msg : response?.data
119 131
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 -}; 132 + const flag = checkStatus(error?.response?.status, msg, errorMessageMode)
  133 + return Promise.reject(response?.data)
  134 + }
  135 +}
131 136
132 function createAxios(opt?: Partial<CreateAxiosOptions>) { 137 function createAxios(opt?: Partial<CreateAxiosOptions>) {
133 return new VAxios( 138 return new VAxios(
@@ -169,11 +174,11 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) { @@ -169,11 +174,11 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
169 ignoreCancelToken: true, 174 ignoreCancelToken: true,
170 // 是否携带token 175 // 是否携带token
171 withToken: true 176 withToken: true
172 - }, 177 + }
173 }, 178 },
174 opt || {} 179 opt || {}
175 ) 180 )
176 - ); 181 + )
177 } 182 }
178 -export const customHttp = createAxios();  
179 183
  184 +export const customHttp = createAxios()
1 -import { RequestBodyEnum, RequestHttpEnum, RequestParams } from "@/enums/httpEnum"  
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" 1 +import { RequestBodyEnum, RequestHttpEnum, RequestParams, RequestParamsObjType } from '@/enums/httpEnum'
  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'
7 7
8 export enum ParamsType { 8 export enum ParamsType {
9 REQUIRED, 9 REQUIRED,
@@ -20,7 +20,7 @@ const regDynamicParams = /(?={).+?(?<=})/g @@ -20,7 +20,7 @@ const regDynamicParams = /(?={).+?(?<=})/g
20 20
21 /** 21 /**
22 * @description 判断是否是动态参数 22 * @description 判断是否是动态参数
23 - * @param url 23 + * @param url
24 */ 24 */
25 export const isDynamicUrl = (url: string) => { 25 export const isDynamicUrl = (url: string) => {
26 regDynamicParams.lastIndex = 0 26 regDynamicParams.lastIndex = 0
@@ -29,7 +29,7 @@ export const isDynamicUrl = (url: string) => { @@ -29,7 +29,7 @@ export const isDynamicUrl = (url: string) => {
29 29
30 /** 30 /**
31 * @description 解析动态参数 31 * @description 解析动态参数
32 - * @param url 32 + * @param url
33 */ 33 */
34 export const decomposeDynamicParams = (url: string) => { 34 export const decomposeDynamicParams = (url: string) => {
35 regDynamicParams.lastIndex = 0 35 regDynamicParams.lastIndex = 0
@@ -46,8 +46,8 @@ export const decomposeDynamicParams = (url: string) => { @@ -46,8 +46,8 @@ export const decomposeDynamicParams = (url: string) => {
46 46
47 /** 47 /**
48 * @description 正则替换url中的动态参数 48 * @description 正则替换url中的动态参数
49 - * @param requestUrl  
50 - * @param Params 49 + * @param requestUrl
  50 + * @param Params
51 */ 51 */
52 const getDynamicRequestUrl = (requestUrl = '', Params: Recordable) => { 52 const getDynamicRequestUrl = (requestUrl = '', Params: Recordable) => {
53 requestUrl = decodeURI(requestUrl || '') 53 requestUrl = decodeURI(requestUrl || '')
@@ -101,9 +101,9 @@ const handleParams = (Params: Recordable) => { @@ -101,9 +101,9 @@ const handleParams = (Params: Recordable) => {
101 * 源代码 Params.keys = (Params.keys || [] as any).join(',') 101 * 源代码 Params.keys = (Params.keys || [] as any).join(',')
102 */ 102 */
103 if (!Array.isArray(Params.keys)) { 103 if (!Array.isArray(Params.keys)) {
104 - Params.keys = ([Params.keys] || [] as any).join(',') 104 + Params.keys = ([Params.keys] || ([] as any)).join(',')
105 } else { 105 } else {
106 - Params.keys = (Params.keys || [] as any).join(',') 106 + Params.keys = (Params.keys || ([] as any)).join(',')
107 } 107 }
108 //ft 108 //ft
109 } 109 }
@@ -115,27 +115,37 @@ const handleParams = (Params: Recordable) => { @@ -115,27 +115,37 @@ const handleParams = (Params: Recordable) => {
115 Reflect.deleteProperty(Params, SelectTimeAggregationFieldEnum.TIME_PERIOD) 115 Reflect.deleteProperty(Params, SelectTimeAggregationFieldEnum.TIME_PERIOD)
116 } 116 }
117 117
118 - return Object.keys(Params).filter(Boolean).reduce((prev, next) => ({ ...prev, [next]: Params[next] }), {}) 118 + return Object.keys(Params)
  119 + .filter(Boolean)
  120 + .reduce((prev, next) => ({ ...prev, [next]: Params[next] }), {})
119 } 121 }
120 122
121 //post请求动态追加query参数 123 //post请求动态追加query参数
122 const objConvertQuery = (data: Recordable) => { 124 const objConvertQuery = (data: Recordable) => {
123 - const _result = []; 125 + const _result = []
124 for (const key in data) { 126 for (const key in data) {
125 - const value = data[key]; 127 + const value = data[key]
126 if (value.constructor == Array) { 128 if (value.constructor == Array) {
127 value.forEach(function (_value) { 129 value.forEach(function (_value) {
128 - _result.push(key + "=" + _value);  
129 - }); 130 + _result.push(key + '=' + _value)
  131 + })
130 } else { 132 } else {
131 - _result.push(key + '=' + value); 133 + _result.push(key + '=' + value)
132 } 134 }
133 } 135 }
134 - return _result.join('&'); 136 + return _result.join('&')
135 } 137 }
136 138
137 export const customRequest = async (request: RequestConfigType) => { 139 export const customRequest = async (request: RequestConfigType) => {
138 - const { requestHttpType, requestParams, requestParamsBodyType, requestOriginUrl } = request as ExtraRequestConfigType 140 + const {
  141 + requestHttpType,
  142 + requestParams,
  143 + requestParamsBodyType,
  144 + requestOriginUrl,
  145 + requestVerificationToken,
  146 + requestTokenKey,
  147 + requestTokenSuffix
  148 + } = request as ExtraRequestConfigType
139 let { requestUrl } = request as ExtraRequestConfigType 149 let { requestUrl } = request as ExtraRequestConfigType
140 const { Header, Body } = requestParams 150 const { Header, Body } = requestParams
141 let { Params } = requestParams 151 let { Params } = requestParams
@@ -155,18 +165,47 @@ export const customRequest = async (request: RequestConfigType) => { @@ -155,18 +165,47 @@ export const customRequest = async (request: RequestConfigType) => {
155 * 修改后代码 requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl: `${requestUrl}?${objConvertQuery(Params)} 165 * 修改后代码 requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl: `${requestUrl}?${objConvertQuery(Params)}
156 */ 166 */
157 Params = handleParams(Params) 167 Params = handleParams(Params)
158 -  
159 - return customHttp.request<any>({  
160 - url: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl : `${requestUrl}?${objConvertQuery(Params)}`,  
161 - baseURL: getOriginUrl(requestOriginUrl!),  
162 - method: requestHttpType,  
163 - params: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? Params : null,  
164 - data: body,  
165 - headers: extraValue(Header)  
166 - }, {  
167 - joinPrefix: false,  
168 - apiUrl: '',  
169 - withShareToken: isShareMode()  
170 - }) 168 + return customHttp.request<any>(
  169 + {
  170 + url:
  171 + requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl : `${requestUrl}?${objConvertQuery(Params)}`,
  172 + baseURL: requestVerificationToken ? '' : getOriginUrl(requestOriginUrl!), // 如果是第三方接口,则无需添加baseURL
  173 + method: requestHttpType,
  174 + params: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? Params : null,
  175 + data: body,
  176 + headers: extraValue(Header)
  177 + },
  178 + {
  179 + joinPrefix: false,
  180 + apiUrl: '',
  181 + withShareToken: isShareMode(),
  182 + withThirdTokenString: requestVerificationToken,
  183 + withThirdTokenKey: requestTokenKey,
  184 + withThirdTokenPrefix: requestTokenSuffix
  185 + }
  186 + )
171 //ft 187 //ft
172 } 188 }
  189 +
  190 +export interface thirdInterfaceRequest {
  191 + requestOriginUrl: string
  192 + body: RequestParamsObjType
  193 +}
  194 +
  195 +//特殊处理第三方接口,一般获取token是POST请求,暂定POST
  196 +export const customThirdInterfaceRequest = async (request: thirdInterfaceRequest) => {
  197 + const { body, requestOriginUrl } = request
  198 +
  199 + return customHttp.request<any>(
  200 + {
  201 + url: requestOriginUrl,
  202 + method: RequestHttpEnum.POST,
  203 + data: body
  204 + },
  205 + {
  206 + joinPrefix: false,
  207 + apiUrl: '',
  208 + withToken: false
  209 + }
  210 + )
  211 +}
  1 +export enum DataTypeEnum {
  2 + DATA_RANGE = 'dataRange',
  3 + DATA_INPUT = 'dataInput'
  4 +}
  5 +
  6 +export enum DataTypeNameEnum {
  7 + DATA_RANGE = '日期区间',
  8 + DATA_INPUT = '文本输入'
  9 +}
  1 +export enum TokenEnum {
  2 + DEFAULT_TOKEN = 'Token',
  3 + TOKEN_STRING = 'TokenString',
  4 + NO_VERIFICATION = 'NoVerification'
  5 +}
  6 +
  7 +export enum TokenNameEnum {
  8 + DEFAULT_TOKEN = 'Token',
  9 + TOKEN_STRING = '令牌',
  10 + NO_VERIFICATION = '无验证'
  11 +}
@@ -23,7 +23,7 @@ export enum EditCanvasTypeEnum { @@ -23,7 +23,7 @@ export enum EditCanvasTypeEnum {
23 IS_CREATE = 'isCreate', 23 IS_CREATE = 'isCreate',
24 IS_DRAG = 'isDrag', 24 IS_DRAG = 'isDrag',
25 IS_SELECT = 'isSelect', 25 IS_SELECT = 'isSelect',
26 - IS_CODE_EDIT = "isCodeEdit" 26 + IS_CODE_EDIT = 'isCodeEdit'
27 } 27 }
28 28
29 // 编辑区域 29 // 编辑区域
@@ -61,10 +61,9 @@ export enum EditCanvasConfigEnum { @@ -61,10 +61,9 @@ export enum EditCanvasConfigEnum {
61 BACKGROUND_IMAGE = 'backgroundImage', 61 BACKGROUND_IMAGE = 'backgroundImage',
62 SELECT_COLOR = 'selectColor', 62 SELECT_COLOR = 'selectColor',
63 PREVIEW_SCALE_TYPE = 'previewScaleType', 63 PREVIEW_SCALE_TYPE = 'previewScaleType',
64 - ANIMATION_STYLE_CONFIG = 'animationsStyleConfig', 64 + ANIMATION_STYLE_CONFIG = 'animationsStyleConfig'
65 } 65 }
66 66
67 -  
68 export interface EditCanvasConfigType { 67 export interface EditCanvasConfigType {
69 // 滤镜-启用 68 // 滤镜-启用
70 [FilterEnum.FILTERS_SHOW]: boolean 69 [FilterEnum.FILTERS_SHOW]: boolean
@@ -176,8 +175,8 @@ type RequestPublicConfigType = { @@ -176,8 +175,8 @@ type RequestPublicConfigType = {
176 175
177 // 数据池项类型 176 // 数据池项类型
178 export type RequestDataPondItemType = { 177 export type RequestDataPondItemType = {
179 - dataPondId: string,  
180 - dataPondName: string, 178 + dataPondId: string
  179 + dataPondName: string
181 dataPondRequestConfig: RequestConfigType 180 dataPondRequestConfig: RequestConfigType
182 } 181 }
183 182
@@ -189,6 +188,14 @@ export interface RequestGlobalConfigType extends RequestPublicConfigType { @@ -189,6 +188,14 @@ export interface RequestGlobalConfigType extends RequestPublicConfigType {
189 requestOriginUrl?: string 188 requestOriginUrl?: string
190 // 公共数据池 189 // 公共数据池
191 requestDataPond: RequestDataPondItemType[] 190 requestDataPond: RequestDataPondItemType[]
  191 + // 验证方式
  192 + requestVerificationMethods?: TokenEnum
  193 + // 全局Token
  194 + requestVerificationToken?: string
  195 + // 请求头里的Token键
  196 + requestTokenKey?: string
  197 + // 请求头里的Token前缀
  198 + requestTokenSuffix?: string,
192 } 199 }
193 200
194 // 单个图表请求配置 201 // 单个图表请求配置
@@ -211,6 +218,12 @@ export interface RequestConfigType extends RequestPublicConfigType { @@ -211,6 +218,12 @@ export interface RequestConfigType extends RequestPublicConfigType {
211 requestSQLContent: { 218 requestSQLContent: {
212 sql: string 219 sql: string
213 } 220 }
  221 + // Token
  222 + requestVerificationToken?: string
  223 + // 请求头里的Token键
  224 + requestTokenKey?: string
  225 + // 请求头里的Token前缀
  226 + requestTokenSuffix?: string
214 } 227 }
215 228
216 // Store 类型 229 // Store 类型
@@ -135,7 +135,9 @@ function createNewPageItem(id: string = getUUID(), title = '页面'): PageChartE @@ -135,7 +135,9 @@ function createNewPageItem(id: string = getUUID(), title = '页面'): PageChartE
135 }, 135 },
136 Header: {}, 136 Header: {},
137 Params: {} 137 Params: {}
138 - } 138 + },
  139 + requestVerificationMethods: 'Token',
  140 + requestVerificationToken: '',
139 }, 141 },
140 // 图表数组(需存储给后端) 142 // 图表数组(需存储给后端)
141 componentList: [] 143 componentList: []
@@ -119,7 +119,16 @@ export class VAxios { @@ -119,7 +119,16 @@ export class VAxios {
119 if (userStore) { 119 if (userStore) {
120 try { 120 try {
121 const { requestOptions = {} } = config 121 const { requestOptions = {} } = config
122 - const { withShareToken, withToken } = requestOptions 122 + const { withShareToken, withToken, withThirdTokenString } = requestOptions
  123 + if (withThirdTokenString) {
  124 + //三方平台逻辑
  125 + const res = jwt_decode(withThirdTokenString) as Recordable;
  126 + const currentTime = (new Date().getTime() + (config.timeout || 0)) / 1000;
  127 + if (currentTime >= res?.exp) {
  128 + window['$message'].warning('第三方平台Token已经失效,请您重新返回设计页面点击执行请求获取最新Token')
  129 + }
  130 + } else {
  131 + //此平台逻辑
123 const token = withShareToken && withToken ? userStore.shareJwtToken : userStore.jwtToken 132 const token = withShareToken && withToken ? userStore.shareJwtToken : userStore.jwtToken
124 const doRefresh = withShareToken && withToken ? userStore.doShareRefresh : userStore.doRefresh 133 const doRefresh = withShareToken && withToken ? userStore.doShareRefresh : userStore.doRefresh
125 if (token) { 134 if (token) {
@@ -129,7 +138,8 @@ export class VAxios { @@ -129,7 +138,8 @@ export class VAxios {
129 await this.refreshTokenBeforeReq(doRefresh); 138 await this.refreshTokenBeforeReq(doRefresh);
130 } 139 }
131 } 140 }
132 - 141 + //
  142 + }
133 } catch (error) { 143 } catch (error) {
134 userStore.logout(); 144 userStore.logout();
135 } 145 }
@@ -38,3 +38,30 @@ export const parseWebUrl = (str = window.location.search) => { @@ -38,3 +38,30 @@ export const parseWebUrl = (str = window.location.search) => {
38 str.replace(reg, (_, k, v) => (params[k] = v)) 38 str.replace(reg, (_, k, v) => (params[k] = v))
39 return params 39 return params
40 } 40 }
  41 +
  42 +//嵌套对象转换为级联选择器数据格式
  43 +interface cascadingData {
  44 + label: string
  45 + value: string | cascadingData[] | number
  46 + children: cascadingData[] | null
  47 +}
  48 +export const convertToCascadingData = (obj: Recordable): cascadingData[] => {
  49 + const result: cascadingData[] = []
  50 + for (const key in obj) {
  51 + // eslint-disable-next-line no-prototype-builtins
  52 + if (obj.hasOwnProperty(key)) {
  53 + let value: cascadingData[] | string | number
  54 + if (typeof obj[key] === 'object' && obj[key] !== null) {
  55 + value = convertToCascadingData(obj[key])
  56 + } else {
  57 + value = String(obj[key])
  58 + }
  59 + result.push({
  60 + label: key,
  61 + value,
  62 + children: Array.isArray(value) ? value : null
  63 + })
  64 + }
  65 + }
  66 + return result
  67 +}
@@ -166,6 +166,20 @@ const closeFilter = () => { @@ -166,6 +166,20 @@ const closeFilter = () => {
166 showModal.value = false 166 showModal.value = false
167 } 167 }
168 168
  169 +// 发送请求
  170 +const sendHandle = async () => {
  171 + try {
  172 + const res = await fetchHandle()
  173 + if (res) {
  174 + const { value } = useFilterFn(targetData.value.filter, res)
  175 + targetData.value.option.dataset = value
  176 + return
  177 + }
  178 + } catch(e) {
  179 + console.error(e)
  180 + }
  181 +}
  182 +
169 // 新增过滤器 183 // 新增过滤器
170 const saveFilter = () => { 184 const saveFilter = () => {
171 if (errorFlag.value) { 185 if (errorFlag.value) {
@@ -174,6 +188,7 @@ const saveFilter = () => { @@ -174,6 +188,7 @@ const saveFilter = () => {
174 } 188 }
175 targetData.value.filter = filter.value 189 targetData.value.filter = filter.value
176 closeFilter() 190 closeFilter()
  191 + sendHandle()
177 } 192 }
178 193
179 watch( 194 watch(
@@ -14,21 +14,18 @@ import { RequestDataTypeEnum } from '@/enums/external/httpEnum' @@ -14,21 +14,18 @@ import { RequestDataTypeEnum } from '@/enums/external/httpEnum'
14 14
15 const { HelpOutlineIcon, FlashIcon } = icon.ionicons5 15 const { HelpOutlineIcon, FlashIcon } = icon.ionicons5
16 const { targetData } = useTargetData() 16 const { targetData } = useTargetData()
17 -  
18 -  
19 17
20 const requestModal = ref<InstanceType<typeof RequestModal>>() 18 const requestModal = ref<InstanceType<typeof RequestModal>>()
21 19
22 const designStore = useDesignStore() 20 const designStore = useDesignStore()
23 21
24 -  
25 /** 22 /**
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 - */ 23 + * ft 修改在公共接口下拉框里默认选择公共接口
  24 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  25 + * 源代码 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.AJAX)
  26 + * 修改后的代码 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.Pond)
  27 + * 修改后代码在//ft之间
  28 + */
32 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.Pond) 29 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.Pond)
33 30
34 const getApiRequestType: SelectOption[] = [ 31 const getApiRequestType: SelectOption[] = [
@@ -43,7 +40,7 @@ const showMatching = ref(false) @@ -43,7 +40,7 @@ const showMatching = ref(false)
43 let firstFocus = 0 40 let firstFocus = 0
44 let lastFilter: any = undefined 41 let lastFilter: any = undefined
45 42
46 -const { fetchTargetData, } = useFetchTargetData() 43 +const { fetchTargetData } = useFetchTargetData()
47 44
48 // 发送请求 45 // 发送请求
49 const sendHandle = async () => { 46 const sendHandle = async () => {
@@ -63,9 +60,9 @@ const sendHandle = async () => { @@ -63,9 +60,9 @@ const sendHandle = async () => {
63 } finally { 60 } finally {
64 loading.value = false 61 loading.value = false
65 } 62 }
66 -  
67 } 63 }
68 64
  65 +
69 // 颜色 66 // 颜色
70 const themeColor = computed(() => { 67 const themeColor = computed(() => {
71 return designStore.getAppTheme 68 return designStore.getAppTheme
@@ -73,6 +70,9 @@ const themeColor = computed(() => { @@ -73,6 +70,9 @@ const themeColor = computed(() => {
73 70
74 const handleClickPanel = () => { 71 const handleClickPanel = () => {
75 unref(requestModal as any)?.openModal?.(true, unref(selectedRequestType)) 72 unref(requestModal as any)?.openModal?.(true, unref(selectedRequestType))
  73 + if (selectedRequestType.value === RequestDataTypeEnum.AJAX) {
  74 + targetData.value.request.requestDataType = RequestDataTypeEnum.AJAX
  75 + }
76 } 76 }
77 77
78 // TODO socket 请求时会触发 78 // TODO socket 请求时会触发
@@ -81,7 +81,7 @@ watchEffect(() => { @@ -81,7 +81,7 @@ watchEffect(() => {
81 /** 81 /**
82 * FT 修改 82 * FT 修改
83 */ 83 */
84 - if(!filter) return 84 + if (!filter) return
85 //ft 85 //ft
86 if (lastFilter !== filter && firstFocus) { 86 if (lastFilter !== filter && firstFocus) {
87 lastFilter = filter 87 lastFilter = filter
@@ -93,8 +93,6 @@ watchEffect(() => { @@ -93,8 +93,6 @@ watchEffect(() => {
93 onBeforeUnmount(() => { 93 onBeforeUnmount(() => {
94 lastFilter = null 94 lastFilter = null
95 }) 95 })
96 -  
97 -  
98 </script> 96 </script>
99 97
100 <template> 98 <template>
@@ -137,8 +135,6 @@ onBeforeUnmount(() => { @@ -137,8 +135,6 @@ onBeforeUnmount(() => {
137 </div> 135 </div>
138 </template> 136 </template>
139 137
140 -  
141 -  
142 <style lang="scss" scoped> 138 <style lang="scss" scoped>
143 @include thingsKit('chart-configurations-data-ajax') { 139 @include thingsKit('chart-configurations-data-ajax') {
144 .n-card-shallow { 140 .n-card-shallow {
@@ -174,4 +170,4 @@ onBeforeUnmount(() => { @@ -174,4 +170,4 @@ onBeforeUnmount(() => {
174 } 170 }
175 } 171 }
176 } 172 }
177 -</style> 173 +</style>
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 -import { NInput, NInputNumber, NInputGroup, NButton, NSelect, SelectOption, NTabs, NTabPane, NSpace } from 'naive-ui' 2 +import { NInput, NInputNumber, NInputGroup, NSelect, SelectOption, NTabs, NTabPane } from 'naive-ui'
3 import { SettingItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'; 3 import { SettingItem, SettingItemBox } from '@/components/Pages/ChartItemSetting';
4 import { selectTimeOptions, selectTypeOptions } from '../../../index.d'; 4 import { selectTimeOptions, selectTypeOptions } from '../../../index.d';
5 import { RequestBodyEnum, RequestContentTypeEnum, RequestDataTypeEnum, RequestHttpEnum, RequestHttpIntervalEnum, RequestParams } from '@/enums/httpEnum'; 5 import { RequestBodyEnum, RequestContentTypeEnum, RequestDataTypeEnum, RequestHttpEnum, RequestHttpIntervalEnum, RequestParams } from '@/enums/httpEnum';
@@ -7,9 +7,6 @@ import { ref, unref } from 'vue'; @@ -7,9 +7,6 @@ import { ref, unref } from 'vue';
7 import DefaultRequestContent from './DefaultRequestContent.vue'; 7 import DefaultRequestContent from './DefaultRequestContent.vue';
8 import SqlConfiguration from './SqlConfiguration.vue'; 8 import SqlConfiguration from './SqlConfiguration.vue';
9 import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'; 9 import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d';
10 -import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';  
11 -  
12 -const chartEditStore = useChartEditStore()  
13 10
14 const requestContentTypeRef = ref(RequestContentTypeEnum.DEFAULT) 11 const requestContentTypeRef = ref(RequestContentTypeEnum.DEFAULT)
15 12
@@ -39,7 +36,7 @@ const getConfigurationData = (): RequestConfigType => { @@ -39,7 +36,7 @@ const getConfigurationData = (): RequestConfigType => {
39 sql: unref(requestSQLContentRef) 36 sql: unref(requestSQLContentRef)
40 }, 37 },
41 requestParams: unref(requestParamsRef), 38 requestParams: unref(requestParamsRef),
42 - requestUrl: `${chartEditStore.getRequestGlobalConfig.requestOriginUrl}${unref(requestUrlRef)}` 39 + requestUrl: `${unref(requestUrlRef)}`
43 } 40 }
44 } 41 }
45 42
@@ -53,7 +50,7 @@ const setConfigurationData = (request: RequestConfigType) => { @@ -53,7 +50,7 @@ const setConfigurationData = (request: RequestConfigType) => {
53 requestParamsBodyTypeRef.value = requestParamsBodyType 50 requestParamsBodyTypeRef.value = requestParamsBodyType
54 requestSQLContentRef.value = requestSQLContent.sql 51 requestSQLContentRef.value = requestSQLContent.sql
55 requestParamsRef.value = requestParams 52 requestParamsRef.value = requestParams
56 - requestUrlRef.value = !requestUrl ? ``: 'h' + requestUrl?.split('h')[1] 53 + requestUrlRef.value = requestUrl
57 } 54 }
58 55
59 defineExpose({ 56 defineExpose({
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -import { RequestBodyEnum, RequestParams, RequestParamsTypeEnum } from '@/enums/httpEnum';  
3 -import { NTabPane, NTabs } from 'naive-ui';  
4 -import { ref } from 'vue';  
5 -import ParamsTable from './ParamsTable.vue';  
6 -import RequestBody from './RequestBody.vue'; 2 +import { RequestBodyEnum, RequestParams, RequestParamsTypeEnum } from '@/enums/httpEnum'
  3 +import { NTabPane, NTabs } from 'naive-ui'
  4 +import { ref } from 'vue'
  5 +import ParamsTable from './ParamsTable.vue'
  6 +import RequestBody from './RequestBody.vue'
7 7
8 const props = defineProps<{ 8 const props = defineProps<{
9 value: RequestParams 9 value: RequestParams
@@ -21,7 +21,6 @@ const handleSyncRequestParamsBodyType = (value: RequestBodyEnum) => { @@ -21,7 +21,6 @@ const handleSyncRequestParamsBodyType = (value: RequestBodyEnum) => {
21 const handleUpdate = (key: RequestParamsTypeEnum, value: Recordable) => { 21 const handleUpdate = (key: RequestParamsTypeEnum, value: Recordable) => {
22 emit('update:value', { ...props.value, [key]: value }) 22 emit('update:value', { ...props.value, [key]: value })
23 } 23 }
24 -  
25 </script> 24 </script>
26 25
27 <template> 26 <template>
@@ -30,24 +29,29 @@ const handleUpdate = (key: RequestParamsTypeEnum, value: Recordable) => { @@ -30,24 +29,29 @@ const handleUpdate = (key: RequestParamsTypeEnum, value: Recordable) => {
30 <NTabPane v-for="item in RequestParamsTypeEnum" :name="item" :key="item"></NTabPane> 29 <NTabPane v-for="item in RequestParamsTypeEnum" :name="item" :key="item"></NTabPane>
31 </NTabs> 30 </NTabs>
32 <section v-if="tabValue === RequestParamsTypeEnum.PARAMS"> 31 <section v-if="tabValue === RequestParamsTypeEnum.PARAMS">
33 - <ParamsTable :value="value[RequestParamsTypeEnum.PARAMS]"  
34 - @update:value="(value: Recordable) => handleUpdate(RequestParamsTypeEnum.PARAMS, value)" /> 32 + <ParamsTable
  33 + :value="value[RequestParamsTypeEnum.PARAMS]"
  34 + @update:value="(value: Recordable) => handleUpdate(RequestParamsTypeEnum.PARAMS, value)"
  35 + />
35 </section> 36 </section>
36 37
37 - <RequestBody :value="value" @update:value="(value: Recordable) => handleUpdate(RequestParamsTypeEnum.BODY, value)"  
38 - @update:requestParamsBodyType="handleSyncRequestParamsBodyType" :requestParamsBodyType="requestParamsBodyType"  
39 - v-if="tabValue === RequestParamsTypeEnum.BODY" />  
40 -  
41 - <ParamsTable v-if="tabValue === RequestParamsTypeEnum.HEADER" :value="value.Header"  
42 - @update:value="(value: Recordable) => handleUpdate(RequestParamsTypeEnum.HEADER, value)" /> 38 + <RequestBody
  39 + :value="value"
  40 + @update:value="(value: Recordable) => handleUpdate(RequestParamsTypeEnum.BODY, value)"
  41 + @update:requestParamsBodyType="handleSyncRequestParamsBodyType"
  42 + :requestParamsBodyType="requestParamsBodyType"
  43 + v-if="tabValue === RequestParamsTypeEnum.BODY"
  44 + />
  45 +
  46 + <ParamsTable
  47 + v-if="tabValue === RequestParamsTypeEnum.HEADER"
  48 + :value="value.Header"
  49 + @update:value="(value: Recordable) => handleUpdate(RequestParamsTypeEnum.HEADER, value)"
  50 + />
43 </section> 51 </section>
44 </template> 52 </template>
45 53
46 <style lang="scss" scoped> 54 <style lang="scss" scoped>
47 -.container {  
48 - width: 600px;  
49 -}  
50 -  
51 .body-container { 55 .body-container {
52 margin-top: 20px; 56 margin-top: 20px;
53 } 57 }
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -import { SettingItem, SettingItemBox } from '@/components/Pages/ChartItemSetting';  
3 -import { icon } from '@/plugins';  
4 -import { NButton, NCard, NCollapseTransition, NIcon, NInput, NInputGroup, NInputNumber, NSelect, NSpace, NTag, NTooltip, SelectOption } from 'naive-ui';  
5 -import { computed, ref, unref } from 'vue'; 2 +import { SettingItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
  3 +import { icon } from '@/plugins'
  4 +import {
  5 + NButton,
  6 + NCard,
  7 + NCollapseTransition,
  8 + NIcon,
  9 + NInput,
  10 + NInputGroup,
  11 + NInputNumber,
  12 + NSelect,
  13 + NSpace,
  14 + NTag,
  15 + NTooltip,
  16 + SelectOption,
  17 + NCascader
  18 +} from 'naive-ui'
  19 +import { computed, ref, unref, onMounted, reactive } from 'vue'
6 import GlobalParamsConfiguration from './GlobalParamsConfiguration.vue' 20 import GlobalParamsConfiguration from './GlobalParamsConfiguration.vue'
7 import { ChevronDown, ChevronUp } from '@vicons/carbon' 21 import { ChevronDown, ChevronUp } from '@vicons/carbon'
8 -import { useDesignStore } from '@/store/modules/designStore/designStore';  
9 -import { selectTimeOptions } from '../../../index.d';  
10 -import { useTargetData } from '../../../../hooks/useTargetData.hook';  
11 -import { RequestHttpIntervalEnum } from '@/enums/httpEnum'; 22 +import { useDesignStore } from '@/store/modules/designStore/designStore'
  23 +import { selectTimeOptions } from '../../../index.d'
  24 +import { useTargetData } from '../../../../hooks/useTargetData.hook'
  25 +import { RequestDataTypeEnum, RequestHttpIntervalEnum } from '@/enums/httpEnum'
  26 +import { TokenNameEnum, TokenEnum } from '@/enums/external/tokenEnum'
  27 +import { customThirdInterfaceRequest, thirdInterfaceRequest } from '@/api/external/customRequest'
  28 +import { CascaderOption } from 'naive-ui'
  29 +import { convertToCascadingData } from '@/utils/external/utils'
12 30
13 const { PencilIcon } = icon.ionicons5 31 const { PencilIcon } = icon.ionicons5
14 const designStore = useDesignStore() 32 const designStore = useDesignStore()
15 const editDisabled = ref(false) 33 const editDisabled = ref(false)
16 const collapseHeaderTable = ref(false) 34 const collapseHeaderTable = ref(false)
17 35
18 -const { chartEditStore } = useTargetData() 36 +const { targetData, chartEditStore } = useTargetData()
19 37
20 const handleCollapse = () => { 38 const handleCollapse = () => {
21 collapseHeaderTable.value = !unref(collapseHeaderTable) 39 collapseHeaderTable.value = !unref(collapseHeaderTable)
22 } 40 }
23 41
24 -  
25 // 颜色 42 // 颜色
26 const themeColor = computed(() => { 43 const themeColor = computed(() => {
27 return designStore.getAppTheme 44 return designStore.getAppTheme
28 }) 45 })
29 46
  47 +//第三方接口相关代码
  48 +const verifiationValue = ref(TokenEnum.DEFAULT_TOKEN)
  49 +
  50 +const tokenString = ref('')
  51 +
  52 +const getTokenString = ref()
  53 +
  54 +const resOptions = ref<CascaderOption[]>([])
  55 +
  56 +const resValue = ref()
  57 +
  58 +const cascaderConfig = reactive({
  59 + hoverTrigger: true,
  60 + checkStrategyIsChild: true,
  61 + filterable: false,
  62 + showPath: true
  63 +})
  64 +
  65 +const requestTokenSuffix = ref('Bearer')
  66 +
  67 +const requestTokenKey = ref('Token')
  68 +
  69 +//验证方式
  70 +const verificationMethods = [
  71 + {
  72 + label: TokenNameEnum.DEFAULT_TOKEN,
  73 + value: TokenEnum.DEFAULT_TOKEN
  74 + },
  75 + {
  76 + label: TokenNameEnum.TOKEN_STRING,
  77 + value: TokenEnum.TOKEN_STRING
  78 + },
  79 + {
  80 + label: TokenNameEnum.NO_VERIFICATION,
  81 + value: TokenEnum.NO_VERIFICATION
  82 + }
  83 +]
  84 +
  85 +const hasDefaultToken = (value: string[]) => value.includes(TokenEnum.DEFAULT_TOKEN)
  86 +
  87 +const hasTokenString = (value: string[]) => value.includes(TokenEnum.TOKEN_STRING)
30 88
  89 +const handleVerificationUpdate = (value: string) => {
  90 + chartEditStore.getRequestGlobalConfig.requestVerificationMethods = value
  91 + hasTokenString([value])
  92 + hasDefaultToken([value])
  93 + resValue.value = null
  94 + resOptions.value = []
  95 + getTokenString.value = ''
  96 + requestTokenKey.value = ''
  97 + requestTokenSuffix.value = ''
  98 +}
  99 +
  100 +const handleResCascader = (value: string | number) => {
  101 + getTokenString.value = value as string | number
  102 + chartEditStore.getRequestGlobalConfig.requestVerificationToken = value as string
  103 + targetData.value.request.requestVerificationToken = value as string
  104 + targetData.value.request.requestDataType = RequestDataTypeEnum.AJAX
  105 +}
31 106
  107 +//执行请求获取三方Token
  108 +const handleExecuteRequest = async () => {
  109 + try {
  110 + const request = {
  111 + requestOriginUrl: chartEditStore.getRequestGlobalConfig.requestOriginUrl,
  112 + body: chartEditStore.getRequestGlobalConfig.requestParams.Header
  113 + }
  114 + const res = await customThirdInterfaceRequest(request as thirdInterfaceRequest)
  115 + resOptions.value = convertToCascadingData(res) as unknown as CascaderOption[]
  116 + chartEditStore.getRequestGlobalConfig.requestVerificationMethods = verifiationValue.value
  117 + chartEditStore.getRequestGlobalConfig.requestVerificationToken = resValue.value as string
  118 + chartEditStore.getRequestGlobalConfig.requestTokenKey = requestTokenKey.value
  119 + chartEditStore.getRequestGlobalConfig.requestTokenSuffix = requestTokenSuffix.value
  120 + //存储到当前组件的请求对象里
  121 + targetData.value.request.requestTokenSuffix = requestTokenSuffix.value
  122 + targetData.value.request.requestTokenKey = requestTokenKey.value
  123 + } catch (e) {
  124 + getTokenString.value = JSON.stringify(e) as string
  125 + }
  126 +}
  127 +
  128 +onMounted(() => {
  129 + getTokenString.value = chartEditStore.getRequestGlobalConfig.requestVerificationToken
  130 + verifiationValue.value = chartEditStore.getRequestGlobalConfig.requestVerificationMethods || TokenEnum.DEFAULT_TOKEN
  131 + requestTokenKey.value = chartEditStore.getRequestGlobalConfig.requestTokenKey!
  132 + requestTokenSuffix.value = chartEditStore.getRequestGlobalConfig.requestTokenSuffix!
  133 +})
  134 +//
32 </script> 135 </script>
33 136
34 <template> 137 <template>
@@ -37,23 +140,43 @@ const themeColor = computed(() => { @@ -37,23 +140,43 @@ const themeColor = computed(() => {
37 <NTag type="info">全局公共配置</NTag> 140 <NTag type="info">全局公共配置</NTag>
38 </template> 141 </template>
39 <NSpace vertical> 142 <NSpace vertical>
40 - <SettingItemBox name="服务" :itemRightStyle="{  
41 - gridTemplateColumns: '5fr 2fr 1fr'  
42 - }"> 143 + <SettingItemBox
  144 + name="服务"
  145 + :itemRightStyle="{
  146 + gridTemplateColumns: '5fr 2fr 1fr'
  147 + }"
  148 + >
43 <!-- 源地址 --> 149 <!-- 源地址 -->
44 <SettingItem name="前置 URL"> 150 <SettingItem name="前置 URL">
45 - <NInput v-model:value="chartEditStore.getRequestGlobalConfig.requestOriginUrl" default-value="http://127.0.0.1" :disabled="editDisabled"  
46 - size="small" placeholder="例:http://127.0.0.1"></NInput> 151 + <NInput
  152 + v-model:value="chartEditStore.getRequestGlobalConfig.requestOriginUrl"
  153 + default-value="http://127.0.0.1"
  154 + :disabled="editDisabled"
  155 + size="small"
  156 + placeholder="例:http://127.0.0.1"
  157 + ></NInput>
47 </SettingItem> 158 </SettingItem>
48 <SettingItem name="更新间隔,为 0 只会初始化"> 159 <SettingItem name="更新间隔,为 0 只会初始化">
49 <NInputGroup> 160 <NInputGroup>
50 - <NInputNumber v-model:value="chartEditStore.getRequestGlobalConfig.requestInterval" class="select-time-number"  
51 - size="small" min="0" :show-button="false" :disabled="editDisabled" placeholder="请输入数字"> 161 + <NInputNumber
  162 + v-model:value="chartEditStore.getRequestGlobalConfig.requestInterval"
  163 + class="select-time-number"
  164 + size="small"
  165 + min="0"
  166 + :show-button="false"
  167 + :disabled="editDisabled"
  168 + placeholder="请输入数字"
  169 + >
52 </NInputNumber> 170 </NInputNumber>
53 <!-- 单位 --> 171 <!-- 单位 -->
54 - <NSelect v-model:value="chartEditStore.getRequestGlobalConfig.requestIntervalUnit" class="select-time-options"  
55 - size="small" :default-value="RequestHttpIntervalEnum.SECOND" :options="selectTimeOptions as SelectOption[]"  
56 - :disabled="editDisabled" /> 172 + <NSelect
  173 + v-model:value="chartEditStore.getRequestGlobalConfig.requestIntervalUnit"
  174 + class="select-time-options"
  175 + size="small"
  176 + :default-value="RequestHttpIntervalEnum.SECOND"
  177 + :options="selectTimeOptions as SelectOption[]"
  178 + :disabled="editDisabled"
  179 + />
57 </NInputGroup> 180 </NInputGroup>
58 </SettingItem> 181 </SettingItem>
59 <NButton v-show="editDisabled" type="primary" ghost @click="editDisabled = false"> 182 <NButton v-show="editDisabled" type="primary" ghost @click="editDisabled = false">
@@ -65,8 +188,67 @@ const themeColor = computed(() => { @@ -65,8 +188,67 @@ const themeColor = computed(() => {
65 编辑配置 188 编辑配置
66 </NButton> 189 </NButton>
67 </SettingItemBox> 190 </SettingItemBox>
  191 + <!-- 针对第三方接口 -->
  192 + <SettingItemBox
  193 + name="验证方式"
  194 + :itemRightStyle="{
  195 + gridTemplateColumns: '5fr 2fr 1fr'
  196 + }"
  197 + >
  198 + <n-radio-group v-model:value="verifiationValue" name="radiogroup" @update:value="handleVerificationUpdate">
  199 + <n-space>
  200 + <n-radio
  201 + v-for="verificationItem in verificationMethods"
  202 + :key="verificationItem.value"
  203 + :value="verificationItem.value"
  204 + >
  205 + {{ verificationItem.label }}
  206 + </n-radio>
  207 + </n-space>
  208 + </n-radio-group>
  209 + </SettingItemBox>
  210 + <SettingItemBox v-if="hasDefaultToken([verifiationValue])" name="配置">
  211 + <SettingItem name="Token前缀">
  212 + <n-input v-model:value.trim="requestTokenSuffix" type="text" placeholder="例如:Bearer" />
  213 + </SettingItem>
  214 + <SettingItem name="Token键">
  215 + <n-input v-model:value.trim="requestTokenKey" type="text" placeholder="例如:X-Authorization" />
  216 + </SettingItem>
  217 + </SettingItemBox>
68 <NCollapseTransition :show="collapseHeaderTable"> 218 <NCollapseTransition :show="collapseHeaderTable">
69 - <GlobalParamsConfiguration /> 219 + <GlobalParamsConfiguration v-if="hasDefaultToken([verifiationValue])" />
  220 + <n-input
  221 + v-else-if="hasTokenString([verifiationValue])"
  222 + v-model:value="tokenString"
  223 + type="text"
  224 + placeholder="请输入令牌字符串"
  225 + />
  226 + <n-empty v-else description="无"> </n-empty>
  227 + <div style="margin-top: 10px">
  228 + <n-space vertical>
  229 + <n-button type="primary" @click="handleExecuteRequest">执行请求</n-button>
  230 + <NCascader
  231 + v-model:value="resValue"
  232 + @update:value="handleResCascader"
  233 + :expand-trigger="cascaderConfig.hoverTrigger ? 'hover' : 'click'"
  234 + :check-strategy="cascaderConfig.checkStrategyIsChild ? 'child' : 'all'"
  235 + :show-path="cascaderConfig.showPath"
  236 + :filterable="cascaderConfig.filterable"
  237 + placeholder="请选择"
  238 + :options="resOptions"
  239 + />
  240 + <n-input
  241 + :autosize="{
  242 + minRows: 3,
  243 + maxRows: 9
  244 + }"
  245 + v-model:value="getTokenString"
  246 + type="textarea"
  247 + placeholder="Token:"
  248 + />
  249 + </n-space>
  250 + </div>
  251 + <!-- 针对第三方接口 -->
70 </NCollapseTransition> 252 </NCollapseTransition>
71 <section class="arrow"> 253 <section class="arrow">
72 <NTooltip> 254 <NTooltip>
@@ -83,7 +265,6 @@ const themeColor = computed(() => { @@ -83,7 +265,6 @@ const themeColor = computed(() => {
83 </NCard> 265 </NCard>
84 </template> 266 </template>
85 267
86 -  
87 <style lang="scss" scoped> 268 <style lang="scss" scoped>
88 .arrow { 269 .arrow {
89 display: flex; 270 display: flex;
@@ -93,7 +274,6 @@ const themeColor = computed(() => { @@ -93,7 +274,6 @@ const themeColor = computed(() => {
93 274
94 &:hover { 275 &:hover {
95 color: v-bind('themeColor'); 276 color: v-bind('themeColor');
96 -  
97 } 277 }
98 } 278 }
99 </style> 279 </style>
1 -<script setup lang="ts" >  
2 -import { getUUID } from '@/utils';  
3 -import { ButtonProps, DataTableColumns, InputProps, NButton, NDataTable, NIcon, NInput, NSpace, NTag, NTooltip, TagProps } from 'naive-ui';  
4 -import { computed, h, ref, unref, watch } from 'vue'; 1 +<script setup lang="ts">
  2 +import { getUUID } from '@/utils'
  3 +import {
  4 + ButtonProps,
  5 + DataTableColumns,
  6 + InputProps,
  7 + NButton,
  8 + NDataTable,
  9 + NIcon,
  10 + NInput,
  11 + NSpace,
  12 + NTooltip,
  13 + NSelect,
  14 + SelectProps,
  15 + NDatePicker,
  16 + DatePickerProps
  17 +} from 'naive-ui'
  18 +import { computed, h, ref, unref, watch } from 'vue'
5 import { Subtract, Add } from '@vicons/carbon' 19 import { Subtract, Add } from '@vicons/carbon'
6 -import { isObject } from '@/utils/external/is'; 20 +import { isArray, isObject } from '@/utils/external/is'
  21 +import { DataTypeEnum, DataTypeNameEnum } from '@/enums/external/dataTypeEnum'
  22 +import { Recordable } from 'vite-plugin-mock'
7 23
8 interface DataSource { 24 interface DataSource {
9 id: string 25 id: string
10 value?: string 26 value?: string
11 keyName?: string 27 keyName?: string
  28 + indexName?: number
  29 + typeName?: string
  30 + dateRange?: number[] | null
12 result?: boolean 31 result?: boolean
13 } 32 }
14 33
@@ -17,99 +36,126 @@ const columns: DataTableColumns<DataSource> = [ @@ -17,99 +36,126 @@ const columns: DataTableColumns<DataSource> = [
17 title: '序号', 36 title: '序号',
18 key: 'index', 37 key: 'index',
19 render: (_, index) => index + 1, 38 render: (_, index) => index + 1,
20 - width: 50, 39 + width: 50
  40 + },
  41 + {
  42 + title: 'Type',
  43 + key: 'typeName',
  44 + render: (row, index) => {
  45 + return h(NSelect, {
  46 + value: row.typeName,
  47 + options: [
  48 + {
  49 + label: DataTypeNameEnum.DATA_RANGE,
  50 + value: DataTypeEnum.DATA_RANGE
  51 + },
  52 + {
  53 + label: DataTypeNameEnum.DATA_INPUT,
  54 + value: DataTypeEnum.DATA_INPUT
  55 + }
  56 + ],
  57 + onUpdateValue: (value: string) => {
  58 + unref(dataSource)[index].typeName = value
  59 + unref(dataSource)[index].indexName = index
  60 + },
  61 + size: 'small',
  62 + disabled: props.disabled
  63 + } as SelectProps)
  64 + },
  65 + width: 120
21 }, 66 },
22 { 67 {
23 title: 'Key', 68 title: 'Key',
24 key: 'keyName', 69 key: 'keyName',
25 render: (row, index) => { 70 render: (row, index) => {
26 - return h(  
27 - NInput,  
28 - {  
29 - value: row.keyName,  
30 - onBlur: () => handleInputBlur(row),  
31 - onUpdateValue: (value: string) => unref(dataSource)[index].keyName = value,  
32 - size: 'small',  
33 - disabled: props.disabled  
34 - } as InputProps  
35 - )  
36 - } 71 + return h(NInput, {
  72 + value: row.keyName,
  73 + onBlur: () => handleInputBlur(),
  74 + onUpdateValue: (value: string) => (unref(dataSource)[index].keyName = value),
  75 + size: 'small',
  76 + disabled: props.disabled
  77 + } as InputProps)
  78 + },
  79 + width: 120
37 }, 80 },
38 { 81 {
39 title: 'Value', 82 title: 'Value',
40 key: 'value', 83 key: 'value',
41 render: (row, index) => { 84 render: (row, index) => {
42 - return h(  
43 - NInput,  
44 - {  
45 - value: row.value,  
46 - onBlur: () => handleInputBlur(row),  
47 - onUpdateValue: (value: string) => unref(dataSource)[index].value = value,  
48 - size: 'small',  
49 - disabled: props.disabled  
50 - } as InputProps  
51 - )  
52 - } 85 + const findIndexName = unref(dataSource).find(item => item.indexName === index)
  86 + return findIndexName?.indexName === index && findIndexName.typeName === DataTypeEnum.DATA_INPUT
  87 + ? h(NInput, {
  88 + value: row.value,
  89 + onBlur: () => handleInputBlur(),
  90 + onUpdateValue: (value: string) => (unref(dataSource)[index].value = value),
  91 + size: 'small',
  92 + disabled: props.disabled
  93 + } as InputProps)
  94 + : ''
  95 + },
  96 + width: 120
53 }, 97 },
54 { 98 {
55 - title: '操作',  
56 - key: 'actions',  
57 - render: (row) => {  
58 - return h(  
59 - NSpace,  
60 - () => [  
61 - h(  
62 - NTooltip,  
63 - null,  
64 - {  
65 - trigger: () => h(  
66 - NButton,  
67 - {  
68 - type: 'success',  
69 - size: 'small',  
70 - ghost: true,  
71 - onClick: () => handleAddRow(row),  
72 - disabled: props.disabled || !unref(canAddRow)  
73 - } as ButtonProps,  
74 - {  
75 - default: () => h(NIcon, () => h(Add))  
76 - }  
77 - ),  
78 - default: () => '插入行'  
79 - }  
80 - ),  
81 - h(  
82 - NTooltip,  
83 - null,  
84 - {  
85 - trigger: () => h(  
86 - NButton,  
87 - {  
88 - type: 'warning',  
89 - size: 'small',  
90 - ghost: true,  
91 - onClick: () => handleSubtractRow(row),  
92 - // disabled: props.disabled || !unref(canDeleteRow)  
93 - } as ButtonProps,  
94 - {  
95 - default: () => h(NIcon, () => h(Subtract))  
96 - }  
97 - ),  
98 - default: () => '删除行'  
99 - }  
100 - )  
101 - ]  
102 - ) 99 + title: 'Date',
  100 + key: 'dateRange',
  101 + render: (row, index) => {
  102 + const findIndexName = unref(dataSource).find(item => item.indexName === index)
  103 + return findIndexName?.indexName === index && findIndexName.typeName === DataTypeEnum.DATA_RANGE
  104 + ? h(NDatePicker, {
  105 + value: row.value,
  106 + size: 'small',
  107 + type: 'datetimerange',
  108 + onBlur: () => handleInputBlur(),
  109 + onUpdateValue: (value: number[]) => {
  110 + unref(dataSource)[index].dateRange = value
  111 + },
  112 + disabled: props.disabled
  113 + } as DatePickerProps)
  114 + : ''
103 }, 115 },
104 - width: 100, 116 + width: 200
105 }, 117 },
106 { 118 {
107 - title: '结果',  
108 - key: 'result',  
109 - render: (row) => {  
110 - return h(NTag, { type: row.result ? 'success' : 'error' } as TagProps, () => `${row.result ? '' : '未'}通过`) 119 + title: '操作',
  120 + key: 'actions',
  121 + render: row => {
  122 + return h(NSpace, () => [
  123 + h(NTooltip, null, {
  124 + trigger: () =>
  125 + h(
  126 + NButton,
  127 + {
  128 + type: 'success',
  129 + size: 'small',
  130 + ghost: true,
  131 + onClick: () => handleAddRow(row),
  132 + disabled: props.disabled || !unref(canAddRow)
  133 + } as ButtonProps,
  134 + {
  135 + default: () => h(NIcon, () => h(Add))
  136 + }
  137 + ),
  138 + default: () => '插入行'
  139 + }),
  140 + h(NTooltip, null, {
  141 + trigger: () =>
  142 + h(
  143 + NButton,
  144 + {
  145 + type: 'warning',
  146 + size: 'small',
  147 + ghost: true,
  148 + onClick: () => handleSubtractRow(row)
  149 + } as ButtonProps,
  150 + {
  151 + default: () => h(NIcon, () => h(Subtract))
  152 + }
  153 + ),
  154 + default: () => '删除行'
  155 + })
  156 + ])
111 }, 157 },
112 - width: 80 158 + width: 120
113 } 159 }
114 ] 160 ]
115 161
@@ -121,29 +167,33 @@ const props = withDefaults( @@ -121,29 +167,33 @@ const props = withDefaults(
121 }>(), 167 }>(),
122 { 168 {
123 disabled: false, 169 disabled: false,
124 - maxRow: 50, 170 + maxRow: 50
125 } 171 }
126 ) 172 )
127 173
128 -  
129 const emit = defineEmits(['update:value']) 174 const emit = defineEmits(['update:value'])
130 175
131 const createNewRow = () => { 176 const createNewRow = () => {
132 return { id: getUUID(), result: true } as DataSource 177 return { id: getUUID(), result: true } as DataSource
133 } 178 }
134 179
135 -const dataSource = ref<DataSource[]>([  
136 - createNewRow()  
137 -]) 180 +const dataSource = ref<DataSource[]>([createNewRow()])
  181 +
  182 +const blurFlag = ref(false)
138 183
139 watch( 184 watch(
140 () => props.value, 185 () => props.value,
141 - (target) => { 186 + (target: Recordable) => {
142 if (target && isObject(target) && Object.keys(target).length) { 187 if (target && isObject(target) && Object.keys(target).length) {
143 - dataSource.value = Object.keys(props.value || {}).map(keyName => ({ ...createNewRow(), keyName, value: Reflect.get(props.value || {}, keyName) }))  
144 - } else {  
145 - dataSource.value = [createNewRow()]  
146 - } 188 + if (blurFlag.value) return
  189 + dataSource.value = Object.keys(props.value || {}).map((keyName, keyIndex) => ({
  190 + ...createNewRow(),
  191 + keyName,
  192 + indexName: keyIndex,
  193 + typeName: isArray(props.value![keyName]) ? DataTypeEnum.DATA_RANGE : DataTypeEnum.DATA_INPUT,
  194 + value: Reflect.get(props.value || {}, keyName)
  195 + }))
  196 + }
147 }, 197 },
148 { 198 {
149 immediate: true, 199 immediate: true,
@@ -151,10 +201,6 @@ watch( @@ -151,10 +201,6 @@ watch(
151 } 201 }
152 ) 202 )
153 203
154 -const canDeleteRow = computed(() => {  
155 - return unref(dataSource).length >= 2  
156 -})  
157 -  
158 const canAddRow = computed(() => { 204 const canAddRow = computed(() => {
159 return unref(dataSource).length < props.maxRow 205 return unref(dataSource).length < props.maxRow
160 }) 206 })
@@ -174,23 +220,19 @@ const handleSubtractRow = (record: DataSource) => { @@ -174,23 +220,19 @@ const handleSubtractRow = (record: DataSource) => {
174 } 220 }
175 } 221 }
176 222
177 -  
178 -const handleInputBlur = (record: DataSource) => {  
179 - const { keyName, value } = record  
180 - record.result = !!(keyName && value)  
181 - if (unref(dataSource).every(item => item.result)) {  
182 - emit('update:value', getHeaderConfiguration())  
183 - } 223 +const handleInputBlur = () => {
  224 + blurFlag.value = true
  225 + emit('update:value', getHeaderConfiguration())
184 } 226 }
185 227
186 const getHeaderConfiguration = () => { 228 const getHeaderConfiguration = () => {
187 return unref(dataSource).reduce((prev, next) => { 229 return unref(dataSource).reduce((prev, next) => {
188 - const { result, value, keyName } = next  
189 - const header = result && value && keyName ? { [keyName]: value } : {} 230 + const { value, keyName, dateRange } = next
  231 + const header = keyName ? { [keyName as unknown as string]: dateRange && isArray(dateRange) ? dateRange: value } : {}
  232 + for (let item in header) if (!Reflect.get(header, item)) Reflect.deleteProperty(header, item)
190 return { ...prev, ...header } 233 return { ...prev, ...header }
191 }, {} as Recordable) 234 }, {} as Recordable)
192 } 235 }
193 -  
194 </script> 236 </script>
195 237
196 <template> 238 <template>
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -import { RequestDataTypeEnum, RequestDataTypeNameEnum } from '@/enums/external/httpEnum';  
3 -import { useDesign } from '@/hooks/external/useDesign';  
4 -import { CreateComponentType } from '@/packages/index.d';  
5 -import { CreateComponentGroupType } from '@/packages/index.d';  
6 -import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d';  
7 -import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';  
8 -import { NButton, NDivider, NModal, NSpace, NTag } from 'naive-ui';  
9 -import { ref, unref, computed, nextTick } from 'vue';  
10 -import { PublicInterfaceForm } from '../PublicInterfaceForm';  
11 -import ComponentConfiguration from './ComponentConfiguration.vue';  
12 -import GlobalPublicConfiguration from './GlobalPublicConfiguration.vue';  
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';  
17 - 2 +import { RequestDataTypeEnum, RequestDataTypeNameEnum } from '@/enums/external/httpEnum'
  3 +import { useDesign } from '@/hooks/external/useDesign'
  4 +import { CreateComponentType } from '@/packages/index.d'
  5 +import { CreateComponentGroupType } from '@/packages/index.d'
  6 +import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
  7 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  8 +import { NButton, NDivider, NModal, NSpace, NTag } from 'naive-ui'
  9 +import { ref, unref, computed, nextTick } from 'vue'
  10 +import { PublicInterfaceForm } from '../PublicInterfaceForm'
  11 +import ComponentConfiguration from './ComponentConfiguration.vue'
  12 +import GlobalPublicConfiguration from './GlobalPublicConfiguration.vue'
  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'
18 17
19 const requestDataType = ref<RequestDataTypeEnum>(RequestDataTypeEnum.AJAX) 18 const requestDataType = ref<RequestDataTypeEnum>(RequestDataTypeEnum.AJAX)
20 19
@@ -84,12 +83,22 @@ const sendHandle = async () => { @@ -84,12 +83,22 @@ const sendHandle = async () => {
84 targetData.value.option.dataset = value 83 targetData.value.option.dataset = value
85 return 84 return
86 } 85 }
  86 +}
87 87
  88 +const setRequestKey = (value: Recordable, key: string) => {
  89 + value[key] =
  90 + targetData.value.request.requestDataType === RequestDataTypeEnum.AJAX
  91 + ? (targetData.value.request as unknown as Recordable)[key] ||
  92 + (chartEditStore.getRequestGlobalConfig as unknown as Recordable)[key]
  93 + : null
88 } 94 }
89 95
90 const handleSaveAction = async () => { 96 const handleSaveAction = async () => {
91 if (!(await validate())) return 97 if (!(await validate())) return
92 const value = getResult() 98 const value = getResult()
  99 + setRequestKey(value, 'requestTokenSuffix')
  100 + setRequestKey(value, 'requestTokenKey')
  101 + setRequestKey(value, 'requestVerificationToken')
93 if (unref(selectTarget)) { 102 if (unref(selectTarget)) {
94 chartEditStore.updateComponentList(chartEditStore.fetchTargetIndex(), { 103 chartEditStore.updateComponentList(chartEditStore.fetchTargetIndex(), {
95 ...unref(selectTarget)!, 104 ...unref(selectTarget)!,
@@ -105,26 +114,29 @@ createRequestModalContext({ @@ -105,26 +114,29 @@ createRequestModalContext({
105 }) 114 })
106 115
107 defineExpose({ 116 defineExpose({
108 - openModal, 117 + openModal
109 }) 118 })
110 -  
111 </script> 119 </script>
112 120
113 <template> 121 <template>
114 - <NModal :class="prefixCls" v-model:show="showModal" preset="card" style="width: 1000px;" title="请求配置"> 122 + <NModal :class="prefixCls" v-model:show="showModal" preset="card" style="width: 1000px" title="请求配置">
115 <GlobalPublicConfiguration v-if="requestDataType === RequestDataTypeEnum.AJAX" /> 123 <GlobalPublicConfiguration v-if="requestDataType === RequestDataTypeEnum.AJAX" />
116 <NDivider v-if="requestDataType === RequestDataTypeEnum.AJAX" /> 124 <NDivider v-if="requestDataType === RequestDataTypeEnum.AJAX" />
117 <ComponentConfiguration v-if="requestDataType === RequestDataTypeEnum.AJAX" ref="componentConfigurationEl" /> 125 <ComponentConfiguration v-if="requestDataType === RequestDataTypeEnum.AJAX" ref="componentConfigurationEl" />
118 <PublicInterfaceForm v-if="requestDataType === RequestDataTypeEnum.Pond" ref="publicInterfaceFormEl" /> 126 <PublicInterfaceForm v-if="requestDataType === RequestDataTypeEnum.Pond" ref="publicInterfaceFormEl" />
119 <template #action> 127 <template #action>
120 - <NSpace justify="space-between">  
121 - <div style="display: flex;flex-direction: column;">  
122 - <NTag type="info">当公共接口选择“实时轨迹或者获取设备经纬度历史数据”时,属性选择则选择经纬度即可(longitude,latitude)</NTag>  
123 - <div style="height:5px"></div>  
124 - <NTag type="info">如果是结构体属性的话,选择对应结构体属性即可,里面的经纬度,平台已经通过接口里面的过滤函数进行处理</NTag>  
125 - <div style="display: flex; align-items: center; margin-top:10px"> 128 + <NSpace justify="space-between">
  129 + <div style="display: flex; flex-direction: column">
  130 + <NTag type="info"
  131 + >当公共接口选择“实时轨迹或者获取设备经纬度历史数据”时,属性选择则选择经纬度即可(longitude,latitude)</NTag
  132 + >
  133 + <div style="height: 5px"></div>
  134 + <NTag type="info"
  135 + >如果是结构体属性的话,选择对应结构体属性即可,里面的经纬度,平台已经通过接口里面的过滤函数进行处理</NTag
  136 + >
  137 + <div style="display: flex; align-items: center; margin-top: 10px">
126 <span>「 更多 」</span> 138 <span>「 更多 」</span>
127 - <span style="margin-right: 5px;">——</span> 139 + <span style="margin-right: 5px">——</span>
128 <NTag type="info">{{ getRequestTypeName }}</NTag> 140 <NTag type="info">{{ getRequestTypeName }}</NTag>
129 </div> 141 </div>
130 </div> 142 </div>
@@ -134,10 +146,8 @@ defineExpose({ @@ -134,10 +146,8 @@ defineExpose({
134 </NModal> 146 </NModal>
135 </template> 147 </template>
136 148
137 -  
138 -<style lang="scss" > 149 +<style lang="scss">
139 @include thingsKit('chart-data-request') { 150 @include thingsKit('chart-data-request') {
140 -  
141 &.n-card.n-modal, 151 &.n-card.n-modal,
142 .n-card { 152 .n-card {
143 @extend .go-background-filter; 153 @extend .go-background-filter;
@@ -148,7 +158,7 @@ defineExpose({ @@ -148,7 +158,7 @@ defineExpose({
148 } 158 }
149 159
150 @include deep() { 160 @include deep() {
151 - &>.n-card__content { 161 + & > .n-card__content {
152 padding-right: 0; 162 padding-right: 0;
153 } 163 }
154 164
@@ -23,6 +23,9 @@ export interface RequestOptions { @@ -23,6 +23,9 @@ export interface RequestOptions {
23 withToken?: boolean; 23 withToken?: boolean;
24 // Carry and share token 携带分享的访问令牌 24 // Carry and share token 携带分享的访问令牌
25 withShareToken?: boolean 25 withShareToken?: boolean
  26 + withThirdTokenString?: string;
  27 + withThirdTokenKey?: string;
  28 + withThirdTokenPrefix?: string;
26 } 29 }
27 30
28 export interface Result<T = any> { 31 export interface Result<T = any> {