Commit 46909226921fc5fb02fbf9e9b59ed6499c8a8c77

Authored by xp.Huang
2 parents c0a4a0fb cb813ee9

Merge branch 'main_dev' into 'main'

Revert "Merge branch 'perf/view-interface' into 'main_dev'"

See merge request yunteng/thingskit-view!272
Showing 95 changed files with 4775 additions and 549 deletions
@@ -12,3 +12,4 @@ VITE_GLOB_CONTENT_SECURITY_POLICY = false @@ -12,3 +12,4 @@ VITE_GLOB_CONTENT_SECURITY_POLICY = false
12 12
13 # 公共路径 13 # 公共路径
14 VITE_GLOB_PUBLIC_PATH = /large-designer/ 14 VITE_GLOB_PUBLIC_PATH = /large-designer/
  15 +
@@ -4,6 +4,31 @@ import { Plugin } from "vite"; @@ -4,6 +4,31 @@ import { Plugin } from "vite";
4 import { GLOB_CONFIG_FILE_NAME } from "./const"; 4 import { GLOB_CONFIG_FILE_NAME } from "./const";
5 import { getGlobalConfigName } from "./getGlobConfigName"; 5 import { getGlobalConfigName } from "./getGlobConfigName";
6 6
  7 +
  8 +const stringToJSONParse = (string: string) => {
  9 + try {
  10 + return JSON.parse(string);
  11 + } catch (error) {
  12 + return string;
  13 + }
  14 +};
  15 +
  16 +export function parseEnv(env: Record<string, string>) {
  17 + const res: Record<string, string> = {};
  18 +
  19 + Object.keys(env).forEach((key) => {
  20 + try {
  21 + const value = env[key];
  22 + res[key] = stringToJSONParse(value);
  23 + } catch (err) {
  24 + // eslint-disable-next-line no-console
  25 + console.log(`env variable ${key} can't serialization!`);
  26 + }
  27 + });
  28 +
  29 + return res;
  30 +}
  31 +
7 export function GenerateBuildConfig(viteEnv: Record<string, any>) { 32 export function GenerateBuildConfig(viteEnv: Record<string, any>) {
8 return { 33 return {
9 name: 'vite-plugin-generate-global-config', 34 name: 'vite-plugin-generate-global-config',
@@ -15,7 +40,7 @@ export function GenerateBuildConfig(viteEnv: Record<string, any>) { @@ -15,7 +40,7 @@ export function GenerateBuildConfig(viteEnv: Record<string, any>) {
15 try { 40 try {
16 const windowConf = `window.${configName}`; 41 const windowConf = `window.${configName}`;
17 // Ensure that the variable will not be modified 42 // Ensure that the variable will not be modified
18 - const configStr = `${windowConf}=${JSON.stringify(config)}; 43 + const configStr = `${windowConf}=${JSON.stringify(parseEnv(config))};
19 Object.freeze(${windowConf}); 44 Object.freeze(${windowConf});
20 Object.defineProperty(window, "${configName}", { 45 Object.defineProperty(window, "${configName}", {
21 configurable: false, 46 configurable: false,
@@ -159,4 +159,7 @@ export const getAlarmList = (params?: object) => @@ -159,4 +159,7 @@ export const getAlarmList = (params?: object) =>
159 defHttp.get({ 159 defHttp.get({
160 url: Api.ALARM_LIST, 160 url: Api.ALARM_LIST,
161 params 161 params
  162 + },
  163 + {
  164 + withShareToken: true
162 }) 165 })
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 ? 'Bearer': withThirdTokenPrefix
  106 + const tokenKey = withThirdTokenKey ? withThirdTokenKey : 'X-Authorization'
  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 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
7 8
8 export enum ParamsType { 9 export enum ParamsType {
9 REQUIRED, 10 REQUIRED,
@@ -20,7 +21,7 @@ const regDynamicParams = /(?={).+?(?<=})/g @@ -20,7 +21,7 @@ const regDynamicParams = /(?={).+?(?<=})/g
20 21
21 /** 22 /**
22 * @description 判断是否是动态参数 23 * @description 判断是否是动态参数
23 - * @param url 24 + * @param url
24 */ 25 */
25 export const isDynamicUrl = (url: string) => { 26 export const isDynamicUrl = (url: string) => {
26 regDynamicParams.lastIndex = 0 27 regDynamicParams.lastIndex = 0
@@ -29,7 +30,7 @@ export const isDynamicUrl = (url: string) => { @@ -29,7 +30,7 @@ export const isDynamicUrl = (url: string) => {
29 30
30 /** 31 /**
31 * @description 解析动态参数 32 * @description 解析动态参数
32 - * @param url 33 + * @param url
33 */ 34 */
34 export const decomposeDynamicParams = (url: string) => { 35 export const decomposeDynamicParams = (url: string) => {
35 regDynamicParams.lastIndex = 0 36 regDynamicParams.lastIndex = 0
@@ -46,8 +47,8 @@ export const decomposeDynamicParams = (url: string) => { @@ -46,8 +47,8 @@ export const decomposeDynamicParams = (url: string) => {
46 47
47 /** 48 /**
48 * @description 正则替换url中的动态参数 49 * @description 正则替换url中的动态参数
49 - * @param requestUrl  
50 - * @param Params 50 + * @param requestUrl
  51 + * @param Params
51 */ 52 */
52 const getDynamicRequestUrl = (requestUrl = '', Params: Recordable) => { 53 const getDynamicRequestUrl = (requestUrl = '', Params: Recordable) => {
53 requestUrl = decodeURI(requestUrl || '') 54 requestUrl = decodeURI(requestUrl || '')
@@ -101,9 +102,9 @@ const handleParams = (Params: Recordable) => { @@ -101,9 +102,9 @@ const handleParams = (Params: Recordable) => {
101 * 源代码 Params.keys = (Params.keys || [] as any).join(',') 102 * 源代码 Params.keys = (Params.keys || [] as any).join(',')
102 */ 103 */
103 if (!Array.isArray(Params.keys)) { 104 if (!Array.isArray(Params.keys)) {
104 - Params.keys = ([Params.keys] || [] as any).join(',') 105 + Params.keys = ([Params.keys] || ([] as any)).join(',')
105 } else { 106 } else {
106 - Params.keys = (Params.keys || [] as any).join(',') 107 + Params.keys = (Params.keys || ([] as any)).join(',')
107 } 108 }
108 //ft 109 //ft
109 } 110 }
@@ -115,27 +116,43 @@ const handleParams = (Params: Recordable) => { @@ -115,27 +116,43 @@ const handleParams = (Params: Recordable) => {
115 Reflect.deleteProperty(Params, SelectTimeAggregationFieldEnum.TIME_PERIOD) 116 Reflect.deleteProperty(Params, SelectTimeAggregationFieldEnum.TIME_PERIOD)
116 } 117 }
117 118
118 - return Object.keys(Params).filter(Boolean).reduce((prev, next) => ({ ...prev, [next]: Params[next] }), {}) 119 + return Object.keys(Params)
  120 + .filter(Boolean)
  121 + .reduce((prev, next) => ({ ...prev, [next]: Params[next] }), {})
119 } 122 }
120 123
121 //post请求动态追加query参数 124 //post请求动态追加query参数
122 const objConvertQuery = (data: Recordable) => { 125 const objConvertQuery = (data: Recordable) => {
123 - const _result = []; 126 + const _result = []
124 for (const key in data) { 127 for (const key in data) {
125 - const value = data[key]; 128 + const value = data[key]
126 if (value.constructor == Array) { 129 if (value.constructor == Array) {
127 value.forEach(function (_value) { 130 value.forEach(function (_value) {
128 - _result.push(key + "=" + _value);  
129 - }); 131 + _result.push(key + '=' + _value)
  132 + })
130 } else { 133 } else {
131 - _result.push(key + '=' + value); 134 + _result.push(key + '=' + value)
132 } 135 }
133 } 136 }
134 - return _result.join('&'); 137 + return _result.join('&')
135 } 138 }
136 139
137 export const customRequest = async (request: RequestConfigType) => { 140 export const customRequest = async (request: RequestConfigType) => {
138 - const { requestHttpType, requestParams, requestParamsBodyType, requestOriginUrl } = request as ExtraRequestConfigType 141 + const {
  142 + requestHttpType,
  143 + requestParams,
  144 + requestParamsBodyType,
  145 + requestOriginUrl,
  146 + requestVerificationToken,
  147 + pondRequestOriginUrl,
  148 + pondRequestGlobalTokenKey,
  149 + pondRequestGlobalTokenSuffix,
  150 + pondRequestGlobalIsToken
  151 + } = request as ExtraRequestConfigType
  152 + const chartEditStore = useChartEditStore()
  153 +
  154 + const {requestOriginUrl: globalRequestOriginUrl} = chartEditStore.getRequestGlobalConfig
  155 +
139 let { requestUrl } = request as ExtraRequestConfigType 156 let { requestUrl } = request as ExtraRequestConfigType
140 const { Header, Body } = requestParams 157 const { Header, Body } = requestParams
141 let { Params } = requestParams 158 let { Params } = requestParams
@@ -155,18 +172,48 @@ export const customRequest = async (request: RequestConfigType) => { @@ -155,18 +172,48 @@ export const customRequest = async (request: RequestConfigType) => {
155 * 修改后代码 requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl: `${requestUrl}?${objConvertQuery(Params)} 172 * 修改后代码 requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl: `${requestUrl}?${objConvertQuery(Params)}
156 */ 173 */
157 Params = handleParams(Params) 174 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 - }) 175 + return customHttp.request<any>(
  176 + {
  177 + url:
  178 + requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl : `${requestUrl}?${objConvertQuery(Params)}`,
  179 + baseURL: pondRequestGlobalIsToken ? requestVerificationToken ? pondRequestOriginUrl : globalRequestOriginUrl ? globalRequestOriginUrl : getOriginUrl(requestOriginUrl!): pondRequestOriginUrl,
  180 + method: requestHttpType,
  181 + params: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? Params : null,
  182 + data: body,
  183 + headers: extraValue(Header)
  184 + },
  185 + {
  186 + joinPrefix: false,
  187 + apiUrl: '',
  188 + withToken:true,
  189 + withShareToken: !requestVerificationToken ? isShareMode(): false,
  190 + withThirdTokenString: requestVerificationToken,
  191 + withThirdTokenKey: pondRequestGlobalTokenKey,
  192 + withThirdTokenPrefix: pondRequestGlobalTokenSuffix
  193 + }
  194 + )
171 //ft 195 //ft
172 } 196 }
  197 +
  198 +export interface thirdInterfaceRequest {
  199 + requestOriginUrl: string
  200 + body: RequestParamsObjType
  201 +}
  202 +
  203 +//特殊处理第三方接口,一般获取token是POST请求,暂定POST
  204 +export const customThirdInterfaceRequest = async (request: thirdInterfaceRequest) => {
  205 + const { body, requestOriginUrl } = request
  206 +
  207 + return customHttp.request<any>(
  208 + {
  209 + url: requestOriginUrl,
  210 + method: RequestHttpEnum.POST,
  211 + data: body
  212 + },
  213 + {
  214 + joinPrefix: false,
  215 + apiUrl: '',
  216 + withToken: false
  217 + }
  218 + )
  219 +}
@@ -164,12 +164,17 @@ @@ -164,12 +164,17 @@
164 <template #header> 164 <template #header>
165 <n-switch v-model:value="yAxis.show" size="small"></n-switch> 165 <n-switch v-model:value="yAxis.show" size="small"></n-switch>
166 </template> 166 </template>
  167 + <setting-item-box name="范围">
  168 + <setting-item name="开启" >
  169 + <n-switch v-model:value="yAxis.showRange" size="small"></n-switch>
  170 + </setting-item>
  171 + </setting-item-box>
167 <setting-item-box name="范围" v-if="yAxis.showRange"> 172 <setting-item-box name="范围" v-if="yAxis.showRange">
168 <setting-item name="最小值" > 173 <setting-item name="最小值" >
169 - <n-input-number v-model:value="yAxis.min" size="small" min="0"></n-input-number> 174 + <n-input-number v-model:value="yAxis.minData" size="small" min="0"></n-input-number>
170 </setting-item> 175 </setting-item>
171 <setting-item name="最大值"> 176 <setting-item name="最大值">
172 - <n-input-number v-model:value="yAxis.max" size="small" min="0"></n-input-number> 177 + <n-input-number v-model:value="yAxis.maxData" size="small" min="0"></n-input-number>
173 </setting-item> 178 </setting-item>
174 </setting-item-box> 179 </setting-item-box>
175 <setting-item-box name="单位"> 180 <setting-item-box name="单位">
@@ -418,13 +423,6 @@ const xAxis = computed(() => { @@ -418,13 +423,6 @@ const xAxis = computed(() => {
418 }) 423 })
419 424
420 const yAxis = computed(() => { 425 const yAxis = computed(() => {
421 - if((props.optionData?.yAxis as Recordable)){  
422 - if(!(props.optionData?.yAxis as Recordable).showRange) {  
423 - //针对横向柱状图和热力图  
424 - Reflect.deleteProperty((props.optionData.yAxis as Recordable),'min');  
425 - Reflect.deleteProperty((props.optionData.yAxis as Recordable),'max');  
426 - }  
427 - }  
428 return props.optionData.yAxis 426 return props.optionData.yAxis
429 }) 427 })
430 428
1 <template> 1 <template>
2 - <div ref="el" class="go-editor-area" :style="{ width, height }"></div>  
3 - <EditorWorker></EditorWorker> 2 + <div :style="cacheConfigStyle">
  3 + <div ref="el" class="go-editor-area" :style="{ width, height }"></div>
  4 + <EditorWorker></EditorWorker>
  5 + <div style="margin-left:10px;">
  6 + <n-gradient-text type="danger">
  7 + {{ errorText }}
  8 + </n-gradient-text>
  9 +</div>
  10 + </div>
4 </template> 11 </template>
5 12
6 <script lang="ts" setup> 13 <script lang="ts" setup>
7 -import { onMounted, watch, PropType } from 'vue' 14 +import { onMounted, watch, PropType, ref, computed } from 'vue'
8 import { useMonacoEditor } from './index.hook' 15 import { useMonacoEditor } from './index.hook'
9 import { EditorWorker } from './index' 16 import { EditorWorker } from './index'
10 17
@@ -32,7 +39,11 @@ const props = defineProps({ @@ -32,7 +39,11 @@ const props = defineProps({
32 editorOptions: { 39 editorOptions: {
33 type: Object as PropType<object>, 40 type: Object as PropType<object>,
34 default: () => ({}) 41 default: () => ({})
35 - } 42 + },
  43 + config: {
  44 + type: Boolean as PropType<boolean>,
  45 + default: false
  46 + },
36 }) 47 })
37 48
38 const emits = defineEmits(['blur', 'update:modelValue']) 49 const emits = defineEmits(['blur', 'update:modelValue'])
@@ -56,9 +67,30 @@ onMounted(() => { @@ -56,9 +67,30 @@ onMounted(() => {
56 updateMonacoVal() 67 updateMonacoVal()
57 }) 68 })
58 69
  70 +const errorText = ref('')
  71 +
  72 +const cacheConfigStyle = computed(() => {
  73 + const configStyle = {
  74 + display:'flex',
  75 + justifyContent: 'space-between',
  76 + alignItems: 'center'
  77 + }
  78 + return props.config ? configStyle : ''
  79 +})
  80 +
59 watch( 81 watch(
60 () => props.modelValue, 82 () => props.modelValue,
61 (val: string) => { 83 (val: string) => {
  84 + if(props.language === 'json') {
  85 + try {
  86 + const res = JSON.parse(val)
  87 + if(res) {
  88 + errorText.value = ''
  89 + }
  90 + } catch (_) {
  91 + errorText.value = 'JSON格式有误,请仔细检查!'
  92 + }
  93 + }
62 val !== getEditor()?.getValue() && updateMonacoVal(val) 94 val !== getEditor()?.getValue() && updateMonacoVal(val)
63 } 95 }
64 ) 96 )
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 -import Player, { Events, IError } from 'xgplayer';  
3 -import { FlvPlugin } from 'xgplayer-flv';  
4 -import Mp4Plugin from 'xgplayer-mp4';  
5 -import { HlsPlugin } from 'xgplayer-hls';  
6 -import { onMounted, shallowRef, computed, unref, toRaw, onUnmounted, ref, watch } from 'vue';  
7 -import PresetPlayer from 'xgplayer';  
8 -import { IPlayerOptions } from 'xgplayer/es/player';  
9 -import 'xgplayer/dist/index.min.css';  
10 -import { StreamType, XGPlayerProps } from './types';  
11 -import { isShareMode } from "@/views/share/hook";  
12 -import { getJwtToken, getShareJwtToken } from "@/utils/external/auth";  
13 -  
14 -const props = withDefaults(defineProps<{  
15 - streamType?: StreamType;  
16 - autoPlay?: boolean;  
17 - url?: string;  
18 - withToken?: boolean;  
19 - config?: Omit<IPlayerOptions, 'url'>;  
20 -}>(), {  
21 - streamType: 'auto',  
22 - autoPlay: true,  
23 - config: () => ({}),  
24 -}); 2 +import Player, { Events, IError } from 'xgplayer'
  3 +import { FlvPlugin } from 'xgplayer-flv'
  4 +import Mp4Plugin from 'xgplayer-mp4'
  5 +import { HlsPlugin } from 'xgplayer-hls'
  6 +import { onMounted, shallowRef, computed, unref, toRaw, onUnmounted, ref, watch } from 'vue'
  7 +import PresetPlayer from 'xgplayer'
  8 +import { IPlayerOptions } from 'xgplayer/es/player'
  9 +import 'xgplayer/dist/index.min.css'
  10 +import { StreamType, UserActionEventType, XGPlayerProps } from './types'
  11 +import { isShareMode } from '@/views/share/hook'
  12 +import { getJwtToken, getShareJwtToken } from '@/utils/external/auth'
  13 +
  14 +const props = withDefaults(
  15 + defineProps<{
  16 + streamType?: StreamType
  17 + autoPlay?: boolean
  18 + url?: string
  19 + withToken?: boolean
  20 + config?: Omit<IPlayerOptions, 'url'>
  21 + }>(),
  22 + {
  23 + streamType: 'auto',
  24 + autoPlay: true,
  25 + config: () => ({})
  26 + }
  27 +)
25 28
26 const emits = defineEmits<{ 29 const emits = defineEmits<{
27 - (eventName: 'ready', player: PresetPlayer): void;  
28 - (eventName: 'onUnmounted', player: PresetPlayer): void;  
29 -}>(); 30 + (eventName: 'ready', player: PresetPlayer): void
  31 + (eventName: 'userAction', event: UserActionEventType, player: PresetPlayer): void
  32 + (eventName: 'onUnmounted', player: PresetPlayer): void
  33 +}>()
30 34
31 function parsePlayUrl(url: string) { 35 function parsePlayUrl(url: string) {
32 try { 36 try {
33 - return new URL(url).pathname; 37 + return new URL(url).pathname
34 } catch { 38 } catch {
35 - return url; 39 + return url
36 } 40 }
37 } 41 }
38 42
39 function getStreamTypeByUrl(url = ''): StreamType | undefined { 43 function getStreamTypeByUrl(url = ''): StreamType | undefined {
40 url = parsePlayUrl(url) || '' 44 url = parsePlayUrl(url) || ''
41 - if (url.endsWith('.m3u8')) return 'hls';  
42 - else if (url.endsWith('.mp4')) return 'mp4'; 45 + if (url.endsWith('.m3u8')) return 'hls'
  46 + else if (url.endsWith('.mp4')) return 'mp4'
43 else if (url.endsWith('.flv')) { 47 else if (url.endsWith('.flv')) {
44 - return 'flv';  
45 - } else return; 48 + return 'flv'
  49 + } else return
46 } 50 }
47 51
48 const getPluginByStreamType = (): IPlayerOptions => { 52 const getPluginByStreamType = (): IPlayerOptions => {
49 - let { url, withToken } = props;  
50 - let { streamType } = props;  
51 - streamType = streamType === 'auto' ? getStreamTypeByUrl(url)! : streamType; 53 + let { url, withToken } = props
  54 + let { streamType } = props
  55 + streamType = streamType === 'auto' ? getStreamTypeByUrl(url)! : streamType
52 56
53 const liveConfig = { 57 const liveConfig = {
54 targetLatency: 10, 58 targetLatency: 10,
@@ -56,38 +60,38 @@ const getPluginByStreamType = (): IPlayerOptions => { @@ -56,38 +60,38 @@ const getPluginByStreamType = (): IPlayerOptions => {
56 disconnectTime: 0, 60 disconnectTime: 0,
57 fetchOptions: withToken 61 fetchOptions: withToken
58 ? { 62 ? {
59 - headers: {  
60 - 'X-Authorization': `Bearer ${isShareMode() ? getShareJwtToken() : getJwtToken()}`,  
61 - },  
62 - }  
63 - : {},  
64 - }; 63 + headers: {
  64 + 'X-Authorization': `Bearer ${isShareMode() ? getShareJwtToken() : getJwtToken()}`
  65 + }
  66 + }
  67 + : {}
  68 + }
65 const config: IPlayerOptions = { 69 const config: IPlayerOptions = {
66 flv: liveConfig, 70 flv: liveConfig,
67 - hls: liveConfig,  
68 - }; 71 + hls: liveConfig
  72 + }
69 switch (streamType) { 73 switch (streamType) {
70 case 'hls': 74 case 'hls':
71 - config.plugins = [HlsPlugin];  
72 - break; 75 + config.plugins = [HlsPlugin]
  76 + break
73 case 'mp4': 77 case 'mp4':
74 - config.plugins = [Mp4Plugin];  
75 - break; 78 + config.plugins = [Mp4Plugin]
  79 + break
76 case 'flv': 80 case 'flv':
77 - config.plugins = [FlvPlugin];  
78 - break; 81 + config.plugins = [FlvPlugin]
  82 + break
79 } 83 }
80 - return config;  
81 -}; 84 + return config
  85 +}
82 86
83 -const videoElRef = shallowRef<Nullable<HTMLDivElement>>(); 87 +const videoElRef = shallowRef<Nullable<HTMLDivElement>>()
84 88
85 -const playerRef = shallowRef<Nullable<PresetPlayer>>(); 89 +const playerRef = shallowRef<Nullable<PresetPlayer>>()
86 90
87 -const propsRef = ref<XGPlayerProps>({}); 91 +const propsRef = ref<XGPlayerProps>({})
88 92
89 const getPlayerConfig = computed<IPlayerOptions>(() => { 93 const getPlayerConfig = computed<IPlayerOptions>(() => {
90 - const { url, autoPlay, config } = props; 94 + const { url, autoPlay, config } = props
91 95
92 const basicConfig: IPlayerOptions = { 96 const basicConfig: IPlayerOptions = {
93 ...config, 97 ...config,
@@ -97,79 +101,83 @@ const getPlayerConfig = computed<IPlayerOptions>(() => { @@ -97,79 +101,83 @@ const getPlayerConfig = computed<IPlayerOptions>(() => {
97 isLive: true, 101 isLive: true,
98 autoplay: autoPlay, 102 autoplay: autoPlay,
99 autoplayMuted: autoPlay, 103 autoplayMuted: autoPlay,
100 - ...getPluginByStreamType(),  
101 - };  
102 - return basicConfig;  
103 -}); 104 + ...getPluginByStreamType()
  105 + }
  106 + return basicConfig
  107 +})
104 108
105 function onDecodeError() { 109 function onDecodeError() {
106 - console.warn('player happend decode error');  
107 - playerRef.value?.switchURL(props.url!); 110 + console.warn('player happend decode error')
  111 + playerRef.value?.switchURL(props.url!)
108 } 112 }
109 113
110 function initializePlayer() { 114 function initializePlayer() {
111 if (unref(playerRef)) { 115 if (unref(playerRef)) {
112 - playerRef.value?.destroy?.();  
113 - playerRef.value = null; 116 + playerRef.value?.destroy?.()
  117 + playerRef.value = null
114 } 118 }
115 119
116 - const config = toRaw(unref(getPlayerConfig)); 120 + const config = toRaw(unref(getPlayerConfig))
117 121
118 - if (!unref(videoElRef)) return; 122 + if (!unref(videoElRef)) return
119 123
120 - const player = (playerRef.value = new Player(Object.assign(config, { el: unref(videoElRef) }))); 124 + const player = (playerRef.value = new Player(Object.assign(config, { el: unref(videoElRef) })))
121 125
122 player.on(Events.READY, () => { 126 player.on(Events.READY, () => {
123 - emits('ready', player);  
124 - }); 127 + emits('ready', player)
  128 + })
  129 +
  130 + player.on(Events.USER_ACTION, (event: UserActionEventType) => {
  131 + emits('userAction', event, player)
  132 + })
125 133
126 player.setEventsMiddleware({ 134 player.setEventsMiddleware({
127 error: (event, callback) => { 135 error: (event, callback) => {
128 const code = ( 136 const code = (
129 event as unknown as { 137 event as unknown as {
130 - error: MediaError; 138 + error: MediaError
131 } 139 }
132 - ).error.code; 140 + ).error.code
133 if (code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) { 141 if (code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) {
134 if (!props.url) { 142 if (!props.url) {
135 - return; 143 + return
136 } 144 }
137 - callback();  
138 - return; 145 + callback()
  146 + return
139 } 147 }
140 148
141 if (code === MediaError.MEDIA_ERR_DECODE) { 149 if (code === MediaError.MEDIA_ERR_DECODE) {
142 // 视频流可以播放 中途解码失败重载 150 // 视频流可以播放 中途解码失败重载
143 if (playerRef.value?.isPlaying) { 151 if (playerRef.value?.isPlaying) {
144 - onDecodeError(); 152 + onDecodeError()
145 } 153 }
146 - return; 154 + return
147 } 155 }
148 156
149 - callback();  
150 - },  
151 - }); 157 + callback()
  158 + }
  159 + })
152 } 160 }
153 161
154 onMounted(() => { 162 onMounted(() => {
155 - initializePlayer();  
156 -}); 163 + initializePlayer()
  164 +})
157 165
158 onUnmounted(() => { 166 onUnmounted(() => {
159 - emits('onUnmounted', unref(playerRef)!);  
160 - playerRef.value?.destroy?.();  
161 -}); 167 + emits('onUnmounted', unref(playerRef)!)
  168 + playerRef.value?.destroy?.()
  169 +})
162 170
163 watch( 171 watch(
164 () => props.url, 172 () => props.url,
165 () => { 173 () => {
166 - initializePlayer(); 174 + initializePlayer()
167 } 175 }
168 -); 176 +)
169 177
170 defineExpose({ 178 defineExpose({
171 - getPlayerInstance: () => unref(playerRef),  
172 -}); 179 + getPlayerInstance: () => unref(playerRef)
  180 +})
173 </script> 181 </script>
174 182
175 <template> 183 <template>
1 -import { IPlayerOptions } from 'xgplayer/es/player'; 1 +import { IPlayerOptions } from 'xgplayer/es/player'
2 2
3 -export type StreamType = 'flv' | 'mp4' | 'hls' | 'auto'; 3 +export type StreamType = 'flv' | 'mp4' | 'hls' | 'auto'
4 export interface XGPlayerProps { 4 export interface XGPlayerProps {
5 - streamType?: StreamType;  
6 - autoPlay?: boolean;  
7 - url?: string;  
8 - withToken?: boolean;  
9 - config?: Omit<IPlayerOptions, 'url'>; 5 + streamType?: StreamType
  6 + autoPlay?: boolean
  7 + url?: string
  8 + withToken?: boolean
  9 + config?: Omit<IPlayerOptions, 'url'>
  10 +}
  11 +
  12 +export interface UserActionEventType {
  13 + action: string // 用户行为
  14 + pluginName: string // 从哪个插件触发
  15 + props: [
  16 + {
  17 + // 发生变化的属性列表
  18 + props: string // 发生变化的属性
  19 + from: any // 变化前的值
  20 + to: any // 变化后的值
  21 + }
  22 + ]
  23 + event: Event // 事件
  24 + currentTime: number // 当前播放时间
  25 + duration: number // 当前播放器时长
  26 + ended: boolean // 是否播放结束
  27 + paused: boolean // 是否暂停
  28 + from?: boolean
  29 + to?: boolean
10 } 30 }
  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 +}
@@ -25,7 +25,8 @@ export enum RequestContentTypeEnum { @@ -25,7 +25,8 @@ export enum RequestContentTypeEnum {
25 // 普通请求 25 // 普通请求
26 DEFAULT = 0, 26 DEFAULT = 0,
27 // SQL请求 27 // SQL请求
28 - SQL = 1 28 + SQL = 1,
  29 + WEB_SOCKET
29 } 30 }
30 31
31 /** 32 /**
@@ -10,7 +10,7 @@ export const useGlobSetting = (): Readonly<GlobConfig> => { @@ -10,7 +10,7 @@ export const useGlobSetting = (): Readonly<GlobConfig> => {
10 VITE_GLOB_UPLOAD_URL, 10 VITE_GLOB_UPLOAD_URL,
11 VITE_GLOB_WEB_SOCKET, 11 VITE_GLOB_WEB_SOCKET,
12 VITE_GLOB_CONTENT_SECURITY_POLICY, 12 VITE_GLOB_CONTENT_SECURITY_POLICY,
13 - VITE_GLOB_PUBLIC_PATH 13 + VITE_GLOB_PUBLIC_PATH,
14 } = getAppEnvConfig(); 14 } = getAppEnvConfig();
15 15
16 if (!/[a-zA-Z_]*/.test(VITE_GLOB_APP_SHORT_NAME)) { 16 if (!/[a-zA-Z_]*/.test(VITE_GLOB_APP_SHORT_NAME)) {
@@ -28,7 +28,7 @@ export const useGlobSetting = (): Readonly<GlobConfig> => { @@ -28,7 +28,7 @@ export const useGlobSetting = (): Readonly<GlobConfig> => {
28 uploadUrl: VITE_GLOB_UPLOAD_URL, 28 uploadUrl: VITE_GLOB_UPLOAD_URL,
29 socketUrl: VITE_GLOB_WEB_SOCKET, 29 socketUrl: VITE_GLOB_WEB_SOCKET,
30 securityPolicy: VITE_GLOB_CONTENT_SECURITY_POLICY, 30 securityPolicy: VITE_GLOB_CONTENT_SECURITY_POLICY,
31 - publicPath: VITE_GLOB_PUBLIC_PATH 31 + publicPath: VITE_GLOB_PUBLIC_PATH,
32 }; 32 };
33 33
34 return glob as Readonly<GlobConfig>; 34 return glob as Readonly<GlobConfig>;
1 import {ref, toRefs, toRaw, watch} from 'vue' 1 import {ref, toRefs, toRaw, watch} from 'vue'
2 import type VChart from 'vue-echarts' 2 import type VChart from 'vue-echarts'
3 -import {useChartDataPondFetch} from '@/hooks/'  
4 import {CreateComponentType, ChartFrameEnum, CreateComponentGroupType} from '@/packages/index.d' 3 import {CreateComponentType, ChartFrameEnum, CreateComponentGroupType} from '@/packages/index.d'
5 import {useChartEditStore} from '@/store/modules/chartEditStore/chartEditStore' 4 import {useChartEditStore} from '@/store/modules/chartEditStore/chartEditStore'
6 import {isPreview, intervalUnitHandle} from '@/utils' 5 import {isPreview, intervalUnitHandle} from '@/utils'
7 import {setOption} from '@/packages/public/chart' 6 import {setOption} from '@/packages/public/chart'
8 import {useChartDataSocket} from './useChartDataSocket' 7 import {useChartDataSocket} from './useChartDataSocket'
9 -import {customRequest} from '@/api/external/customRequest' 8 +import {customRequest, customThirdInterfaceRequest, thirdInterfaceRequest} from '@/api/external/customRequest'
10 import {useFilterFn} from './useFilterFn' 9 import {useFilterFn} from './useFilterFn'
11 import {RequestContentTypeEnum} from '@/enums/external/httpEnum' 10 import {RequestContentTypeEnum} from '@/enums/external/httpEnum'
12 import dayjs from 'dayjs' 11 import dayjs from 'dayjs'
  12 +import { RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
  13 +import { JSONParse, convertToCascadingData, findItemByLabel } from '@/utils/external/utils'
  14 +import { CascaderOption } from 'naive-ui'
  15 +import { useUserStore } from '@/store/external/modules/user'
13 16
14 17
15 // 获取类型 18 // 获取类型
@@ -40,7 +43,8 @@ export const useChartDataFetch = ( @@ -40,7 +43,8 @@ export const useChartDataFetch = (
40 } 43 }
41 } 44 }
42 } 45 }
43 - 46 +
  47 + // 单个组件请求
44 const requestIntervalFn = () => { 48 const requestIntervalFn = () => {
45 const chartEditStore = useChartEditStore() 49 const chartEditStore = useChartEditStore()
46 if ((targetComponent.request.requestContentType as RequestContentTypeEnum) === RequestContentTypeEnum.WEB_SOCKET) return 50 if ((targetComponent.request.requestContentType as RequestContentTypeEnum) === RequestContentTypeEnum.WEB_SOCKET) return
@@ -52,6 +56,12 @@ export const useChartDataFetch = ( @@ -52,6 +56,12 @@ export const useChartDataFetch = (
52 requestInterval: globalRequestInterval 56 requestInterval: globalRequestInterval
53 } = toRefs(chartEditStore.getRequestGlobalConfig) 57 } = toRefs(chartEditStore.getRequestGlobalConfig)
54 58
  59 + // 公共配置
  60 + const {
  61 + pondRequestGlobalInterval,
  62 + pondRequestGlobalIntervalUnit
  63 + } = toRefs(targetComponent.request)
  64 +
55 // 目标组件 65 // 目标组件
56 const { 66 const {
57 requestUrl, 67 requestUrl,
@@ -92,11 +102,55 @@ export const useChartDataFetch = ( @@ -92,11 +102,55 @@ export const useChartDataFetch = (
92 (toRaw(targetComponent.request).requestParams.Params.startTs as unknown as number) = startTs as unknown as number 102 (toRaw(targetComponent.request).requestParams.Params.startTs as unknown as number) = startTs as unknown as number
93 (toRaw(targetComponent.request).requestParams.Params.endTs as unknown as number) = endTs as unknown as number 103 (toRaw(targetComponent.request).requestParams.Params.endTs as unknown as number) = endTs as unknown as number
94 } 104 }
  105 + //处理过期
  106 + const userStore = useUserStore();
  107 + const findCurrentPond = () => {
  108 + return chartEditStore.getRequestGlobalConfig.requestDataPond.find((pondItem: RequestDataPondItemType) =>
  109 + pondItem.dataPondId === targetComponent?.request?.requestDataPondId && userStore.getThirdTokenIsExp)
  110 + }
  111 + const handleExecuteRequest = async () => {
  112 + try {
  113 + if(findCurrentPond()?.dataPondRequestConfig?.pondRequestOriginUrl){
  114 + const originUrlString = findCurrentPond()?.dataPondRequestConfig?.pondRequestOriginUrl
  115 + const requestUrlString = findCurrentPond()?.dataPondRequestConfig?.pondRequestUrl
  116 + const body = findCurrentPond()?.dataPondRequestConfig?.pondRequestParams!['Body']['json']
  117 + const request = {
  118 + requestOriginUrl: `${originUrlString}${requestUrlString}`,
  119 + body
  120 + }
  121 + const res = await customThirdInterfaceRequest(request as unknown as thirdInterfaceRequest)
  122 + const resOptions = convertToCascadingData(res) as unknown as CascaderOption[]
  123 + const findLabel = findItemByLabel(resOptions, targetComponent.request.thirdSelectCascaderLabel as string)
  124 + if(findLabel) {
  125 + targetComponent.request.requestVerificationToken = findLabel?.value
  126 + }
  127 + }
  128 + } catch (e) {
  129 + console.error(e)
  130 + }
  131 + }
  132 + // 定时时间
  133 + const time = targetInterval && targetInterval.value ? targetInterval.value : pondRequestGlobalInterval?.value?pondRequestGlobalInterval?.value: globalRequestInterval.value
  134 + // 单位
  135 + const unit = targetInterval && targetInterval.value ? targetUnit.value :pondRequestGlobalIntervalUnit?.value?pondRequestGlobalIntervalUnit?.value: globalUnit.value
  136 + setInterval(handleExecuteRequest, intervalUnitHandle(time, (unit as unknown as any)))
  137 + //
95 const res = await customRequest(toRaw(targetComponent.request)) 138 const res = await customRequest(toRaw(targetComponent.request))
96 if (res) { 139 if (res) {
97 try { 140 try {
98 const filter = targetComponent.filter 141 const filter = targetComponent.filter
99 const {value} = useFilterFn(filter, res) 142 const {value} = useFilterFn(filter, res)
  143 + //分组更新下面子组件
  144 + if(targetComponent.isGroup) {
  145 + const parseHistoryInput = JSONParse(targetComponent.saveHistoryInput!)
  146 + parseHistoryInput?.forEach((historyItem:Recordable) => {
  147 + const findCurrentItem = targetComponent.groupList?.find((groupItem:CreateComponentType | CreateComponentGroupType) => groupItem.id === historyItem.id)
  148 + if(findCurrentItem) {
  149 + findCurrentItem.option.dataset = value[historyItem.inputValue]
  150 + }
  151 + })
  152 + }
  153 + //
100 echartsUpdateHandle(value) 154 echartsUpdateHandle(value)
101 // 更新回调函数 155 // 更新回调函数
102 if (updateCallback) { 156 if (updateCallback) {
@@ -119,13 +173,14 @@ export const useChartDataFetch = ( @@ -119,13 +173,14 @@ export const useChartDataFetch = (
119 deep: true 173 deep: true
120 } 174 }
121 ) 175 )
122 -  
123 // 定时时间 176 // 定时时间
124 - const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value 177 + const time = targetInterval && targetInterval.value ? targetInterval.value : pondRequestGlobalInterval?.value?pondRequestGlobalInterval?.value: globalRequestInterval.value
125 // 单位 178 // 单位
126 - const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value 179 + const unit = targetInterval && targetInterval.value ? targetUnit.value :pondRequestGlobalIntervalUnit?.value?pondRequestGlobalIntervalUnit?.value: globalUnit.value
127 // 开启轮询 180 // 开启轮询
128 - if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit)) 181 + if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, (unit as unknown as any)))
  182 +
  183 +
129 } 184 }
130 // eslint-disable-next-line no-empty 185 // eslint-disable-next-line no-empty
131 } catch (error) { 186 } catch (error) {
@@ -140,11 +195,12 @@ export const useChartDataFetch = ( @@ -140,11 +195,12 @@ export const useChartDataFetch = (
140 /** 195 /**
141 * 支持分组也可以接受ws 196 * 支持分组也可以接受ws
142 * 如果是分组并且绑定了ws 197 * 如果是分组并且绑定了ws
  198 + * 也支持http轮询
143 */ 199 */
144 chartEditStore.getComponentList?.forEach((item: CreateComponentType | CreateComponentGroupType) => { 200 chartEditStore.getComponentList?.forEach((item: CreateComponentType | CreateComponentGroupType) => {
145 if (item.isGroup) { 201 if (item.isGroup) {
146 if (item.request.requestUrl?.includes('ws')) { 202 if (item.request.requestUrl?.includes('ws')) {
147 - initial(item, useChartEditStore, updateCallback) 203 + initial(item, useChartEditStore, updateCallback) // ws
148 } 204 }
149 } 205 }
150 }) 206 })
@@ -2,8 +2,9 @@ @@ -2,8 +2,9 @@
2 * 重写select下拉框联动 2 * 重写select下拉框联动
3 */ 3 */
4 import { toRefs } from 'vue' 4 import { toRefs } from 'vue'
5 -import { CreateComponentType } from '@/packages/index.d' 5 +import { CreateComponentType } from '@/packages/index.d'
6 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 6 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  7 +import { JSONParse } from '@/utils/external/utils'
7 8
8 // 获取类型 9 // 获取类型
9 type ChartEditStoreType = typeof useChartEditStore 10 type ChartEditStoreType = typeof useChartEditStore
@@ -32,9 +33,19 @@ export const useChartInteract = ( @@ -32,9 +33,19 @@ export const useChartInteract = (
32 chartEditStore.getComponentList.forEach(targetItem => { 33 chartEditStore.getComponentList.forEach(targetItem => {
33 if (targetItem.isGroup) { 34 if (targetItem.isGroup) {
34 targetItem.groupList?.forEach(groupItem => { 35 targetItem.groupList?.forEach(groupItem => {
  36 + let jsonBody: any = null
35 if (groupItem.id === item.interactComponentId) { 37 if (groupItem.id === item.interactComponentId) {
36 - const { Params, Header } = toRefs(groupItem.request.requestParams) 38 + const { Params, Header, Body } = toRefs(groupItem.request.requestParams)
37 Object.keys(item.interactFn).forEach(key => { 39 Object.keys(item.interactFn).forEach(key => {
  40 + if (Body.value['json']) {
  41 + jsonBody = JSONParse(Body.value['json'])
  42 + const splitDaterange = param['daterange'].split('-')
  43 + jsonBody[item.interactFn[key][0]] = decodeURIComponent(splitDaterange[0])
  44 + jsonBody[item.interactFn[key][1]] = decodeURIComponent(splitDaterange[1])
  45 + }
  46 + if (jsonBody) {
  47 + Body.value['json'] = JSON.stringify(jsonBody)
  48 + }
38 if (Params.value[key]) { 49 if (Params.value[key]) {
39 Params.value[key] = param[item.interactFn[key]] 50 Params.value[key] = param[item.interactFn[key]]
40 } 51 }
@@ -45,9 +56,19 @@ export const useChartInteract = ( @@ -45,9 +56,19 @@ export const useChartInteract = (
45 } 56 }
46 }) 57 })
47 } else { 58 } else {
  59 + let jsonBody: any = null
48 if (targetItem.id === item.interactComponentId) { 60 if (targetItem.id === item.interactComponentId) {
49 - const { Params, Header } = toRefs(targetItem.request.requestParams) 61 + const { Params, Header, Body } = toRefs(targetItem.request.requestParams)
50 Object.keys(item.interactFn).forEach(key => { 62 Object.keys(item.interactFn).forEach(key => {
  63 + if (Body.value['json']) {
  64 + jsonBody = JSONParse(Body.value['json'])
  65 + const splitDaterange = param['daterange'].split('-')
  66 + jsonBody[item.interactFn[key][0]] = decodeURIComponent(splitDaterange[0])
  67 + jsonBody[item.interactFn[key][1]] = decodeURIComponent(splitDaterange[1])
  68 + }
  69 + if (jsonBody) {
  70 + Body.value['json'] = JSON.stringify(jsonBody)
  71 + }
51 if (Params.value[key]) { 72 if (Params.value[key]) {
52 Params.value[key] = param[item.interactFn[key]] 73 Params.value[key] = param[item.interactFn[key]]
53 } 74 }
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 import { toRefs } from 'vue' 4 import { toRefs } from 'vue'
5 import { CreateComponentType } from '@/packages/index.d' 5 import { CreateComponentType } from '@/packages/index.d'
6 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 6 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  7 +import { JSONParse } from '@/utils'
7 8
8 // 获取类型 9 // 获取类型
9 type ChartEditStoreType = typeof useChartEditStore 10 type ChartEditStoreType = typeof useChartEditStore
@@ -33,21 +34,38 @@ export const useChartInteract = ( @@ -33,21 +34,38 @@ export const useChartInteract = (
33 if (targetItem.isGroup) { 34 if (targetItem.isGroup) {
34 targetItem.groupList?.forEach(groupItem => { 35 targetItem.groupList?.forEach(groupItem => {
35 if (groupItem.id === item.interactComponentId) { 36 if (groupItem.id === item.interactComponentId) {
36 - const { Params, Header } = toRefs(groupItem.request.requestParams)  
37 - Object.keys(item.interactFn).forEach(key => {  
38 - Params.value[key] = decodeURIComponent(param[item.interactFn[key]])  
39 - if(Reflect.has(Params.value, 'attrName')) {  
40 - Params.value['attrName'] = attrNames as unknown as string // 修改联动选择,lengend未实时更新  
41 - }  
42 - if (key in Header.value) {  
43 - Header.value[key] = param[item.interactFn[key]] 37 + const { Params, Header, Body } = toRefs(groupItem.request.requestParams)
  38 + //特殊处理 只针对两个下拉选择器,一个是产品下拉,一个是设备下拉,选择了产品,设备列表选择值清空
  39 + if (targetItem.chartConfig.title.includes('设备列表下拉选择器')) {
  40 + if (window.location.href.includes('preview')) {
  41 + if (window.sessionStorage.getItem('deviceProfileSelectStatus') === 'selected') {
  42 + targetItem.option.selectValue = "'"
44 } 43 }
  44 + }
  45 + }
  46 + //
  47 + let jsonBody: any = null
  48 + Object.keys(item.interactFn).forEach(key => {
  49 + Params.value[key] = decodeURIComponent(param[item.interactFn[key]])
  50 + if (Body.value['json']) {
  51 + jsonBody = JSONParse(Body.value['json'])
  52 + jsonBody[item.interactFn[key]] = decodeURIComponent(param['data'])
  53 + }
  54 + if (jsonBody) {
  55 + Body.value['json'] = JSON.stringify(jsonBody)
  56 + }
  57 + if (Reflect.has(Params.value, 'attrName')) {
  58 + Params.value['attrName'] = attrNames as unknown as string // 修改联动选择,lengend未实时更新
  59 + }
  60 + if (key in Header.value) {
  61 + Header.value[key] = param[item.interactFn[key]]
  62 + }
45 }) 63 })
46 } 64 }
47 }) 65 })
48 } else { 66 } else {
49 if (targetItem.id === item.interactComponentId) { 67 if (targetItem.id === item.interactComponentId) {
50 - const { Params, Header } = toRefs(targetItem.request.requestParams) 68 + const { Params, Header, Body } = toRefs(targetItem.request.requestParams)
51 //特殊处理 只针对两个下拉选择器,一个是产品下拉,一个是设备下拉,选择了产品,设备列表选择值清空 69 //特殊处理 只针对两个下拉选择器,一个是产品下拉,一个是设备下拉,选择了产品,设备列表选择值清空
52 if (targetItem.chartConfig.title.includes('设备列表下拉选择器')) { 70 if (targetItem.chartConfig.title.includes('设备列表下拉选择器')) {
53 if (window.location.href.includes('preview')) { 71 if (window.location.href.includes('preview')) {
@@ -57,14 +75,22 @@ export const useChartInteract = ( @@ -57,14 +75,22 @@ export const useChartInteract = (
57 } 75 }
58 } 76 }
59 // 77 //
  78 + let jsonBody: any = null
60 Object.keys(item.interactFn).forEach(key => { 79 Object.keys(item.interactFn).forEach(key => {
61 - Params.value[key] = decodeURIComponent(param[item.interactFn[key]])  
62 - if(Reflect.has(Params.value, 'attrName')) {  
63 - Params.value['attrName'] = attrNames as unknown as string // 修改联动选择,lengend未实时更新  
64 - }  
65 - if (key in Header.value) {  
66 - Header.value[key] = param[item.interactFn[key]]  
67 - } 80 + Params.value[key] = decodeURIComponent(param[item.interactFn[key]])
  81 + if (Body.value['json']) {
  82 + jsonBody = JSONParse(Body.value['json'])
  83 + jsonBody[item.interactFn[key]] = decodeURIComponent(param['data'])
  84 + }
  85 + if (jsonBody) {
  86 + Body.value['json'] = JSON.stringify(jsonBody)
  87 + }
  88 + if (Reflect.has(Params.value, 'attrName')) {
  89 + Params.value['attrName'] = attrNames as unknown as string // 修改联动选择,lengend未实时更新
  90 + }
  91 + if (key in Header.value) {
  92 + Header.value[key] = param[item.interactFn[key]]
  93 + }
68 }) 94 })
69 } 95 }
70 } 96 }
@@ -12,17 +12,18 @@ export const useFetchTargetData = () => { @@ -12,17 +12,18 @@ export const useFetchTargetData = () => {
12 const fetchTargetData = async () => { 12 const fetchTargetData = async () => {
13 const { targetData } = useTargetData() 13 const { targetData } = useTargetData()
14 if (unref(targetData).request.requestDataType === RequestDataTypeEnum.STATIC) return 14 if (unref(targetData).request.requestDataType === RequestDataTypeEnum.STATIC) return
  15 + if (!unref(targetData).request.requestUrl) return
15 loading.value = true 16 loading.value = true
16 try { 17 try {
17 - const isSocketType = (targetData.value.request.requestContentType as RequestContentTypeEnum) === RequestContentTypeEnum.WEB_SOCKET  
18 - const res = isSocketType  
19 - ? await sendMessage(unref(targetData) as CreateComponentType)  
20 - : await customRequest(toRaw(targetData.value.request))  
21 -  
22 - if (res) {  
23 - return res  
24 - }  
25 - window['$message'].warning('没有拿到返回值,请检查接口!') 18 + const isSocketType = (targetData.value.request.requestContentType as RequestContentTypeEnum) === RequestContentTypeEnum.WEB_SOCKET
  19 + const res = isSocketType
  20 + ? await sendMessage(unref(targetData) as CreateComponentType)
  21 + : await customRequest(toRaw(targetData.value.request))
  22 +
  23 + if (res) {
  24 + return res
  25 + }
  26 + window['$message'].warning('没有拿到返回值,请检查接口!')
26 } catch (error) { 27 } catch (error) {
27 loading.value = false 28 loading.value = false
28 console.error(error); 29 console.error(error);
  1 +/**
  2 + * 此hook用于获取物模型
  3 + * @param entityId 设备id
  4 + * @returns
  5 + */
  6 +
  7 +import { getAttribute, getDeviceDetail } from '@/api/external/common'
  8 +
  9 +export function useTsl() {
  10 + const handleDeviceProfileAttributes = async (entityId: string) => {
  11 + const deviceDetailRes = await getDeviceDetail(entityId)
  12 + const { deviceProfileId } = deviceDetailRes
  13 + if (!deviceProfileId) return
  14 + const attributeRes = await getAttribute(deviceProfileId)
  15 + const dataFormat = handleDataFormat(deviceDetailRes, attributeRes)
  16 + return dataFormat
  17 + }
  18 +
  19 + const handleDataFormat = (deviceDetail: Recordable, attributes: Recordable[]) => {
  20 + const { name, tbDeviceId } = deviceDetail
  21 + const attribute = attributes.map((item: Recordable) => ({
  22 + identifier: item.identifier,
  23 + name: item.name,
  24 + detail: item.detail
  25 + }))
  26 + return {
  27 + name,
  28 + tbDeviceId,
  29 + attribute
  30 + }
  31 + }
  32 +
  33 + return {
  34 + handleDeviceProfileAttributes
  35 + }
  36 +}
@@ -6,8 +6,7 @@ let initialFlag = false; @@ -6,8 +6,7 @@ let initialFlag = false;
6 export function useWebSecurityPolicy() { 6 export function useWebSecurityPolicy() {
7 if (window && window.document && window.document.documentElement) { 7 if (window && window.document && window.document.documentElement) {
8 const { securityPolicy } = useGlobSetting(); 8 const { securityPolicy } = useGlobSetting();
9 - const flag = isBoolean(securityPolicy) ? securityPolicy : securityPolicy === 'true'  
10 - if (flag && !initialFlag) { 9 + if (securityPolicy && !initialFlag) {
11 const meta = document.createElement('meta'); 10 const meta = document.createElement('meta');
12 meta.setAttribute('http-equiv', 'Content-Security-Policy'); 11 meta.setAttribute('http-equiv', 'Content-Security-Policy');
13 meta.setAttribute('content', 'upgrade-insecure-requests'); 12 meta.setAttribute('content', 'upgrade-insecure-requests');
@@ -129,7 +129,7 @@ const props = defineProps({ @@ -129,7 +129,7 @@ const props = defineProps({
129 129
130 const header = ref() 130 const header = ref()
131 const median = ref<string[]>([]) 131 const median = ref<string[]>([])
132 -props.optionData.dataset.dimensions.forEach(item => { 132 +props.optionData.dataset?.dimensions?.forEach(item => {
133 median.value.push(item.title) 133 median.value.push(item.title)
134 }) 134 })
135 135
@@ -138,7 +138,7 @@ watch( @@ -138,7 +138,7 @@ watch(
138 () => props.optionData, 138 () => props.optionData,
139 () => { 139 () => {
140 median.value = [] 140 median.value = []
141 - props.optionData.dataset.dimensions.forEach(item => { 141 + props.optionData.dataset.dimensions?.forEach(item => {
142 median.value.push(item.title) 142 median.value.push(item.title)
143 }) 143 })
144 header.value = median.value.toString() 144 header.value = median.value.toString()
@@ -153,8 +153,10 @@ watch( @@ -153,8 +153,10 @@ watch(
153 watch([header], ([headerNew], [headerOld]) => { 153 watch([header], ([headerNew], [headerOld]) => {
154 if (headerNew !== headerOld) { 154 if (headerNew !== headerOld) {
155 headerNew.split(',').forEach((item: string, index: number) => { 155 headerNew.split(',').forEach((item: string, index: number) => {
156 - if (index + 1 <= props.optionData.dataset.dimensions.length) {  
157 - props.optionData.dataset.dimensions[index].title = headerNew.split(',')[index] 156 + if(props.optionData.dataset?.dimensions) {
  157 + if (index + 1 <= props.optionData.dataset.dimensions.length) {
  158 + props.optionData.dataset.dimensions[index].title = headerNew.split(',')[index]
  159 + }
158 } 160 }
159 }) 161 })
160 } 162 }
@@ -62,6 +62,8 @@ const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSe @@ -62,6 +62,8 @@ const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSe
62 62
63 const { queryCondition } = toRefs(props.chartConfig.option) 63 const { queryCondition } = toRefs(props.chartConfig.option)
64 64
  65 +const { limit, startTs, endTs, interval, agg } = toRefs(props.chartConfig.request.requestParams.Params)
  66 +
65 use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent]) 67 use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent])
66 68
67 const chartEditStore = useChartEditStore() 69 const chartEditStore = useChartEditStore()
@@ -286,6 +288,23 @@ const handleAggChange = (value: string) => { @@ -286,6 +288,23 @@ const handleAggChange = (value: string) => {
286 } 288 }
287 289
288 onMounted(() => { 290 onMounted(() => {
  291 + if (Reflect.get(props.chartConfig.request.requestParams.Params, 'startTs')) {
  292 + queryCondition.value.timeRange[0] = startTs.value
  293 + getPacketIntervalByRange(queryCondition.value.timeRange)
  294 + }
  295 + if (Reflect.get(props.chartConfig.request.requestParams.Params, 'endTs')) {
  296 + queryCondition.value.timeRange[1] = endTs.value
  297 + getPacketIntervalByRange(queryCondition.value.timeRange)
  298 + }
  299 + if (Reflect.get(props.chartConfig.request.requestParams.Params, 'agg')) {
  300 + queryCondition.value.agg = agg.value
  301 + }
  302 + if (Reflect.get(props.chartConfig.request.requestParams.Params, 'interval')) {
  303 + queryCondition.value.interval = interval.value
  304 + }
  305 + if (Reflect.get(props.chartConfig.request.requestParams.Params, 'limit')) {
  306 + queryCondition.value.limit = limit.value
  307 + }
289 seriesDataMaxLength = dataJson.source.length 308 seriesDataMaxLength = dataJson.source.length
290 if (props.chartConfig.option.isCarousel) { 309 if (props.chartConfig.option.isCarousel) {
291 addPieInterval(undefined, true) 310 addPieInterval(undefined, true)
@@ -6,6 +6,7 @@ import { chartInitConfig } from '@/settings/designSetting' @@ -6,6 +6,7 @@ import { chartInitConfig } from '@/settings/designSetting'
6 6
7 export const option = { 7 export const option = {
8 dataset: 80, 8 dataset: 80,
  9 + valueRange: [0, 100],
9 unitStr: '个', 10 unitStr: '个',
10 openAnim: true, 11 openAnim: true,
11 duration: 3, 12 duration: 3,
@@ -12,6 +12,12 @@ @@ -12,6 +12,12 @@
12 <n-input-number :min="0.1" step="0.5" v-model:value="optionData.duration"></n-input-number> 12 <n-input-number :min="0.1" step="0.5" v-model:value="optionData.duration"></n-input-number>
13 </SettingItem> 13 </SettingItem>
14 </SettingItemBox> 14 </SettingItemBox>
  15 + <setting-item-box name="范围">
  16 + <setting-item name="范围">
  17 + <n-input-number :min="0" :max="99" v-model:value="optionData.valueRange[0]" />
  18 + <n-input-number :min="1" :max="100" v-model:value="optionData.valueRange[1]" />
  19 + </setting-item>
  20 + </setting-item-box>
15 <setting-item-box name="数据源"> 21 <setting-item-box name="数据源">
16 <setting-item name="数据"> 22 <setting-item name="数据">
17 <n-input-number :min="0" :max="100" v-model:value="optionData.dataset" /> 23 <n-input-number :min="0" :max="100" v-model:value="optionData.dataset" />
@@ -260,7 +260,7 @@ @@ -260,7 +260,7 @@
260 d="M202.38 399.21C205.97 399.21 208.88 402.12 208.88 405.71C208.88 409.3 205.97 412.21 202.38 412.21C198.79 412.21 195.88 409.3 195.88 405.71C195.88 402.12 198.79 399.21 202.38 399.21L202.38 399.21Z" 260 d="M202.38 399.21C205.97 399.21 208.88 402.12 208.88 405.71C208.88 409.3 205.97 412.21 202.38 412.21C198.79 412.21 195.88 409.3 195.88 405.71C195.88 402.12 198.79 399.21 202.38 399.21L202.38 399.21Z"
261 /> 261 />
262 <animateMotion 262 <animateMotion
263 - path="M0,0 L0 -5 L0 -13 L0 -15 L0 -17 L0 -19 L0 -22 L0 -26 L0 -36 263 + path="M0,0 L0 -5 L0 -13 L0 -15 L0 -17 L0 -19 L0 -22 L0 -26 L0 -36
264 L0 -46 L0 -50 L0 -59 L0 -60 L0 -69 L0 -71 L0 -79 L0 -89 L0 -91 L0 -122 L0 -132 L0 -142 L0 -162 L0 -172 L0 -182 L0 -192 264 L0 -46 L0 -50 L0 -59 L0 -60 L0 -69 L0 -71 L0 -79 L0 -89 L0 -91 L0 -122 L0 -132 L0 -142 L0 -162 L0 -172 L0 -182 L0 -192
265 " 265 "
266 begin="1.5s" 266 begin="1.5s"
@@ -278,7 +278,7 @@ @@ -278,7 +278,7 @@
278 d="M231.69 443.18C235.28 443.18 238.19 446.09 238.19 449.68C238.19 453.27 235.28 456.18 231.69 456.18C228.1 456.18 225.19 453.27 225.19 449.68C225.19 446.09 228.1 443.18 231.69 443.18L231.69 443.18Z" 278 d="M231.69 443.18C235.28 443.18 238.19 446.09 238.19 449.68C238.19 453.27 235.28 456.18 231.69 456.18C228.1 456.18 225.19 453.27 225.19 449.68C225.19 446.09 228.1 443.18 231.69 443.18L231.69 443.18Z"
279 /> 279 />
280 <animateMotion 280 <animateMotion
281 - path="M0,0 L0 -5 L0 -13 L0 -15 L0 -17 L0 -19 L0 -22 L0 -26 L0 -36 281 + path="M0,0 L0 -5 L0 -13 L0 -15 L0 -17 L0 -19 L0 -22 L0 -26 L0 -36
282 L0 -46 L0 -50 L0 -59 L0 -60 L0 -69 L0 -71 L0 -79 L0 -89 L0 -91 L0 -122 L0 -132 L0 -142 L0 -162 L0 -172 L0 -182 L0 -192 282 L0 -46 L0 -50 L0 -59 L0 -60 L0 -69 L0 -71 L0 -79 L0 -89 L0 -91 L0 -122 L0 -132 L0 -142 L0 -162 L0 -172 L0 -182 L0 -192
283 " 283 "
284 begin="1.5s" 284 begin="1.5s"
@@ -296,7 +296,7 @@ @@ -296,7 +296,7 @@
296 d="M231.69 443.18C235.28 443.18 238.19 446.09 238.19 449.68C238.19 453.27 235.28 456.18 231.69 456.18C228.1 456.18 225.19 453.27 225.19 449.68C225.19 446.09 228.1 443.18 231.69 443.18L231.69 443.18Z" 296 d="M231.69 443.18C235.28 443.18 238.19 446.09 238.19 449.68C238.19 453.27 235.28 456.18 231.69 456.18C228.1 456.18 225.19 453.27 225.19 449.68C225.19 446.09 228.1 443.18 231.69 443.18L231.69 443.18Z"
297 /> 297 />
298 <animateMotion 298 <animateMotion
299 - path="M0,0 L0 -5 L0 -13 L0 -15 L0 -17 L0 -19 L0 -22 L0 -26 L0 -36 299 + path="M0,0 L0 -5 L0 -13 L0 -15 L0 -17 L0 -19 L0 -22 L0 -26 L0 -36
300 L0 -46 L0 -50 L0 -59 L0 -60 L0 -69 L0 -71 L0 -79 L0 -89 L0 -91 L0 -122 L0 -132 L0 -142 L0 -162 L0 -172 L0 -182 L0 -192 300 L0 -46 L0 -50 L0 -59 L0 -60 L0 -69 L0 -71 L0 -79 L0 -89 L0 -91 L0 -122 L0 -132 L0 -142 L0 -162 L0 -172 L0 -182 L0 -192
301 " 301 "
302 begin="1.5s" 302 begin="1.5s"
@@ -656,7 +656,7 @@ @@ -656,7 +656,7 @@
656 </div> 656 </div>
657 </template> 657 </template>
658 <script setup lang="ts"> 658 <script setup lang="ts">
659 -import { PropType, toRefs } from 'vue' 659 +import { PropType, toRefs, watch } from 'vue'
660 import { CreateComponentType } from '@/packages/index.d' 660 import { CreateComponentType } from '@/packages/index.d'
661 import { option } from './config' 661 import { option } from './config'
662 import { useChartDataFetch } from '@/hooks' 662 import { useChartDataFetch } from '@/hooks'
@@ -671,13 +671,29 @@ const props = defineProps({ @@ -671,13 +671,29 @@ const props = defineProps({
671 671
672 const { w, h } = toRefs(props.chartConfig.attr) 672 const { w, h } = toRefs(props.chartConfig.attr)
673 673
674 -const { dataset, unitStr, colorConfig, openAnim, duration, fontConfig } = toRefs( 674 +const { dataset, unitStr, colorConfig, openAnim, duration, fontConfig, valueRange } = toRefs(
675 props.chartConfig.option as typeof option 675 props.chartConfig.option as typeof option
676 ) 676 )
677 677
  678 +watch(()=>dataset.value,(newData)=>{
  679 + if((Number(newData)) >= valueRange.value[1]){
  680 + newData = valueRange.value[1]
  681 + }
  682 + if((Number(newData)) <= valueRange.value[0]){
  683 + newData = valueRange.value[0]
  684 + }
  685 + dataset.value = newData as number
  686 +})
  687 +
678 // 预览更新 688 // 预览更新
679 -useChartDataFetch(props.chartConfig, useChartEditStore, (newData: number) => {  
680 - dataset.value = newData 689 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: number | string) => {
  690 + if((Number(newData)) >= valueRange.value[1]){
  691 + newData = valueRange.value[1]
  692 + }
  693 + if((Number(newData)) <= valueRange.value[0]){
  694 + newData = valueRange.value[0]
  695 + }
  696 + dataset.value = newData as number
681 }) 697 })
682 </script> 698 </script>
683 699
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { Decorates27Config } from './index'
  3 +import { CreateComponentType } from '@/packages/index.d'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
  6 +
  7 +export const option = {
  8 + dataset: '模块标题',
  9 + fontConfig: {
  10 + x1: '132',
  11 + y1: '129.8828125',
  12 + x2: '103',
  13 + y2: '64.96000000000001',
  14 + datasetTspanFill: '#00F0A2',
  15 + titleTspanFill: '#FFFFFF',
  16 + datasetTspanFontSize: 30,
  17 + }
  18 +}
  19 +
  20 +export default class Config extends PublicConfigClass implements CreateComponentType {
  21 + public key = Decorates27Config.key
  22 + public attr = { ...chartInitConfig, w: 305, h: 110, zIndex: -1 }
  23 + public chartConfig = cloneDeep(Decorates27Config)
  24 + public option = cloneDeep(option)
  25 +}
  1 +<template>
  2 + <!-- Echarts 全局设置 -->
  3 + <global-setting :optionData="optionData"></global-setting>
  4 + <CollapseItem name="配置" :expanded="true">
  5 + <setting-item-box name="数据源">
  6 + <setting-item name="数据">
  7 + <n-input v-model:value="optionData.dataset" />
  8 + </setting-item>
  9 + </setting-item-box>
  10 + <SettingItemBox :name="`数据源字体配置`">
  11 + <SettingItem name="x">
  12 + <n-input-number :min="0" v-model:value="optionData.fontConfig.x1"></n-input-number>
  13 + </SettingItem>
  14 + <SettingItem name="y">
  15 + <n-input-number :min="0" v-model:value="optionData.fontConfig.y1"></n-input-number>
  16 + </SettingItem>
  17 + <SettingItem name="大小">
  18 + <n-input-number :min="0" v-model:value="optionData.fontConfig.datasetTspanFontSize"></n-input-number>
  19 + </SettingItem>
  20 + <SettingItem name="颜色">
  21 + <n-color-picker
  22 + size="small"
  23 + :modes="['hex']"
  24 + v-model:value="optionData.fontConfig.datasetTspanFill"
  25 + ></n-color-picker>
  26 + </SettingItem>
  27 + </SettingItemBox>
  28 + </CollapseItem>
  29 +</template>
  30 +
  31 +<script setup lang="ts">
  32 +import { PropType } from 'vue'
  33 +import { option } from './config'
  34 +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  35 +
  36 +defineProps({
  37 + optionData: {
  38 + type: Object as PropType<typeof option>,
  39 + required: true
  40 + }
  41 +})
  42 +</script>
  1 +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
  2 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, chartKey, conKey } = useWidgetKey('Decorates27', true)
  6 +
  7 +export const Decorates27Config: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '模块标题27',
  12 + category: ChatCategoryEnum.DECORATE,
  13 + categoryName: ChatCategoryEnumName.DECORATE,
  14 + package: PackagesCategoryEnum.DECORATES,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'decorates27.png'
  17 +}
  1 +<template>
  2 + <div class="go-content-box">
  3 + <svg
  4 + xmlns="http://www.w3.org/2000/svg"
  5 + xmlns:xlink="http://www.w3.org/1999/xlink"
  6 + :width="w"
  7 + :height="h"
  8 + viewBox="0 0 420 147"
  9 + fill="none"
  10 + >
  11 + <g opacity="0.3">
  12 + <g filter="url(#filter_f159ebae-322a-4973-83f9-9355681bcf9d)">
  13 + <rect
  14 + x="9"
  15 + y="10"
  16 + width="402"
  17 + height="134"
  18 + stroke="rgba(11, 97, 184, 1)"
  19 + stroke-width="2"
  20 + fill="#011231"
  21 + fill-opacity="0.6"
  22 + ></rect>
  23 + </g>
  24 + </g>
  25 + <rect x="9" y="1" width="402" height="134" fill="#022C5B"></rect>
  26 + <g filter="url(#filter_d39fec7c-b2c4-483b-a0f9-e184380ce12e)">
  27 + <rect x="9" y="1" width="402" height="134" stroke="rgba(11, 97, 184, 1)" stroke-width="2"></rect>
  28 + </g>
  29 + <rect x="1" y="0" width="2" height="136" fill="#00ABFF"></rect>
  30 + <rect x="417" y="0" width="2" height="136" fill="#00ABFF"></rect>
  31 + <rect x="416" y="0" width="4" height="30" fill="#00F6FF"></rect>
  32 + <rect x="416" y="106" width="4" height="30" fill="#00F6FF"></rect>
  33 + <rect x="0" y="0" width="4" height="30" fill="#00F6FF"></rect>
  34 + <rect x="0" y="106" width="4" height="30" fill="#00F6FF"></rect>
  35 + <rect x="15" y="6" width="8" height="4" fill="#00F6FF"></rect>
  36 + <rect x="395" y="6" width="8" height="4" fill="#00F6FF"></rect>
  37 + <g opacity="0.6">
  38 + <rect x="382" y="6" width="8" height="4" fill="#00F6FF"></rect>
  39 + </g>
  40 + <g opacity="0.2">
  41 + <rect x="369" y="6" width="8" height="4" fill="#00F6FF"></rect>
  42 + </g>
  43 + <g opacity="0.6">
  44 + <rect x="28" y="6" width="8" height="4" fill="#00F6FF"></rect>
  45 + </g>
  46 + <g opacity="0.2">
  47 + <rect x="41" y="6" width="8" height="4" fill="#00F6FF"></rect>
  48 + </g>
  49 + <g opacity="0.5">
  50 + <path stroke="rgba(11, 97, 184, 1)" stroke-width="2" d="M134 1.5L149.5 16.5L269 16.5L284 1.5"></path>
  51 + </g>
  52 + <g opacity="0.5">
  53 + <path stroke="rgba(11, 97, 184, 1)" stroke-width="2" d="M134 135L149.5 120L269 120L284 135"></path>
  54 + </g>
  55 + <g opacity="1" transform="translate(11 -50)">
  56 + <text>
  57 + <tspan
  58 + :x="fontConfig.x1"
  59 + :y="fontConfig.y1"
  60 + :font-size="fontConfig.datasetTspanFontSize"
  61 + line-height="0"
  62 + :fill="fontConfig.datasetTspanFill"
  63 + opacity="1"
  64 + font-family="Roboto-Regular"
  65 + font-weight="Regular"
  66 + letter-spacing="0"
  67 + >
  68 + {{ dataset }}
  69 + </tspan>
  70 + </text>
  71 + </g>
  72 + <path
  73 + d="M85.5 33C102.9 33 117 47.1 117 64.5C117 81.9 89.87 103 85.5 103C81.13 103 54 81.9 54 64.5C54 47.1 68.1 33 85.5 33ZM85.495 54.875C90.815 54.875 95.125 59.185 95.125 64.495C95.125 69.815 90.815 74.125 85.495 74.125C80.185 74.125 75.875 69.815 75.875 64.495C75.875 59.185 80.185 54.875 85.495 54.875Z"
  74 + fill-rule="evenodd"
  75 + fill="url(#linear_fill_24aadc2d-dd75-4fb1-b98a-92d6c45d95db)"
  76 + ></path>
  77 + <path
  78 + fill-rule="evenodd"
  79 + fill="url(#linear_fill_5b832155-7920-462b-94fb-fb2e3ed3f1d4_0)"
  80 + d="M85.5 38C102.9 38 117 52.1 117 69.5C117 86.9 89.87 108 85.5 108C81.13 108 54 86.9 54 69.5C54 52.1 68.1 38 85.5 38ZM85.495 59.875C90.815 59.875 95.125 64.185 95.125 69.495C95.125 74.815 90.815 79.125 85.495 79.125C80.185 79.125 75.875 74.815 75.875 69.495C75.875 64.185 80.185 59.875 85.495 59.875Z"
  81 + ></path>
  82 + <path
  83 + fill-rule="evenodd"
  84 + fill="rgba(4, 220, 237, 0.26)"
  85 + d="M117 69.5C117 52.1 102.9 38 85.5 38C68.1 38 54 52.1 54 69.5C54 86.9 81.13 108 85.5 108C89.87 108 117 86.9 117 69.5ZM55 69.5C55 52.6553 68.6553 39 85.5 39C102.345 39 116 52.6553 116 69.5Q116 80.5209 102.176 94.5737Q97.0168 99.8181 91.6852 103.617Q86.9368 107 85.5 107Q84.0632 107 79.3148 103.617Q73.9832 99.8181 68.8241 94.5737Q55 80.5209 55 69.5ZM96.125 69.495C96.125 63.6297 91.3603 58.875 85.495 58.875C79.6297 58.875 74.875 63.6297 74.875 69.495C74.875 75.3658 79.6242 80.125 85.495 80.125C91.3658 80.125 96.125 75.3658 96.125 69.495ZM95.125 69.495C95.125 64.185 90.815 59.875 85.495 59.875C80.185 59.875 75.875 64.185 75.875 69.495C75.875 74.815 80.185 79.125 85.495 79.125C90.815 79.125 95.125 74.815 95.125 69.495Z"
  86 + ></path>
  87 + <defs>
  88 + <filter
  89 + id="filter_f159ebae-322a-4973-83f9-9355681bcf9d"
  90 + x="6"
  91 + y="7"
  92 + width="408"
  93 + height="140"
  94 + filterUnits="userSpaceOnUse"
  95 + color-interpolation-filters="sRGB"
  96 + >
  97 + <feFlood flood-opacity="0" result="feFloodId_f159ebae-322a-4973-83f9-9355681bcf9d" />
  98 + <feBlend
  99 + mode="normal"
  100 + in="SourceGraphic"
  101 + in2="feFloodId_f159ebae-322a-4973-83f9-9355681bcf9d"
  102 + result="shape"
  103 + />
  104 + <feGaussianBlur result="gaussian_blur_f159ebae-322a-4973-83f9-9355681bcf9d" stdDeviation="1" />
  105 + </filter>
  106 + <filter
  107 + id="filter_d39fec7c-b2c4-483b-a0f9-e184380ce12e"
  108 + x="8"
  109 + y="0"
  110 + width="404"
  111 + height="136"
  112 + filterUnits="userSpaceOnUse"
  113 + color-interpolation-filters="sRGB"
  114 + >
  115 + <feFlood flood-opacity="0" result="feFloodId_d39fec7c-b2c4-483b-a0f9-e184380ce12e" />
  116 + <feBlend
  117 + mode="normal"
  118 + in="SourceGraphic"
  119 + in2="feFloodId_d39fec7c-b2c4-483b-a0f9-e184380ce12e"
  120 + result="shape_d39fec7c-b2c4-483b-a0f9-e184380ce12e"
  121 + />
  122 + <feColorMatrix
  123 + in="SourceAlpha"
  124 + type="matrix"
  125 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  126 + result="hardAlpha_d39fec7c-b2c4-483b-a0f9-e184380ce12e"
  127 + />
  128 + <feOffset dx="0" dy="0" />
  129 + <feGaussianBlur stdDeviation="10" />
  130 + <feComposite in2="hardAlpha_d39fec7c-b2c4-483b-a0f9-e184380ce12e" operator="arithmetic" k2="-1" k3="1" />
  131 + <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0.6509803921568628 0 0 0 0 1 0 0 0 0.8 0" />
  132 + <feBlend
  133 + mode="normal"
  134 + in2="shape_d39fec7c-b2c4-483b-a0f9-e184380ce12e"
  135 + result="innerShadow_0_d39fec7c-b2c4-483b-a0f9-e184380ce12e"
  136 + />
  137 + </filter>
  138 + <linearGradient
  139 + id="linear_fill_24aadc2d-dd75-4fb1-b98a-92d6c45d95db"
  140 + x1="85.5"
  141 + y1="103"
  142 + x2="85.5"
  143 + y2="33"
  144 + gradientUnits="userSpaceOnUse"
  145 + >
  146 + <stop offset="0" stop-color="#18698C" />
  147 + <stop offset="1" stop-color="#11A6A6" />
  148 + </linearGradient>
  149 + <linearGradient
  150 + id="linear_fill_5b832155-7920-462b-94fb-fb2e3ed3f1d4_0"
  151 + x1="85.5"
  152 + y1="108"
  153 + x2="85.5"
  154 + y2="38"
  155 + gradientUnits="userSpaceOnUse"
  156 + >
  157 + <stop offset="0" stop-color="#0E668C" />
  158 + <stop offset="1" stop-color="#00F2EE" />
  159 + </linearGradient>
  160 + </defs>
  161 + </svg>
  162 + </div>
  163 +</template>
  164 +<script setup lang="ts">
  165 +import { PropType, toRefs } from 'vue'
  166 +import { CreateComponentType } from '@/packages/index.d'
  167 +import { option } from './config'
  168 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  169 +import { useChartDataFetch } from '@/hooks'
  170 +import { isObject } from '@/utils/external/is'
  171 +
  172 +const props = defineProps({
  173 + chartConfig: {
  174 + type: Object as PropType<CreateComponentType & typeof option>,
  175 + required: true
  176 + }
  177 +})
  178 +
  179 +const { w, h } = toRefs(props.chartConfig.attr)
  180 +
  181 +const { dataset, fontConfig } = toRefs(props.chartConfig.option as typeof option)
  182 +
  183 +// 预览更新
  184 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
  185 + if (isObject(newData)) return
  186 + dataset.value = newData as string
  187 +})
  188 +</script>
  189 +
  190 +<style lang="scss" scoped>
  191 +.go-content-box {
  192 + width: v-bind('w+"px"');
  193 + height: v-bind('h+"px"');
  194 + display: flex;
  195 + align-items: center;
  196 + justify-content: center;
  197 +}
  198 +</style>
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { Decorates28Config } from './index'
  3 +import { CreateComponentType } from '@/packages/index.d'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
  6 +
  7 +export const option = {
  8 + dataset: '模块标题',
  9 + fontConfig: {
  10 + x1: '132',
  11 + y1: '129.8828125',
  12 + x2: '103',
  13 + y2: '64.96000000000001',
  14 + datasetTspanFill: '#00F0A2',
  15 + titleTspanFill: '#FFFFFF',
  16 + datasetTspanFontSize: 30,
  17 + }
  18 +}
  19 +
  20 +export default class Config extends PublicConfigClass implements CreateComponentType {
  21 + public key = Decorates28Config.key
  22 + public attr = { ...chartInitConfig, w: 305, h: 110, zIndex: -1 }
  23 + public chartConfig = cloneDeep(Decorates28Config)
  24 + public option = cloneDeep(option)
  25 +}
  1 +<template>
  2 + <!-- Echarts 全局设置 -->
  3 + <global-setting :optionData="optionData"></global-setting>
  4 + <CollapseItem name="配置" :expanded="true">
  5 + <setting-item-box name="数据源">
  6 + <setting-item name="数据">
  7 + <n-input v-model:value="optionData.dataset" />
  8 + </setting-item>
  9 + </setting-item-box>
  10 + <SettingItemBox :name="`数据源字体配置`">
  11 + <SettingItem name="x">
  12 + <n-input-number :min="0" v-model:value="optionData.fontConfig.x1"></n-input-number>
  13 + </SettingItem>
  14 + <SettingItem name="y">
  15 + <n-input-number :min="0" v-model:value="optionData.fontConfig.y1"></n-input-number>
  16 + </SettingItem>
  17 + <SettingItem name="大小">
  18 + <n-input-number :min="0" v-model:value="optionData.fontConfig.datasetTspanFontSize"></n-input-number>
  19 + </SettingItem>
  20 + <SettingItem name="颜色">
  21 + <n-color-picker
  22 + size="small"
  23 + :modes="['hex']"
  24 + v-model:value="optionData.fontConfig.datasetTspanFill"
  25 + ></n-color-picker>
  26 + </SettingItem>
  27 + </SettingItemBox>
  28 + </CollapseItem>
  29 +</template>
  30 +
  31 +<script setup lang="ts">
  32 +import { PropType } from 'vue'
  33 +import { option } from './config'
  34 +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  35 +
  36 +defineProps({
  37 + optionData: {
  38 + type: Object as PropType<typeof option>,
  39 + required: true
  40 + }
  41 +})
  42 +</script>
  1 +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
  2 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, chartKey, conKey } = useWidgetKey('Decorates28', true)
  6 +
  7 +export const Decorates28Config: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '模块标题28',
  12 + category: ChatCategoryEnum.DECORATE,
  13 + categoryName: ChatCategoryEnumName.DECORATE,
  14 + package: PackagesCategoryEnum.DECORATES,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'decorates28.png'
  17 +}
  1 +<template>
  2 + <div class="go-content-box">
  3 + <svg
  4 + xmlns="http://www.w3.org/2000/svg"
  5 + xmlns:xlink="http://www.w3.org/1999/xlink"
  6 + :width="w"
  7 + :height="h"
  8 + viewBox="0 0 428.1663818359375 121.5"
  9 + fill="none"
  10 + >
  11 + <g>
  12 + <g filter="url(#filter_98d03be6-b8cb-4e27-b332-bc2820d07903)">
  13 + <path
  14 + d="M409.722 14.36C409.342 13.82 408.732 13.5 408.072 13.5L44.8918 13.5C44.1218 13.5 43.4118 13.94 43.0818 14.64L12.9417 78.35C12.6517 78.95 12.6917 79.66 13.0317 80.23L35.8918 118.53C36.2518 119.13 36.9118 119.5 37.6118 119.5L385.422 119.5C386.182 119.5 386.882 119.06 387.212 118.38L425.962 39.67C426.282 39.02 426.222 38.25 425.812 37.65L409.722 14.36Z"
  15 + fill="#011231"
  16 + fill-opacity="0.6"
  17 + ></path>
  18 + </g>
  19 + <g filter="url(#filter_c8b60da4-9052-4ab3-a895-6acbad140e0b)">
  20 + <path
  21 + d="M409.722 14.36C409.342 13.82 408.732 13.5 408.072 13.5L44.8918 13.5C44.1218 13.5 43.4118 13.94 43.0818 14.64L12.9417 78.35C12.6517 78.95 12.6917 79.66 13.0317 80.23L35.8918 118.53C36.2518 119.13 36.9118 119.5 37.6118 119.5L385.422 119.5C386.182 119.5 386.882 119.06 387.212 118.38L425.962 39.67C426.282 39.02 426.222 38.25 425.812 37.65L409.722 14.36Z"
  22 + stroke="rgba(11, 97, 184, 1)"
  23 + stroke-width="2"
  24 + ></path>
  25 + </g>
  26 + </g>
  27 + <path
  28 + d="M417.481 27.54C417.791 26.89 417.731 26.13 417.331 25.54L401.581 2.38C401.211 1.83 400.591 1.5 399.921 1.5L44.2517 1.5C43.4717 1.5 42.7717 1.95 42.4417 2.66L12.9218 66.05C12.6418 66.65 12.6818 67.34 13.0118 67.91L35.4017 106.01C35.7617 106.62 36.4117 107 37.1217 107L377.731 107C378.501 107 379.201 106.56 379.531 105.87L417.481 27.54Z"
  29 + fill="#011231"
  30 + fill-opacity="0.6"
  31 + ></path>
  32 + <g filter="url(#filter_19131d1d-3e49-4887-91be-ebc5057ba529)">
  33 + <path
  34 + d="M417.481 27.54C417.791 26.89 417.731 26.13 417.331 25.54L401.581 2.38C401.211 1.83 400.591 1.5 399.921 1.5L44.2517 1.5C43.4717 1.5 42.7717 1.95 42.4417 2.66L12.9218 66.05C12.6418 66.65 12.6818 67.34 13.0118 67.91L35.4017 106.01C35.7617 106.62 36.4117 107 37.1217 107L377.731 107C378.501 107 379.201 106.56 379.531 105.87L417.481 27.54Z"
  35 + stroke="rgba(11, 97, 184, 1)"
  36 + stroke-width="2"
  37 + ></path>
  38 + </g>
  39 + <g opacity="0.6">
  40 + <path
  41 + d="M58.098 7.86505C57.338 7.86505 56.648 8.28505 56.308 8.96505L28.3379 64.7651C28.0279 65.3851 28.0579 66.1351 28.4279 66.7251L49.608 100.205C49.978 100.785 50.608 101.135 51.298 101.135L375.488 101.135C376.238 101.135 376.918 100.725 377.268 100.065L413.248 31.0751C413.608 30.4051 413.548 29.5851 413.098 28.9651L398.248 8.68505C397.868 8.16505 397.268 7.86505 396.628 7.86505L58.098 7.86505Z"
  42 + fill="#081837"
  43 + fill-opacity="0.6"
  44 + ></path>
  45 + <g filter="url(#filter_ecbd7b82-4d30-47dd-822d-74022aba9497)">
  46 + <path
  47 + d="M58.098 7.86505C57.338 7.86505 56.648 8.28505 56.308 8.96505L28.3379 64.7651C28.0279 65.3851 28.0579 66.1351 28.4279 66.7251L49.608 100.205C49.978 100.785 50.608 101.135 51.298 101.135L375.488 101.135C376.238 101.135 376.918 100.725 377.268 100.065L413.248 31.0751C413.608 30.4051 413.548 29.5851 413.098 28.9651L398.248 8.68505C397.868 8.16505 397.268 7.86505 396.628 7.86505L58.098 7.86505Z"
  48 + fill="#081837"
  49 + fill-opacity="0.6"
  50 + ></path>
  51 + </g>
  52 + </g>
  53 + <path
  54 + d="M50.4818 7.5L44.4818 20L51.9818 20L54.9818 12.5L65.9818 12.5L62.4818 7.5L50.4818 7.5Z"
  55 + fill="#0BD9FC"
  56 + ></path>
  57 + <path
  58 + d="M371.482 101L377.482 88.5L369.982 88.5L366.982 96L355.982 96L359.482 101L371.482 101Z"
  59 + fill="#0BD9FC"
  60 + ></path>
  61 + <g opacity="0.8">
  62 + <path d="M348.982 96L343.482 96L348.982 101L354.482 101L348.982 96Z" fill="#0BD9FC"></path>
  63 + </g>
  64 + <g opacity="0.6">
  65 + <path d="M336.982 96L331.482 96L336.982 101L342.482 101L336.982 96Z" fill="#0BD9FC"></path>
  66 + </g>
  67 + <g opacity="0.3">
  68 + <path d="M325.982 96L320.482 96L325.982 101L331.482 101L325.982 96Z" fill="#0BD9FC"></path>
  69 + </g>
  70 + <g opacity="0.8">
  71 + <path d="M72.9818 12.5L78.4818 12.5L72.9818 7.5L67.4818 7.5L72.9818 12.5Z" fill="#0BD9FC"></path>
  72 + </g>
  73 + <g opacity="0.6">
  74 + <path d="M84.9818 12.5L90.4818 12.5L84.9818 7.5L79.4818 7.5L84.9818 12.5Z" fill="#0BD9FC"></path>
  75 + </g>
  76 + <g opacity="0.3">
  77 + <path d="M95.9818 12.5L101.482 12.5L95.9818 7.5L90.4818 7.5L95.9818 12.5Z" fill="#0BD9FC"></path>
  78 + </g>
  79 + <g opacity="0.6">
  80 + <path
  81 + d="M22.1417 106C22.5117 106 22.8417 105.8 23.0217 105.47C23.1917 105.15 23.1717 104.76 22.9717 104.45L10.9917 86.05C10.7917 85.74 10.4417 85.56 10.0717 85.59C9.70171 85.62 9.38171 85.85 9.23171 86.19L1.1017 104.6C0.961703 104.91 1.0017 105.27 1.1817 105.55C1.3717 105.83 1.6817 106 2.02171 106L22.1417 106Z"
  82 + stroke="rgba(0, 185, 255, 1)"
  83 + stroke-width="2"
  84 + fill="#0E3F80"
  85 + ></path>
  86 + </g>
  87 + <g opacity="1" transform="translate(22 -65)">
  88 + <text>
  89 + <tspan
  90 + :x="fontConfig.x1"
  91 + :y="fontConfig.y1"
  92 + :font-size="fontConfig.datasetTspanFontSize"
  93 + line-height="0"
  94 + :fill="fontConfig.datasetTspanFill"
  95 + opacity="1"
  96 + font-family="Roboto-Regular"
  97 + font-weight="Regular"
  98 + letter-spacing="0"
  99 + >
  100 + {{ dataset }}
  101 + </tspan>
  102 + </text>
  103 + </g>
  104 + <path
  105 + d="M82.8819 108.069L37.6304 108.069C35.7021 108.069 34.4931 106.6 34.4426 106.537L34.395 106.478L34.3569 106.413C33.4674 104.889 12.5669 69.0836 12.0755 68.1901C11.4897 67.1249 11.7768 66.1139 12.0729 65.6206L25.08 37.9282L26.8903 38.7785L13.8059 66.6353L13.784 66.6593C13.7442 66.7397 13.6747 66.9476 13.828 67.2263C14.2959 68.0771 34.8648 103.316 36.034 105.319C36.1941 105.487 36.8063 106.069 37.6304 106.069L82.8819 106.069L82.8819 108.069Z"
  106 + fill="url(#linear_fill_a36ae718-b1ea-4e08-8516-037b53322938)"
  107 + ></path>
  108 + <path
  109 + d="M397.024 71.9896L395.227 71.1121C395.43 70.6963 415.542 29.5053 416.397 27.6251C416.809 26.7185 416.707 26.1818 416.589 26.0099L416.545 25.9688L416.483 25.8788C415.903 25.0347 402.256 5.18647 401.226 3.53913C400.579 2.50379 399.663 2.49152 399.518 2.4972L399.465 2.50367L399.439 2.50007L361.457 2.50007L361.457 0.500061L399.403 0.500061C400.241 0.446289 401.874 0.802368 402.922 2.47906C403.903 4.04908 417.289 23.5203 418.094 24.6921C418.413 25.0638 419.203 26.2852 418.217 28.4527C417.351 30.3579 397.854 70.2907 397.024 71.9896Z"
  110 + fill="url(#linear_fill_e679ec05-c54c-45fa-afbc-1f4cc272d7de)"
  111 + ></path>
  112 + <rect
  113 + x="136.48175048828125"
  114 + y="0.5"
  115 + width="174"
  116 + height="2"
  117 + stroke="rgba(0, 0, 0, 0)"
  118 + stroke-width="1"
  119 + fill="url(#linear_fill_67dd1fd1-a96a-4a67-a858-60eb1cc7970d)"
  120 + ></rect>
  121 + <rect
  122 + x="96.48175048828125"
  123 + y="106.5"
  124 + width="174"
  125 + height="2"
  126 + stroke="rgba(0, 0, 0, 0)"
  127 + stroke-width="1"
  128 + fill="url(#linear_fill_2d07459b-3ef9-4b88-a694-f39f3a4fb8db)"
  129 + ></rect>
  130 + <path
  131 + d="M84.9818 34.142C84.9827 32.629 86.2087 31.403 87.7217 31.402L110.112 31.402C111.432 31.402 112.67 32.337 113.032 33.605L115.145 40.999L137.985 40.999C139.957 40.999 141.574 42.566 141.635 44.538L141.636 44.652L141.636 73.445C141.636 75.462 139.998 77.098 137.985 77.098L88.6338 77.098C86.6168 77.098 84.9818 75.462 84.9818 73.445L84.9818 34.142ZM109.646 35.058L88.6367 35.058L88.6367 40.999L111.343 40.999L109.646 35.058Z"
  132 + fill-rule="evenodd"
  133 + fill="#00A8FF"
  134 + ></path>
  135 + <path
  136 + d="M84.9818 34.142C84.9827 32.629 86.2087 31.403 87.7217 31.402L110.112 31.402C111.432 31.402 112.67 32.337 113.032 33.605L115.145 40.999L137.985 40.999C139.957 40.999 141.574 42.566 141.635 44.538L141.636 44.652L141.636 73.445C141.636 75.462 139.998 77.098 137.985 77.098L88.6338 77.098C86.6168 77.098 84.9818 75.462 84.9818 73.445L84.9818 34.142ZM109.646 35.058L88.6367 35.058L88.6367 40.999L111.343 40.999L109.646 35.058Z"
  137 + fill="url(#linear_fill_5a73a61e-dfec-44ae-ab41-e59e92779ecb)"
  138 + ></path>
  139 + <defs>
  140 + <filter
  141 + id="filter_98d03be6-b8cb-4e27-b332-bc2820d07903"
  142 + x="10.74798583984375"
  143 + y="11.5"
  144 + width="417.41839599609375"
  145 + height="110"
  146 + filterUnits="userSpaceOnUse"
  147 + color-interpolation-filters="sRGB"
  148 + >
  149 + <feFlood flood-opacity="0" result="feFloodId_98d03be6-b8cb-4e27-b332-bc2820d07903" />
  150 + <feBlend
  151 + mode="normal"
  152 + in="SourceGraphic"
  153 + in2="feFloodId_98d03be6-b8cb-4e27-b332-bc2820d07903"
  154 + result="shape"
  155 + />
  156 + <feGaussianBlur result="gaussian_blur_98d03be6-b8cb-4e27-b332-bc2820d07903" stdDeviation="1" />
  157 + </filter>
  158 + <filter
  159 + id="filter_c8b60da4-9052-4ab3-a895-6acbad140e0b"
  160 + x="11.722366333007812"
  161 + y="12.5"
  162 + width="415.47483825683594"
  163 + height="108"
  164 + filterUnits="userSpaceOnUse"
  165 + color-interpolation-filters="sRGB"
  166 + >
  167 + <feFlood flood-opacity="0" result="feFloodId_c8b60da4-9052-4ab3-a895-6acbad140e0b" />
  168 + <feBlend
  169 + mode="normal"
  170 + in="SourceGraphic"
  171 + in2="feFloodId_c8b60da4-9052-4ab3-a895-6acbad140e0b"
  172 + result="shape_c8b60da4-9052-4ab3-a895-6acbad140e0b"
  173 + />
  174 + <feColorMatrix
  175 + in="SourceAlpha"
  176 + type="matrix"
  177 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  178 + result="hardAlpha_c8b60da4-9052-4ab3-a895-6acbad140e0b"
  179 + />
  180 + <feOffset dx="0" dy="0" />
  181 + <feGaussianBlur stdDeviation="10" />
  182 + <feComposite in2="hardAlpha_c8b60da4-9052-4ab3-a895-6acbad140e0b" operator="arithmetic" k2="-1" k3="1" />
  183 + <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0.6509803921568628 0 0 0 0 1 0 0 0 0.8 0" />
  184 + <feBlend
  185 + mode="normal"
  186 + in2="shape_c8b60da4-9052-4ab3-a895-6acbad140e0b"
  187 + result="innerShadow_0_c8b60da4-9052-4ab3-a895-6acbad140e0b"
  188 + />
  189 + </filter>
  190 + <filter
  191 + id="filter_19131d1d-3e49-4887-91be-ebc5057ba529"
  192 + x="11.714736938476562"
  193 + y="0.5"
  194 + width="406.99278259277344"
  195 + height="107.5"
  196 + filterUnits="userSpaceOnUse"
  197 + color-interpolation-filters="sRGB"
  198 + >
  199 + <feFlood flood-opacity="0" result="feFloodId_19131d1d-3e49-4887-91be-ebc5057ba529" />
  200 + <feBlend
  201 + mode="normal"
  202 + in="SourceGraphic"
  203 + in2="feFloodId_19131d1d-3e49-4887-91be-ebc5057ba529"
  204 + result="shape_19131d1d-3e49-4887-91be-ebc5057ba529"
  205 + />
  206 + <feColorMatrix
  207 + in="SourceAlpha"
  208 + type="matrix"
  209 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  210 + result="hardAlpha_19131d1d-3e49-4887-91be-ebc5057ba529"
  211 + />
  212 + <feOffset dx="0" dy="0" />
  213 + <feGaussianBlur stdDeviation="10" />
  214 + <feComposite in2="hardAlpha_19131d1d-3e49-4887-91be-ebc5057ba529" operator="arithmetic" k2="-1" k3="1" />
  215 + <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0.6509803921568628 0 0 0 0 1 0 0 0 0.8 0" />
  216 + <feBlend
  217 + mode="normal"
  218 + in2="shape_19131d1d-3e49-4887-91be-ebc5057ba529"
  219 + result="innerShadow_0_19131d1d-3e49-4887-91be-ebc5057ba529"
  220 + />
  221 + </filter>
  222 + <filter
  223 + id="filter_ecbd7b82-4d30-47dd-822d-74022aba9497"
  224 + x="28.125961303710938"
  225 + y="7.86505126953125"
  226 + width="385.35585021972656"
  227 + height="93.26998901367188"
  228 + filterUnits="userSpaceOnUse"
  229 + color-interpolation-filters="sRGB"
  230 + >
  231 + <feFlood flood-opacity="0" result="feFloodId_ecbd7b82-4d30-47dd-822d-74022aba9497" />
  232 + <feBlend
  233 + mode="normal"
  234 + in="SourceGraphic"
  235 + in2="feFloodId_ecbd7b82-4d30-47dd-822d-74022aba9497"
  236 + result="shape_ecbd7b82-4d30-47dd-822d-74022aba9497"
  237 + />
  238 + <feColorMatrix
  239 + in="SourceAlpha"
  240 + type="matrix"
  241 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  242 + result="hardAlpha_ecbd7b82-4d30-47dd-822d-74022aba9497"
  243 + />
  244 + <feOffset dx="0" dy="0" />
  245 + <feGaussianBlur stdDeviation="10" />
  246 + <feComposite in2="hardAlpha_ecbd7b82-4d30-47dd-822d-74022aba9497" operator="arithmetic" k2="-1" k3="1" />
  247 + <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0.6509803921568628 0 0 0 0 1 0 0 0 0.8 0" />
  248 + <feBlend
  249 + mode="normal"
  250 + in2="shape_ecbd7b82-4d30-47dd-822d-74022aba9497"
  251 + result="innerShadow_0_ecbd7b82-4d30-47dd-822d-74022aba9497"
  252 + />
  253 + </filter>
  254 + <linearGradient
  255 + id="linear_fill_a36ae718-b1ea-4e08-8516-037b53322938"
  256 + x1="20.389801025390625"
  257 + y1="80.09097290039062"
  258 + x2="47.30860900878906"
  259 + y2="63.687042236328125"
  260 + gradientUnits="userSpaceOnUse"
  261 + >
  262 + <stop offset="0" stop-color="#00F6FF" />
  263 + <stop offset="1" stop-color="#0055D5" stop-opacity="0" />
  264 + </linearGradient>
  265 + <linearGradient
  266 + id="linear_fill_e679ec05-c54c-45fa-afbc-1f4cc272d7de"
  267 + x1="410.9110107421875"
  268 + y1="15.723907470703125"
  269 + x2="380.83074951171875"
  270 + y2="39.813629150390625"
  271 + gradientUnits="userSpaceOnUse"
  272 + >
  273 + <stop offset="0" stop-color="#00F6FF" />
  274 + <stop offset="1" stop-color="#0055D5" stop-opacity="0" />
  275 + </linearGradient>
  276 + <linearGradient
  277 + id="linear_fill_67dd1fd1-a96a-4a67-a858-60eb1cc7970d"
  278 + x1="311.72615027427673"
  279 + y1="2.5"
  280 + x2="141.3970258012414"
  281 + y2="4.917073726654053"
  282 + gradientUnits="userSpaceOnUse"
  283 + >
  284 + <stop offset="0" stop-color="#05EEFF" stop-opacity="0" />
  285 + <stop offset="0.519694983959198" stop-color="#00D2FF" />
  286 + <stop offset="1" stop-color="#04679A" stop-opacity="0" />
  287 + </linearGradient>
  288 + <linearGradient
  289 + id="linear_fill_2d07459b-3ef9-4b88-a694-f39f3a4fb8db"
  290 + x1="271.72615027427673"
  291 + y1="108.5"
  292 + x2="101.3970258012414"
  293 + y2="110.91707372665405"
  294 + gradientUnits="userSpaceOnUse"
  295 + >
  296 + <stop offset="0" stop-color="#05EEFF" stop-opacity="0" />
  297 + <stop offset="0.519694983959198" stop-color="#00D2FF" />
  298 + <stop offset="1" stop-color="#04679A" stop-opacity="0" />
  299 + </linearGradient>
  300 + <linearGradient
  301 + id="linear_fill_5a73a61e-dfec-44ae-ab41-e59e92779ecb"
  302 + x1="84.98175048828125"
  303 + y1="77.0980224609375"
  304 + x2="84.98175048828125"
  305 + y2="31.402008056640625"
  306 + gradientUnits="userSpaceOnUse"
  307 + >
  308 + <stop offset="0" stop-color="#2787FF" />
  309 + <stop offset="1" stop-color="#46FBFD" />
  310 + </linearGradient>
  311 + </defs>
  312 + </svg>
  313 + </div>
  314 +</template>
  315 +<script setup lang="ts">
  316 +import { PropType, toRefs } from 'vue'
  317 +import { CreateComponentType } from '@/packages/index.d'
  318 +import { option } from './config'
  319 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  320 +import { useChartDataFetch } from '@/hooks'
  321 +import { isObject } from '@/utils/external/is'
  322 +
  323 +const props = defineProps({
  324 + chartConfig: {
  325 + type: Object as PropType<CreateComponentType & typeof option>,
  326 + required: true
  327 + }
  328 +})
  329 +
  330 +const { w, h } = toRefs(props.chartConfig.attr)
  331 +
  332 +const { dataset, fontConfig } = toRefs(props.chartConfig.option as typeof option)
  333 +
  334 +// 预览更新
  335 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
  336 + if (isObject(newData)) return
  337 + dataset.value = newData as string
  338 +})
  339 +</script>
  340 +
  341 +<style lang="scss" scoped>
  342 +.go-content-box {
  343 + width: v-bind('w+"px"');
  344 + height: v-bind('h+"px"');
  345 + display: flex;
  346 + align-items: center;
  347 + justify-content: center;
  348 +}
  349 +</style>
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { Decorates29Config } from './index'
  3 +import { CreateComponentType } from '@/packages/index.d'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
  6 +
  7 +export const option = {
  8 + dataset: '模块标题',
  9 + fontConfig: {
  10 + x1: '132',
  11 + y1: '129.8828125',
  12 + x2: '103',
  13 + y2: '64.96000000000001',
  14 + datasetTspanFill: '#00F0A2',
  15 + titleTspanFill: '#FFFFFF',
  16 + datasetTspanFontSize: 30,
  17 + }
  18 +}
  19 +
  20 +export default class Config extends PublicConfigClass implements CreateComponentType {
  21 + public key = Decorates29Config.key
  22 + public attr = { ...chartInitConfig, w: 305, h: 110, zIndex: -1 }
  23 + public chartConfig = cloneDeep(Decorates29Config)
  24 + public option = cloneDeep(option)
  25 +}
  1 +<template>
  2 + <!-- Echarts 全局设置 -->
  3 + <global-setting :optionData="optionData"></global-setting>
  4 + <CollapseItem name="配置" :expanded="true">
  5 + <setting-item-box name="数据源">
  6 + <setting-item name="数据">
  7 + <n-input v-model:value="optionData.dataset" />
  8 + </setting-item>
  9 + </setting-item-box>
  10 + <SettingItemBox :name="`数据源字体配置`">
  11 + <SettingItem name="x">
  12 + <n-input-number :min="0" v-model:value="optionData.fontConfig.x1"></n-input-number>
  13 + </SettingItem>
  14 + <SettingItem name="y">
  15 + <n-input-number :min="0" v-model:value="optionData.fontConfig.y1"></n-input-number>
  16 + </SettingItem>
  17 + <SettingItem name="大小">
  18 + <n-input-number :min="0" v-model:value="optionData.fontConfig.datasetTspanFontSize"></n-input-number>
  19 + </SettingItem>
  20 + <SettingItem name="颜色">
  21 + <n-color-picker
  22 + size="small"
  23 + :modes="['hex']"
  24 + v-model:value="optionData.fontConfig.datasetTspanFill"
  25 + ></n-color-picker>
  26 + </SettingItem>
  27 + </SettingItemBox>
  28 + </CollapseItem>
  29 +</template>
  30 +
  31 +<script setup lang="ts">
  32 +import { PropType } from 'vue'
  33 +import { option } from './config'
  34 +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  35 +
  36 +defineProps({
  37 + optionData: {
  38 + type: Object as PropType<typeof option>,
  39 + required: true
  40 + }
  41 +})
  42 +</script>
  1 +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
  2 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, chartKey, conKey } = useWidgetKey('Decorates29', true)
  6 +
  7 +export const Decorates29Config: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '模块标题29',
  12 + category: ChatCategoryEnum.DECORATE,
  13 + categoryName: ChatCategoryEnumName.DECORATE,
  14 + package: PackagesCategoryEnum.DECORATES,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'decorates29.png'
  17 +}
  1 +<template>
  2 + <div class="go-content-box">
  3 + <svg
  4 + xmlns="http://www.w3.org/2000/svg"
  5 + xmlns:xlink="http://www.w3.org/1999/xlink"
  6 + :width="w"
  7 + :height="h"
  8 + viewBox="0 0 625 188"
  9 + fill="none"
  10 + >
  11 + <path
  12 + d="M625 23L103 23L103 23.04C138.72 23.54 168.05 50.35 172.45 84.98C168.59 88.55 162.6 93.75 162.64 94C162.64 94.29 168.77 98.65 173.03 101.79C169.13 137 139.12 164.46 103 164.96L103 165L625 165L625 23Z"
  13 + fill="url(#linear_fill_8429581d-818b-40fa-b8e2-65e2f7ce17f2)"
  14 + ></path>
  15 + <path
  16 + d="M173 85.5C169.44 87.88 161.71 94 163 94C161.71 94 169.03 99.42 173 101.5C170.24 126.95 157.91 141 154.61 141L595 141L595 47L153 47C155.18 47 171.69 62.91 173 85.5Z"
  17 + fill="url(#linear_fill_552846d5-6f9c-4dc7-9f6f-1867df41fd74)"
  18 + ></path>
  19 + <rect x="109" y="163" width="516" height="2" fill="url(#linear_fill_5bbe4e01-073b-4a63-b060-4cb8ef016116)"></rect>
  20 + <rect x="109" y="23" width="516" height="2" fill="url(#linear_fill_009e1028-4c17-4ca5-9439-a3ea85c86a5e)"></rect>
  21 + <g>
  22 + <path
  23 + fill="#063475"
  24 + fill-opacity="0.6"
  25 + d="M103 0C51.09 0 9 42.09 9 94C9 145.91 51.09 188 103 188C154.91 188 197 145.91 197 94C197 42.09 154.91 0 103 0Z"
  26 + ></path>
  27 + <path
  28 + fill-rule="evenodd"
  29 + fill="rgba(3, 169, 255, 0.43)"
  30 + d="M9 94C9 42.09 51.09 0 103 0C154.91 0 197 42.09 197 94C197 145.91 154.91 188 103 188C51.09 188 9 145.91 9 94ZM11 94C11 43.1898 52.1898 2 103 2C153.81 2 195 43.1898 195 94C195 144.81 153.81 186 103 186C52.1898 186 11 144.81 11 94Z"
  31 + ></path>
  32 + </g>
  33 + <path
  34 + d="M173.42 84.98C169.02 50.02 139.15 23 103 23C66.85 23 36.98 50.02 32.58 84.98C36.4 88.59 42.43 93.75 42.39 94C42.39 94.29 36.26 98.65 32 101.79C35.9 137.33 66.42 165 103 165C139.58 165 170.1 137.33 174 101.79C169.74 98.65 163.61 94.29 163.61 94C163.57 93.75 169.6 88.59 173.42 84.98Z"
  35 + fill="#0B305F"
  36 + fill-opacity="0.6"
  37 + ></path>
  38 + <g filter="url(#filter_4913fbad-67bd-4cb2-8b05-e187c1858401)">
  39 + <path
  40 + fill-rule="evenodd"
  41 + fill="rgba(27, 140, 199, 1)"
  42 + d="M103 23C139.15 23 169.02 50.02 173.42 84.98C171.698 86.6074 169.527 88.5497 167.665 90.2153C165.397 92.2444 163.588 93.8627 163.61 94C163.61 94.29 169.74 98.65 174 101.79C170.1 137.33 139.58 165 103 165C66.42 165 35.9 137.33 32 101.79C36.26 98.65 42.39 94.29 42.39 94C42.412 93.8627 40.603 92.2444 38.3349 90.2152C36.4731 88.5497 34.302 86.6074 32.58 84.98C36.98 50.02 66.85 23 103 23ZM34.6979 84.2221Q36.4313 85.8287 39.6684 88.7247Q44.0053 92.6046 44.3437 94L44.39 94Q44.39 94.0655 44.3685 94.1431Q44.3776 94.2363 44.3649 94.316L44.306 94.3066Q43.5918 95.8122 36.8034 100.756Q35.1678 101.947 34.1219 102.713Q37.2751 127.952 56.579 145.232Q76.4268 163 103 163Q129.573 163 149.421 145.232Q168.725 127.952 171.878 102.713Q170.832 101.947 169.196 100.756Q162.408 95.8121 161.694 94.3065L161.635 94.3159Q161.622 94.2363 161.631 94.1431Q161.61 94.0655 161.61 94L161.656 94Q161.995 92.6047 166.332 88.7247Q169.569 85.8287 171.302 84.2221Q167.828 59.2722 148.789 42.3759Q129.209 25 103 25Q76.7914 25 57.2113 42.3759Q38.1718 59.2721 34.6979 84.2221Z"
  43 + ></path>
  44 + </g>
  45 + <g opacity="0.2">
  46 + <g filter="url(#filter_72875209-e966-4c55-8b84-785fbe6126cc)">
  47 + <path
  48 + fill="#0B305F"
  49 + fill-opacity="0.6"
  50 + d="M163.5 86.25C159.72 56.22 134.06 33 103 33C71.94 33 46.28 56.22 42.5 86.25C45.78 89.35 50.96 93.78 50.93 94C50.93 94.25 45.66 98 42 100.7C45.35 131.23 71.57 155 103 155C134.43 155 160.65 131.23 164 100.7C160.34 98 155.07 94.25 155.07 94C155.04 93.78 160.22 89.35 163.5 86.25Z"
  51 + ></path>
  52 + <path
  53 + fill-rule="evenodd"
  54 + fill="rgba(26, 148, 214, 1)"
  55 + d="M103 33C134.06 33 159.72 56.22 163.5 86.25C162.021 87.648 160.155 89.3165 158.555 90.7473C156.608 92.4894 155.054 93.8792 155.07 94C155.07 94.25 160.34 98 164 100.7C160.65 131.23 134.43 155 103 155C71.57 155 45.35 131.23 42 100.7C45.66 98 50.93 94.25 50.93 94C50.9465 93.8792 49.3924 92.4894 47.4446 90.7473C45.8447 89.3165 43.9792 87.648 42.5 86.25C46.28 56.22 71.94 33 103 33ZM43.5575 85.8711Q45.0601 87.2732 48.1112 90.0019Q51.6678 93.1827 51.9057 94L51.93 94Q51.93 94.0283 51.9196 94.0629Q51.9253 94.1026 51.9208 94.1351L51.8923 94.1312Q51.4459 95.045 45.7197 99.2179Q44.0219 100.455 43.0592 101.162Q45.6913 123.386 62.6369 138.554Q79.8937 154 103 154Q126.106 154 143.363 138.554Q160.309 123.386 162.941 101.162Q161.977 100.455 160.28 99.218Q154.554 95.045 154.108 94.1312L154.079 94.1351Q154.075 94.1026 154.08 94.0629Q154.07 94.0283 154.07 94L154.094 94Q154.332 93.1827 157.889 90.0019Q160.94 87.2733 162.442 85.8711Q159.513 63.9305 142.816 49.1117Q125.79 34 103 34Q80.2103 34 63.1838 49.1117Q46.4873 63.9304 43.5575 85.8711Z"
  56 + ></path>
  57 + </g>
  58 + </g>
  59 + <g opacity="0.2">
  60 + <rect
  61 + x="10.606597900390625"
  62 + y="89"
  63 + width="15"
  64 + height="15"
  65 + transform="rotate(45 10.606597900390625 89)"
  66 + fill="#03A9FF"
  67 + ></rect>
  68 + </g>
  69 + <g opacity="0.2">
  70 + <rect
  71 + x="195.6099853515625"
  72 + y="89.0033950805664"
  73 + width="15"
  74 + height="15"
  75 + transform="rotate(45 195.6099853515625 89.0033950805664)"
  76 + fill="#03A9FF"
  77 + ></rect>
  78 + </g>
  79 + <g opacity="0.2">
  80 + <rect
  81 + x="10.606597900390625"
  82 + y="79"
  83 + width="15"
  84 + height="15"
  85 + transform="rotate(45 10.606597900390625 79)"
  86 + fill="#03A9FF"
  87 + ></rect>
  88 + </g>
  89 + <g opacity="0.2">
  90 + <rect
  91 + x="195.6099853515625"
  92 + y="79.0033950805664"
  93 + width="15"
  94 + height="15"
  95 + transform="rotate(45 195.6099853515625 79.0033950805664)"
  96 + fill="#03A9FF"
  97 + ></rect>
  98 + </g>
  99 + <path
  100 + fill-rule="evenodd"
  101 + fill="rgba(3, 169, 255, 1)"
  102 + d="M10.6066 105.213L-3.8147e-06 94.6066L10.6066 84L21.2132 94.6066L10.6066 105.213ZM15.5563 94.6066L10.6066 89.6569L5.65685 94.6066L10.6066 99.5564L15.5563 94.6066Z"
  103 + ></path>
  104 + <path
  105 + fill-rule="evenodd"
  106 + fill="rgba(3, 169, 255, 1)"
  107 + d="M195.61 105.217L185.003 94.61L195.61 84.0034L206.217 94.61L195.61 105.217ZM200.56 94.61L195.61 89.6602L190.66 94.61L195.61 99.5597L200.56 94.61Z"
  108 + ></path>
  109 + <g opacity="1" transform="translate(88 -26)">
  110 + <text>
  111 + <tspan
  112 + :x="fontConfig.x1"
  113 + :y="fontConfig.y1"
  114 + :font-size="fontConfig.datasetTspanFontSize"
  115 + line-height="0"
  116 + :fill="fontConfig.datasetTspanFill"
  117 + opacity="1"
  118 + font-family="Roboto-Regular"
  119 + font-weight="Regular"
  120 + letter-spacing="0"
  121 + >
  122 + {{ dataset }}
  123 + </tspan>
  124 + </text>
  125 + </g>
  126 + <g filter="url(#filter_375ad2c7-128f-4997-9ac6-7bbb64a0f289)">
  127 + <path
  128 + d="M84.9911 72.02L84.9911 63L99.9911 63L99.9911 72.16C96.1911 72.55 92.4711 73.65 89.1011 75.42L84.9911 72.02ZM116.898 75.42C113.498 73.65 109.808 72.55 105.978 72.16L105.978 63L120.978 63L120.978 72.02L116.898 75.42ZM103 126.004C89.74 126.034 79 115.284 79 102.004C79 88.7635 89.74 78.0135 103 78.0135C116.26 78.0135 127 88.7635 127 102.004C127 115.284 116.26 126.004 103 126.004ZM99.0269 96.5394L102.997 88.5194L106.967 96.5394L115.837 97.8194L109.417 104.069L110.937 112.899L102.997 108.719L95.0569 112.899L96.5869 104.069L90.1669 97.8194L99.0269 96.5394Z"
  129 + fill-rule="evenodd"
  130 + fill="url(#linear_fill_375ad2c7-128f-4997-9ac6-7bbb64a0f289)"
  131 + ></path>
  132 + </g>
  133 + <path
  134 + fill-rule="evenodd"
  135 + fill="url(#linear_fill_5d114998-6e33-4cae-9064-4cf557eef946_0)"
  136 + d="M84.9911 69.02L84.9911 60L99.9911 60L99.9911 69.16C96.1911 69.55 92.4711 70.65 89.1011 72.42L84.9911 69.02ZM116.898 72.42C113.498 70.65 109.808 69.55 105.978 69.16L105.978 60L120.978 60L120.978 69.02L116.898 72.42ZM103 123.004C89.74 123.034 79 112.284 79 99.0035C79 85.7635 89.74 75.0135 103 75.0135C116.26 75.0135 127 85.7635 127 99.0035C127 112.284 116.26 123.004 103 123.004ZM109.417 101.069L110.937 109.899L102.997 105.719L95.0569 109.899L96.5869 101.069L90.1669 94.8194L99.0269 93.5394L102.997 85.5194L106.967 93.5394L115.837 94.8194L109.417 101.069Z"
  137 + ></path>
  138 + <path
  139 + fill-rule="evenodd"
  140 + fill="rgba(159, 223, 255, 1)"
  141 + d="M84.9911 69.02L84.9911 60L99.9911 60L99.9911 69.16C96.1911 69.55 92.4711 70.65 89.1011 72.42L84.9911 69.02ZM89.2315 71.2301Q93.8202 68.9448 98.9911 68.2698L98.9911 61L85.9911 61L85.9911 68.5494L89.2315 71.2301ZM116.898 72.42C113.498 70.65 109.808 69.55 105.978 69.16L105.978 60L120.978 60L120.978 69.02L116.898 72.42ZM119.978 68.5516L119.978 61L106.978 61L106.978 68.2693Q112.128 68.9391 116.763 71.2304L119.978 68.5516ZM79 99.0035C79 112.284 89.74 123.034 103 123.004C116.26 123.004 127 112.284 127 99.0035C127 85.7635 116.26 75.0135 103 75.0135C89.74 75.0135 79 85.7635 79 99.0035ZM126 99.0035C126 111.706 115.703 122.004 103 122.004L102.998 122.004C90.2749 122.032 80 111.726 80 99.0035C80 86.301 90.2975 76.0135 103 76.0135C115.697 76.0135 126 86.3065 126 99.0035ZM109.417 101.069L110.723 108.657L110.937 109.899L109.821 109.312L102.997 105.719L96.1737 109.311L95.0569 109.899L95.2724 108.656L96.5869 101.069L91.0706 95.6992L90.1669 94.8194L91.4152 94.6391L99.0269 93.5394L102.439 86.6465L102.997 85.5194L103.555 86.6465L106.967 93.5394L114.588 94.6392L115.837 94.8194L114.933 95.6993L109.417 101.069ZM107.63 92.6247L102.997 83.2653L98.3638 92.6248L88.0148 94.1199L95.5116 101.418L93.7247 111.731L102.997 106.85L112.267 111.73L110.492 101.419L117.989 94.1196L107.63 92.6247Z"
  142 + ></path>
  143 + <defs>
  144 + <linearGradient
  145 + id="linear_fill_8429581d-818b-40fa-b8e2-65e2f7ce17f2"
  146 + x1="103"
  147 + y1="94"
  148 + x2="625"
  149 + y2="94"
  150 + gradientUnits="userSpaceOnUse"
  151 + >
  152 + <stop offset="0" stop-color="#0C3162" />
  153 + <stop offset="1" stop-color="#010E24" stop-opacity="0" />
  154 + </linearGradient>
  155 + <linearGradient
  156 + id="linear_fill_552846d5-6f9c-4dc7-9f6f-1867df41fd74"
  157 + x1="153"
  158 + y1="94"
  159 + x2="595"
  160 + y2="94"
  161 + gradientUnits="userSpaceOnUse"
  162 + >
  163 + <stop offset="0" stop-color="#0C3162" />
  164 + <stop offset="1" stop-color="#0B2F6E" stop-opacity="0" />
  165 + </linearGradient>
  166 + <linearGradient
  167 + id="linear_fill_5bbe4e01-073b-4a63-b060-4cb8ef016116"
  168 + x1="109"
  169 + y1="164"
  170 + x2="625"
  171 + y2="164"
  172 + gradientUnits="userSpaceOnUse"
  173 + >
  174 + <stop offset="0" stop-color="#1B8CC7" />
  175 + <stop offset="1" stop-color="#1B8CC7" stop-opacity="0" />
  176 + </linearGradient>
  177 + <linearGradient
  178 + id="linear_fill_009e1028-4c17-4ca5-9439-a3ea85c86a5e"
  179 + x1="109"
  180 + y1="24"
  181 + x2="625"
  182 + y2="24"
  183 + gradientUnits="userSpaceOnUse"
  184 + >
  185 + <stop offset="0" stop-color="#1B8CC7" />
  186 + <stop offset="1" stop-color="#1B8CC7" stop-opacity="0" />
  187 + </linearGradient>
  188 + <filter
  189 + id="filter_4913fbad-67bd-4cb2-8b05-e187c1858401"
  190 + x="32"
  191 + y="23"
  192 + width="142"
  193 + height="142"
  194 + filterUnits="userSpaceOnUse"
  195 + color-interpolation-filters="sRGB"
  196 + >
  197 + <feFlood flood-opacity="0" result="feFloodId_4913fbad-67bd-4cb2-8b05-e187c1858401" />
  198 + <feBlend
  199 + mode="normal"
  200 + in="SourceGraphic"
  201 + in2="feFloodId_4913fbad-67bd-4cb2-8b05-e187c1858401"
  202 + result="shape_4913fbad-67bd-4cb2-8b05-e187c1858401"
  203 + />
  204 + <feColorMatrix
  205 + in="SourceAlpha"
  206 + type="matrix"
  207 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  208 + result="hardAlpha_4913fbad-67bd-4cb2-8b05-e187c1858401"
  209 + />
  210 + <feOffset dx="0" dy="0" />
  211 + <feGaussianBlur stdDeviation="5" />
  212 + <feComposite in2="hardAlpha_4913fbad-67bd-4cb2-8b05-e187c1858401" operator="arithmetic" k2="-1" k3="1" />
  213 + <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0.7843137254901961 0 0 0 0 1 0 0 0 0.6 0" />
  214 + <feBlend
  215 + mode="normal"
  216 + in2="shape_4913fbad-67bd-4cb2-8b05-e187c1858401"
  217 + result="innerShadow_0_4913fbad-67bd-4cb2-8b05-e187c1858401"
  218 + />
  219 + </filter>
  220 + <filter
  221 + id="filter_72875209-e966-4c55-8b84-785fbe6126cc"
  222 + x="40"
  223 + y="31"
  224 + width="126"
  225 + height="126"
  226 + filterUnits="userSpaceOnUse"
  227 + color-interpolation-filters="sRGB"
  228 + >
  229 + <feFlood flood-opacity="0" result="feFloodId_72875209-e966-4c55-8b84-785fbe6126cc" />
  230 + <feBlend
  231 + mode="normal"
  232 + in="SourceGraphic"
  233 + in2="feFloodId_72875209-e966-4c55-8b84-785fbe6126cc"
  234 + result="shape"
  235 + />
  236 + <feGaussianBlur result="gaussian_blur_72875209-e966-4c55-8b84-785fbe6126cc" stdDeviation="1" />
  237 + </filter>
  238 + <linearGradient
  239 + id="linear_fill_375ad2c7-128f-4997-9ac6-7bbb64a0f289"
  240 + x1="103"
  241 + y1="126"
  242 + x2="103"
  243 + y2="63"
  244 + gradientUnits="userSpaceOnUse"
  245 + >
  246 + <stop offset="0" stop-color="#1B7BB3" />
  247 + <stop offset="1" stop-color="#2BACBA" />
  248 + </linearGradient>
  249 + <filter
  250 + id="filter_375ad2c7-128f-4997-9ac6-7bbb64a0f289"
  251 + x="69"
  252 + y="53"
  253 + width="68"
  254 + height="83.03350067138672"
  255 + filterUnits="userSpaceOnUse"
  256 + color-interpolation-filters="sRGB"
  257 + >
  258 + <feFlood flood-opacity="0" result="feFloodId_375ad2c7-128f-4997-9ac6-7bbb64a0f289" />
  259 + <feColorMatrix
  260 + in="SourceAlpha"
  261 + type="matrix"
  262 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  263 + result="hardAlpha_375ad2c7-128f-4997-9ac6-7bbb64a0f289"
  264 + />
  265 + <feOffset dx="0" dy="0" />
  266 + <feGaussianBlur stdDeviation="5" />
  267 + <feComposite in2="hardAlpha_375ad2c7-128f-4997-9ac6-7bbb64a0f289" operator="out" />
  268 + <feColorMatrix
  269 + type="matrix"
  270 + values="0 0 0 0 0.27058823529411763 0 0 0 0 0.7803921568627451 0 0 0 0 1 0 0 0 0.5 0"
  271 + />
  272 + <feBlend
  273 + mode="normal"
  274 + in2="feFloodId_375ad2c7-128f-4997-9ac6-7bbb64a0f289"
  275 + result="dropShadow_1_375ad2c7-128f-4997-9ac6-7bbb64a0f289"
  276 + />
  277 + <feBlend
  278 + mode="normal"
  279 + in="SourceGraphic"
  280 + in2="dropShadow_1_375ad2c7-128f-4997-9ac6-7bbb64a0f289"
  281 + result="shape_375ad2c7-128f-4997-9ac6-7bbb64a0f289"
  282 + />
  283 + </filter>
  284 + <linearGradient
  285 + id="linear_fill_5d114998-6e33-4cae-9064-4cf557eef946_0"
  286 + x1="103"
  287 + y1="123"
  288 + x2="103"
  289 + y2="60"
  290 + gradientUnits="userSpaceOnUse"
  291 + >
  292 + <stop offset="0" stop-color="#3AB4F9" />
  293 + <stop offset="1" stop-color="#6DD0DA" />
  294 + </linearGradient>
  295 + </defs>
  296 + </svg>
  297 + </div>
  298 +</template>
  299 +<script setup lang="ts">
  300 +import { PropType, toRefs } from 'vue'
  301 +import { CreateComponentType } from '@/packages/index.d'
  302 +import { option } from './config'
  303 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  304 +import { useChartDataFetch } from '@/hooks'
  305 +import { isObject } from '@/utils/external/is'
  306 +
  307 +const props = defineProps({
  308 + chartConfig: {
  309 + type: Object as PropType<CreateComponentType & typeof option>,
  310 + required: true
  311 + }
  312 +})
  313 +
  314 +const { w, h } = toRefs(props.chartConfig.attr)
  315 +
  316 +const { dataset, fontConfig } = toRefs(props.chartConfig.option as typeof option)
  317 +
  318 +// 预览更新
  319 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
  320 + if (isObject(newData)) return
  321 + dataset.value = newData as string
  322 +})
  323 +</script>
  324 +
  325 +<style lang="scss" scoped>
  326 +.go-content-box {
  327 + width: v-bind('w+"px"');
  328 + height: v-bind('h+"px"');
  329 + display: flex;
  330 + align-items: center;
  331 + justify-content: center;
  332 +}
  333 +</style>
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { Decorates30Config } from './index'
  3 +import { CreateComponentType } from '@/packages/index.d'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
  6 +
  7 +export const option = {
  8 + dataset: '32',
  9 + unitStr: '个',
  10 + titleStr: '设备总数',
  11 + fontConfig: {
  12 + x1: '320', //数据源
  13 + y1: '80',
  14 + x2: '366', //单位
  15 + y2: '79',
  16 + x3: '11', //标题
  17 + y3: '79',
  18 + datasetTspanFill: '#00F0A2',
  19 + titleTspanFill: '#FFFFFF',
  20 + unitTspanFill: '#FFFFFF',
  21 + datasetTspanFontSize: 30,
  22 + titleTspanFontSize: 30,
  23 + unitTspanFontSize: 30
  24 + }
  25 +}
  26 +
  27 +export default class Config extends PublicConfigClass implements CreateComponentType {
  28 + public key = Decorates30Config.key
  29 + public attr = { ...chartInitConfig, w: 305, h: 110, zIndex: -1 }
  30 + public chartConfig = cloneDeep(Decorates30Config)
  31 + public option = cloneDeep(option)
  32 +}
  1 +<template>
  2 + <!-- Echarts 全局设置 -->
  3 + <global-setting :optionData="optionData"></global-setting>
  4 + <CollapseItem name="配置" :expanded="true">
  5 + <setting-item-box name="数据源">
  6 + <setting-item name="数据">
  7 + <n-input v-model:value="optionData.dataset" />
  8 + </setting-item>
  9 + <setting-item name="单位">
  10 + <n-input v-model:value="optionData.unitStr" />
  11 + </setting-item>
  12 + <setting-item name="标题">
  13 + <n-input v-model:value="optionData.titleStr" />
  14 + </setting-item>
  15 + </setting-item-box>
  16 + <SettingItemBox :name="`单位字体配置`">
  17 + <SettingItem name="x">
  18 + <n-input-number :min="0" v-model:value="optionData.fontConfig.x2"></n-input-number>
  19 + </SettingItem>
  20 + <SettingItem name="y">
  21 + <n-input-number :min="0" v-model:value="optionData.fontConfig.y2"></n-input-number>
  22 + </SettingItem>
  23 + <SettingItem name="大小">
  24 + <n-input-number :min="0" v-model:value="optionData.fontConfig.unitTspanFontSize"></n-input-number>
  25 + </SettingItem>
  26 + <SettingItem name="颜色">
  27 + <n-color-picker
  28 + size="small"
  29 + :modes="['hex']"
  30 + v-model:value="optionData.fontConfig.unitTspanFill"
  31 + ></n-color-picker>
  32 + </SettingItem>
  33 + </SettingItemBox>
  34 + <SettingItemBox :name="`数据源字体配置`">
  35 + <SettingItem name="x">
  36 + <n-input-number :min="0" v-model:value="optionData.fontConfig.x1"></n-input-number>
  37 + </SettingItem>
  38 + <SettingItem name="y">
  39 + <n-input-number :min="0" v-model:value="optionData.fontConfig.y1"></n-input-number>
  40 + </SettingItem>
  41 + <SettingItem name="大小">
  42 + <n-input-number :min="0" v-model:value="optionData.fontConfig.datasetTspanFontSize"></n-input-number>
  43 + </SettingItem>
  44 + <SettingItem name="颜色">
  45 + <n-color-picker
  46 + size="small"
  47 + :modes="['hex']"
  48 + v-model:value="optionData.fontConfig.datasetTspanFill"
  49 + ></n-color-picker>
  50 + </SettingItem>
  51 + </SettingItemBox>
  52 + <SettingItemBox :name="`标题字体配置`">
  53 + <SettingItem name="x">
  54 + <n-input-number :min="0" v-model:value="optionData.fontConfig.x3"></n-input-number>
  55 + </SettingItem>
  56 + <SettingItem name="y">
  57 + <n-input-number :min="0" v-model:value="optionData.fontConfig.y3"></n-input-number>
  58 + </SettingItem>
  59 + <SettingItem name="大小">
  60 + <n-input-number :min="0" v-model:value="optionData.fontConfig.titleTspanFontSize"></n-input-number>
  61 + </SettingItem>
  62 + <SettingItem name="颜色">
  63 + <n-color-picker
  64 + size="small"
  65 + :modes="['hex']"
  66 + v-model:value="optionData.fontConfig.titleTspanFill"
  67 + ></n-color-picker>
  68 + </SettingItem>
  69 + </SettingItemBox>
  70 + </CollapseItem>
  71 +</template>
  72 +
  73 +<script setup lang="ts">
  74 +import { PropType } from 'vue'
  75 +import { option } from './config'
  76 +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  77 +
  78 +defineProps({
  79 + optionData: {
  80 + type: Object as PropType<typeof option>,
  81 + required: true
  82 + }
  83 +})
  84 +</script>
  1 +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
  2 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, chartKey, conKey } = useWidgetKey('Decorates30', true)
  6 +
  7 +export const Decorates30Config: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '数据标题30',
  12 + category: ChatCategoryEnum.DECORATE,
  13 + categoryName: ChatCategoryEnumName.DECORATE,
  14 + package: PackagesCategoryEnum.DECORATES,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'decorates30.png'
  17 +}
  1 +<template>
  2 + <div class="go-content-box">
  3 + <svg
  4 + xmlns="http://www.w3.org/2000/svg"
  5 + xmlns:xlink="http://www.w3.org/1999/xlink"
  6 + :width="w"
  7 + :height="h"
  8 + viewBox="0 0 442 141"
  9 + fill="none"
  10 + >
  11 + <g>
  12 + <g filter="url(#filter_95b2f60e-40ab-42fb-81a1-c50e11e63c01)">
  13 + <rect x="11" y="19" width="429" height="120" fill="#012651" fill-opacity="0.5"></rect>
  14 + <path
  15 + fill-rule="evenodd"
  16 + fill="rgba(1, 80, 152, 1)"
  17 + d="M440 139L11 139L11 19L440 19L440 139ZM438 21L13 21L13 137L438 137L438 21Z"
  18 + ></path>
  19 + </g>
  20 + </g>
  21 + <rect x="0" y="11" width="429" height="120" fill="#012651" fill-opacity="0.5"></rect>
  22 + <g filter="url(#filter_edebad1d-8cf8-4ddf-87ba-cceec465951b)">
  23 + <path
  24 + fill-rule="evenodd"
  25 + fill="rgba(1, 80, 152, 1)"
  26 + d="M429 131L0 131L0 11L429 11L429 131ZM427 13L2 13L2 129L427 129L427 13Z"
  27 + ></path>
  28 + </g>
  29 + <path d="M0 7.2L370 7.2L366.29 3.76L127.79 3.76L122.29 0L3.79 0.59L0 7.2Z" fill="#008AFF"></path>
  30 + <rect x="417" y="1.199951171875" width="11" height="6" fill="#00FDC7"></rect>
  31 + <rect x="12" y="20" width="6" height="6" fill="#00EEFD"></rect>
  32 + <g opacity="0.5">
  33 + <rect x="24" y="20" width="6" height="6" fill="#00EEFD"></rect>
  34 + </g>
  35 + <g opacity="0.2">
  36 + <rect x="36" y="20" width="6" height="6" fill="#00EEFD"></rect>
  37 + </g>
  38 + <rect x="399" y="1.199951171875" width="11" height="6" fill="#00FDC7" fill-opacity="0.6"></rect>
  39 + <rect x="381" y="1.199951171875" width="11" height="6" fill="#00FDC7" fill-opacity="0.2"></rect>
  40 + <path d="M403 131L429 131L429 102L403 131Z" fill="#00B5C6"></path>
  41 + <path
  42 + d="M3 129L31.5 129L87.5 13L59 13L3 129Z"
  43 + fill="url(#linear_fill_d377d882-63b6-4b2f-b075-f04757ddaaf2)"
  44 + ></path>
  45 + <path
  46 + d="M51.8571 129L80.3571 129L136.357 13L107.857 13L51.8571 129Z"
  47 + fill="url(#linear_fill_bffa1776-bd2b-433f-8c5d-b7a711801df9)"
  48 + ></path>
  49 + <path
  50 + d="M100.714 129L129.214 129L185.214 13L156.714 13L100.714 129Z"
  51 + fill="url(#linear_fill_c9bca278-5d80-4ff7-ba93-f353162e7011)"
  52 + ></path>
  53 + <path
  54 + d="M149.571 129L178.071 129L234.071 13L205.571 13L149.571 129Z"
  55 + fill="url(#linear_fill_8c82d359-5e14-4e92-a053-701212e20ddb)"
  56 + ></path>
  57 + <path
  58 + d="M198.429 129L226.929 129L282.929 13L254.429 13L198.429 129Z"
  59 + fill="url(#linear_fill_c1497f7e-7db6-469b-916e-03fb85481d4e)"
  60 + ></path>
  61 + <path
  62 + d="M247.286 129L275.786 129L331.786 13L303.286 13L247.286 129Z"
  63 + fill="url(#linear_fill_52ee754d-41b8-4575-9561-981422976caa)"
  64 + ></path>
  65 + <path
  66 + d="M296.143 129L324.643 129L380.643 13L352.143 13L296.143 129Z"
  67 + fill="url(#linear_fill_3febdb91-9c5c-4985-97d3-16ec34fa4b5c)"
  68 + ></path>
  69 + <path
  70 + d="M345 129L373.5 129L429.5 13L401 13L345 129Z"
  71 + fill="url(#linear_fill_bd8f0060-6382-48ce-9408-29c6216ec4cc)"
  72 + ></path>
  73 + <g>
  74 + <text>
  75 + <tspan
  76 + :x="fontConfig.x3"
  77 + :y="fontConfig.y3"
  78 + :font-size="fontConfig.titleTspanFontSize"
  79 + line-height="0"
  80 + :fill="fontConfig.titleTspanFill"
  81 + opacity="1"
  82 + font-family="Roboto-Regular"
  83 + font-weight="Regular"
  84 + letter-spacing="0"
  85 + >
  86 + {{ titleStr }}
  87 + </tspan>
  88 + </text>
  89 + </g>
  90 + <g opacity="0.8">
  91 + <text>
  92 + <tspan
  93 + :x="fontConfig.x2"
  94 + :y="fontConfig.y2"
  95 + :font-size="fontConfig.unitTspanFontSize"
  96 + line-height="0"
  97 + :fill="fontConfig.unitTspanFill"
  98 + opacity="1"
  99 + font-family="Roboto-Regular"
  100 + font-weight="Regular"
  101 + letter-spacing="0"
  102 + >
  103 + {{ unitStr }}
  104 + </tspan>
  105 + </text>
  106 + </g>
  107 + <g>
  108 + <text>
  109 + <tspan
  110 + :x="fontConfig.x1"
  111 + :y="fontConfig.y1"
  112 + :font-size="fontConfig.datasetTspanFontSize"
  113 + line-height="0"
  114 + :fill="fontConfig.datasetTspanFill"
  115 + opacity="1"
  116 + font-family="Roboto-Regular"
  117 + font-weight="Regular"
  118 + letter-spacing="0"
  119 + >
  120 + {{ dataset }}
  121 + </tspan>
  122 + </text>
  123 + </g>
  124 + <defs>
  125 + <filter
  126 + id="filter_95b2f60e-40ab-42fb-81a1-c50e11e63c01"
  127 + x="9"
  128 + y="17"
  129 + width="433"
  130 + height="124"
  131 + filterUnits="userSpaceOnUse"
  132 + color-interpolation-filters="sRGB"
  133 + >
  134 + <feFlood flood-opacity="0" result="feFloodId_95b2f60e-40ab-42fb-81a1-c50e11e63c01" />
  135 + <feBlend
  136 + mode="normal"
  137 + in="SourceGraphic"
  138 + in2="feFloodId_95b2f60e-40ab-42fb-81a1-c50e11e63c01"
  139 + result="shape"
  140 + />
  141 + <feGaussianBlur result="gaussian_blur_95b2f60e-40ab-42fb-81a1-c50e11e63c01" stdDeviation="1" />
  142 + </filter>
  143 + <filter
  144 + id="filter_edebad1d-8cf8-4ddf-87ba-cceec465951b"
  145 + x="0"
  146 + y="11"
  147 + width="429"
  148 + height="120"
  149 + filterUnits="userSpaceOnUse"
  150 + color-interpolation-filters="sRGB"
  151 + >
  152 + <feFlood flood-opacity="0" result="feFloodId_edebad1d-8cf8-4ddf-87ba-cceec465951b" />
  153 + <feBlend
  154 + mode="normal"
  155 + in="SourceGraphic"
  156 + in2="feFloodId_edebad1d-8cf8-4ddf-87ba-cceec465951b"
  157 + result="shape_edebad1d-8cf8-4ddf-87ba-cceec465951b"
  158 + />
  159 + <feColorMatrix
  160 + in="SourceAlpha"
  161 + type="matrix"
  162 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  163 + result="hardAlpha_edebad1d-8cf8-4ddf-87ba-cceec465951b"
  164 + />
  165 + <feOffset dx="0" dy="0" />
  166 + <feGaussianBlur stdDeviation="5" />
  167 + <feComposite in2="hardAlpha_edebad1d-8cf8-4ddf-87ba-cceec465951b" operator="arithmetic" k2="-1" k3="1" />
  168 + <feColorMatrix
  169 + type="matrix"
  170 + values="0 0 0 0 0 0 0 0 0 0.9333333333333333 0 0 0 0 0.9921568627450981 0 0 0 0.5 0"
  171 + />
  172 + <feBlend
  173 + mode="normal"
  174 + in2="shape_edebad1d-8cf8-4ddf-87ba-cceec465951b"
  175 + result="innerShadow_0_edebad1d-8cf8-4ddf-87ba-cceec465951b"
  176 + />
  177 + </filter>
  178 + <linearGradient
  179 + id="linear_fill_d377d882-63b6-4b2f-b075-f04757ddaaf2"
  180 + x1="25.0595703125"
  181 + y1="129"
  182 + x2="74.54360961914062"
  183 + y2="32.833740234375"
  184 + gradientUnits="userSpaceOnUse"
  185 + >
  186 + <stop offset="0" stop-color="#2466BD" stop-opacity="0.2" />
  187 + <stop offset="1" stop-color="#2466BD" stop-opacity="0" />
  188 + </linearGradient>
  189 + <linearGradient
  190 + id="linear_fill_bffa1776-bd2b-433f-8c5d-b7a711801df9"
  191 + x1="73.91671752929688"
  192 + y1="129"
  193 + x2="123.4007568359375"
  194 + y2="32.833740234375"
  195 + gradientUnits="userSpaceOnUse"
  196 + >
  197 + <stop offset="0" stop-color="#2466BD" stop-opacity="0.2" />
  198 + <stop offset="1" stop-color="#2466BD" stop-opacity="0" />
  199 + </linearGradient>
  200 + <linearGradient
  201 + id="linear_fill_c9bca278-5d80-4ff7-ba93-f353162e7011"
  202 + x1="122.77386474609375"
  203 + y1="129"
  204 + x2="172.25790405273438"
  205 + y2="32.833740234375"
  206 + gradientUnits="userSpaceOnUse"
  207 + >
  208 + <stop offset="0" stop-color="#2466BD" stop-opacity="0.2" />
  209 + <stop offset="1" stop-color="#2466BD" stop-opacity="0" />
  210 + </linearGradient>
  211 + <linearGradient
  212 + id="linear_fill_8c82d359-5e14-4e92-a053-701212e20ddb"
  213 + x1="171.6309814453125"
  214 + y1="129"
  215 + x2="221.11502075195312"
  216 + y2="32.833740234375"
  217 + gradientUnits="userSpaceOnUse"
  218 + >
  219 + <stop offset="0" stop-color="#2466BD" stop-opacity="0.2" />
  220 + <stop offset="1" stop-color="#2466BD" stop-opacity="0" />
  221 + </linearGradient>
  222 + <linearGradient
  223 + id="linear_fill_c1497f7e-7db6-469b-916e-03fb85481d4e"
  224 + x1="220.4881591796875"
  225 + y1="129"
  226 + x2="269.9721984863281"
  227 + y2="32.833740234375"
  228 + gradientUnits="userSpaceOnUse"
  229 + >
  230 + <stop offset="0" stop-color="#2466BD" stop-opacity="0.2" />
  231 + <stop offset="1" stop-color="#2466BD" stop-opacity="0" />
  232 + </linearGradient>
  233 + <linearGradient
  234 + id="linear_fill_52ee754d-41b8-4575-9561-981422976caa"
  235 + x1="269.34527587890625"
  236 + y1="129"
  237 + x2="318.8293151855469"
  238 + y2="32.833740234375"
  239 + gradientUnits="userSpaceOnUse"
  240 + >
  241 + <stop offset="0" stop-color="#2466BD" stop-opacity="0.2" />
  242 + <stop offset="1" stop-color="#2466BD" stop-opacity="0" />
  243 + </linearGradient>
  244 + <linearGradient
  245 + id="linear_fill_3febdb91-9c5c-4985-97d3-16ec34fa4b5c"
  246 + x1="318.2024230957031"
  247 + y1="129"
  248 + x2="367.68646240234375"
  249 + y2="32.833740234375"
  250 + gradientUnits="userSpaceOnUse"
  251 + >
  252 + <stop offset="0" stop-color="#2466BD" stop-opacity="0.2" />
  253 + <stop offset="1" stop-color="#2466BD" stop-opacity="0" />
  254 + </linearGradient>
  255 + <linearGradient
  256 + id="linear_fill_bd8f0060-6382-48ce-9408-29c6216ec4cc"
  257 + x1="367.0595703125"
  258 + y1="129"
  259 + x2="416.5435791015625"
  260 + y2="32.833740234375"
  261 + gradientUnits="userSpaceOnUse"
  262 + >
  263 + <stop offset="0" stop-color="#2466BD" stop-opacity="0.2" />
  264 + <stop offset="1" stop-color="#2466BD" stop-opacity="0" />
  265 + </linearGradient>
  266 + </defs>
  267 + </svg>
  268 + </div>
  269 +</template>
  270 +<script setup lang="ts">
  271 +import { PropType, toRefs } from 'vue'
  272 +import { CreateComponentType } from '@/packages/index.d'
  273 +import { option } from './config'
  274 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  275 +import { useChartDataFetch } from '@/hooks'
  276 +import { isObject } from '@/utils/external/is'
  277 +
  278 +const props = defineProps({
  279 + chartConfig: {
  280 + type: Object as PropType<CreateComponentType & typeof option>,
  281 + required: true
  282 + }
  283 +})
  284 +
  285 +const { w, h } = toRefs(props.chartConfig.attr)
  286 +
  287 +const { dataset, fontConfig, unitStr, titleStr } = toRefs(props.chartConfig.option as typeof option)
  288 +
  289 +// 预览更新
  290 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
  291 + if (isObject(newData)) return
  292 + dataset.value = newData as string
  293 +})
  294 +</script>
  295 +
  296 +<style lang="scss" scoped>
  297 +.go-content-box {
  298 + width: v-bind('w+"px"');
  299 + height: v-bind('h+"px"');
  300 + display: flex;
  301 + align-items: center;
  302 + justify-content: center;
  303 +}
  304 +</style>
@@ -71,7 +71,6 @@ const onChange = (v: number | number[] | null) => { @@ -71,7 +71,6 @@ const onChange = (v: number | number[] | null) => {
71 dateEnd = dayjs(lastTs).set('hour', 23).set('minute', 59).set('second', 59).valueOf() 71 dateEnd = dayjs(lastTs).set('hour', 23).set('minute', 59).set('second', 59).valueOf()
72 } 72 }
73 } 73 }
74 - console.log(daterange)  
75 // 存储到联动数据 74 // 存储到联动数据
76 useChartInteract( 75 useChartInteract(
77 props.chartConfig, 76 props.chartConfig,
@@ -2,11 +2,12 @@ import { PublicConfigClass } from '@/packages/public' @@ -2,11 +2,12 @@ import { PublicConfigClass } from '@/packages/public'
2 import { CreateComponentType } from '@/packages/index.d' 2 import { CreateComponentType } from '@/packages/index.d'
3 import { SingleCameraConfig } from './index' 3 import { SingleCameraConfig } from './index'
4 import cloneDeep from 'lodash/cloneDeep' 4 import cloneDeep from 'lodash/cloneDeep'
5 -import {StreamType} from "@/components/Video/src/types";  
6 -import {useFingerprint} from "@/utils/external/useFingerprint";  
7 -import {getOpenFlvPlayUrl, getVideoControlStart} from "@/api/external/flvPlay";  
8 -import {getVideoUrl} from "@/api/external/common";  
9 -import {CameraRecord} from "@/api/external/common/model"; 5 +import { StreamType } from "@/components/Video/src/types";
  6 +import { useFingerprint } from "@/utils/external/useFingerprint";
  7 +import { getOpenFlvPlayUrl, getVideoControlStart } from "@/api/external/flvPlay";
  8 +import { getVideoUrl } from "@/api/external/common";
  9 +import { CameraRecord } from "@/api/external/common/model";
  10 +import { useGlobSetting } from '@/hooks/external/setting';
10 11
11 export enum sourceTypeEnum { 12 export enum sourceTypeEnum {
12 CUSTOM = 'custom', 13 CUSTOM = 'custom',
@@ -89,7 +90,7 @@ export const isRtspProtocol = (url: string) => { @@ -89,7 +90,7 @@ export const isRtspProtocol = (url: string) => {
89 }; 90 };
90 91
91 export async function getPlayUrl( 92 export async function getPlayUrl(
92 - params: CameraRecord 93 + params: CameraRecord
93 ): Promise<{ url: string; type: StreamType } | undefined> { 94 ): Promise<{ url: string; type: StreamType } | undefined> {
94 const { accessMode } = params; 95 const { accessMode } = params;
95 if (accessMode === AccessMode.ManuallyEnter) { 96 if (accessMode === AccessMode.ManuallyEnter) {
@@ -106,18 +107,20 @@ export async function getPlayUrl( @@ -106,18 +107,20 @@ export async function getPlayUrl(
106 } 107 }
107 } 108 }
108 } else if (accessMode === AccessMode.GBT28181) { 109 } else if (accessMode === AccessMode.GBT28181) {
  110 + const { securityPolicy } = useGlobSetting()
  111 + console.log(useGlobSetting())
109 const { deviceId, channelNo } = params?.params || {}; 112 const { deviceId, channelNo } = params?.params || {};
110 const result = await getVideoControlStart({ channelId: channelNo!, deviceId: deviceId! }); 113 const result = await getVideoControlStart({ channelId: channelNo!, deviceId: deviceId! });
111 - return { url: result.data.flv, type: 'flv' }; 114 + return { url: securityPolicy ? result.data.https_flv : result.data.flv, type: 'flv' };
112 } else { 115 } else {
113 const { id, playProtocol } = params; 116 const { id, playProtocol } = params;
114 const result = await getVideoUrl(id); 117 const result = await getVideoUrl(id);
115 const type: StreamType = 118 const type: StreamType =
116 - playProtocol === FluoriteMideaProtocolEnum.FLV  
117 - ? 'flv'  
118 - : playProtocol === FluoriteMideaProtocolEnum.HLS  
119 - ? 'hls'  
120 - : 'auto'; 119 + playProtocol === FluoriteMideaProtocolEnum.FLV
  120 + ? 'flv'
  121 + : playProtocol === FluoriteMideaProtocolEnum.HLS
  122 + ? 'hls'
  123 + : 'auto';
121 return { url: result.data.url, type }; 124 return { url: result.data.url, type };
122 } 125 }
123 } 126 }
1 <template> 1 <template>
2 <div> 2 <div>
3 <n-spin size="medium" :show="showLoading" class="player-spin"> 3 <n-spin size="medium" :show="showLoading" class="player-spin">
4 - <XGPlayer :url="sourceUrl" :stream-type="playType"  
5 - :config="{width: '100%', height: '100%', poster: option.poster}"  
6 - :auto-play="option.autoplay"/> 4 + <XGPlayer
  5 + ref="XGPlayerRef"
  6 + @userAction="handleOnUserAction"
  7 + :url="sourceUrl"
  8 + :stream-type="playType"
  9 + :config="{ width: '100%', height: '100%', poster: poster }"
  10 + :auto-play="autoplay"
  11 + />
7 </n-spin> 12 </n-spin>
8 </div> 13 </div>
9 </template> 14 </template>
10 <script setup lang="ts"> 15 <script setup lang="ts">
11 -import {PropType, toRefs, shallowReactive, watch, ref} from 'vue'  
12 -import {CreateComponentType} from '@/packages/index.d'  
13 -import {Dataset, getPlayUrl, option as configOption} from './config'  
14 -import {XGPlayer} from '@/components/Video'  
15 -import {StreamType} from "@/components/Video/src/types";  
16 -import {CameraRecord} from "@/api/external/common/model";  
17 -import { isNullOrUnDef } from '@/utils/external/is'; 16 +import { PropType, toRefs, shallowReactive, watch, ref, nextTick } from 'vue'
  17 +import { CreateComponentType } from '@/packages/index.d'
  18 +import { Dataset, getPlayUrl, option as configOption } from './config'
  19 +import { XGPlayer } from '@/components/Video'
  20 +import { StreamType, UserActionEventType } from '@/components/Video/src/types'
  21 +import { CameraRecord } from '@/api/external/common/model'
  22 +import { isNullOrUnDef } from '@/utils/external/is'
18 23
19 const props = defineProps({ 24 const props = defineProps({
20 chartConfig: { 25 chartConfig: {
@@ -25,9 +30,11 @@ const props = defineProps({ @@ -25,9 +30,11 @@ const props = defineProps({
25 30
26 const showLoading = ref(false) 31 const showLoading = ref(false)
27 32
28 -const {w, h} = toRefs(props.chartConfig.attr) 33 +const XGPlayerRef = ref<InstanceType<typeof XGPlayer>>()
29 34
30 -const {autoplay, dataset, poster, customVideoUrl} = toRefs(props.chartConfig.option as typeof configOption) 35 +const { w, h } = toRefs(props.chartConfig.attr)
  36 +
  37 +const { autoplay, dataset, poster, customVideoUrl } = toRefs(props.chartConfig.option as typeof configOption)
31 38
32 const option = shallowReactive({ 39 const option = shallowReactive({
33 dataset: configOption.dataset, 40 dataset: configOption.dataset,
@@ -36,36 +43,55 @@ const option = shallowReactive({ @@ -36,36 +43,55 @@ const option = shallowReactive({
36 }) 43 })
37 44
38 const sourceUrl = ref('') 45 const sourceUrl = ref('')
39 -const playType = ref<StreamType>()  
40 46
  47 +const playType = ref<StreamType>()
41 48
42 async function getPlaySource(params: Dataset) { 49 async function getPlaySource(params: Dataset) {
43 - const {id, channelId, deviceId, accessMode, customUrl, playProtocol} = params  
44 - if (isNullOrUnDef(accessMode)) return  
45 - const {type, url} = await getPlayUrl({ 50 + if (!autoplay.value) return
  51 + doPlaySource(params)
  52 +}
  53 +
  54 +async function doPlaySource(params?: Dataset) {
  55 + const { id, channelId, deviceId, accessMode, customUrl, playProtocol } = params as unknown as Dataset
  56 + if (isNullOrUnDef(accessMode)) return
  57 + const { type, url } =
  58 + (await getPlayUrl({
46 id: id, 59 id: id,
47 accessMode: accessMode, 60 accessMode: accessMode,
48 playProtocol: playProtocol, 61 playProtocol: playProtocol,
49 videoUrl: customUrl, 62 videoUrl: customUrl,
50 params: { 63 params: {
51 deviceId: deviceId, 64 deviceId: deviceId,
52 - channelNo: channelId,  
53 - },  
54 - } as unknown as CameraRecord) || {}  
55 - sourceUrl.value = url!  
56 - playType.value = type 65 + channelNo: channelId
  66 + }
  67 + } as unknown as CameraRecord)) || {}
  68 + sourceUrl.value = url!
  69 + playType.value = type
  70 +}
  71 +
  72 +function handleOnUserAction(event: UserActionEventType) {
  73 + const { from, to } = event
  74 + if (from && !to) {
  75 + doPlaySource(dataset?.value)
  76 + nextTick(() => {
  77 + XGPlayerRef.value?.getPlayerInstance()?.play()
  78 + })
  79 + } else if (!from && to) {
  80 + nextTick(() => {
  81 + XGPlayerRef.value?.getPlayerInstance()?.pause()
  82 + })
  83 + }
57 } 84 }
58 85
59 watch( 86 watch(
60 - () => dataset?.value,  
61 - async (newData) => {  
62 - getPlaySource(newData)  
63 - },  
64 - {  
65 - immediate: true  
66 - } 87 + () => dataset?.value,
  88 + async newData => {
  89 + getPlaySource(newData)
  90 + },
  91 + {
  92 + immediate: true
  93 + }
67 ) 94 )
68 -  
69 </script> 95 </script>
70 96
71 <style lang="scss" scoped> 97 <style lang="scss" scoped>
@@ -36,8 +36,8 @@ export const option = { @@ -36,8 +36,8 @@ export const option = {
36 fontWeight: 'normal', 36 fontWeight: 'normal',
37 37
38 // 边框 38 // 边框
39 - borderWidth: 0,  
40 - borderColor: '#ffffff', 39 + borderWidth: 1,
  40 + borderColor: '#3c7eff',
41 borderRadius: 5, 41 borderRadius: 5,
42 42
43 // 字间距 43 // 字间距
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { CreateComponentType } from '@/packages/index.d'
  3 +import { OverrideTextEnumCommonConfig } from './index'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
  6 +
  7 +export enum WritingModeEnum {
  8 + HORIZONTAL = '水平',
  9 + VERTICAL = '垂直'
  10 +}
  11 +
  12 +export const WritingModeObject = {
  13 + [WritingModeEnum.HORIZONTAL]: 'horizontal-tb',
  14 + [WritingModeEnum.VERTICAL]: 'vertical-rl'
  15 +}
  16 +
  17 +export enum FontWeightEnum {
  18 + NORMAL = '常规',
  19 + BOLD = '加粗'
  20 +}
  21 +
  22 +export const FontWeightObject = {
  23 + [FontWeightEnum.NORMAL]: 'normal',
  24 + [FontWeightEnum.BOLD]: 'bold'
  25 +}
  26 +
  27 +export const option = {
  28 + link: '',
  29 + linkHead: 'http://',
  30 + dataset: '我是文本',
  31 + fontSize: 20,
  32 + fontColor: '#ffffff',
  33 + paddingX: 10,
  34 + paddingY: 10,
  35 + textAlign: 'center', // 水平对齐方式
  36 + fontWeight: 'normal',
  37 +
  38 + // 边框
  39 + borderWidth: 1,
  40 + borderColor: '#3c7eff',
  41 + borderRadius: 5,
  42 +
  43 + // 字间距
  44 + letterSpacing: 5,
  45 + writingMode: 'horizontal-tb',
  46 + backgroundColor: '#00000000',
  47 +
  48 + //跳转方式
  49 + linkMethod: 'default'
  50 +}
  51 +
  52 +export default class Config extends PublicConfigClass implements CreateComponentType {
  53 + public key = OverrideTextEnumCommonConfig.key
  54 + public attr = { ...chartInitConfig, w: 150, h: 40, zIndex: -1 }
  55 + public chartConfig = cloneDeep(OverrideTextEnumCommonConfig)
  56 + public option = cloneDeep(option)
  57 +}
  1 +<template>
  2 + <collapse-item name="信息" :expanded="true">
  3 + <setting-item-box name="文字" :alone="true">
  4 + <setting-item>
  5 + <n-input v-model:value="optionData.dataset" type="textarea" size="small"></n-input>
  6 + </setting-item>
  7 + </setting-item-box>
  8 + <setting-item-box name="链接" :alone="true">
  9 + <setting-item>
  10 + <n-input-group>
  11 + <n-select
  12 + v-model:value="optionData.linkHead"
  13 + size="small"
  14 + :style="{ width: '80%' }"
  15 + :options="linkHeadOptions"
  16 + />
  17 + <n-input v-model:value="optionData.link" size="small"></n-input>
  18 + </n-input-group>
  19 + </setting-item>
  20 + </setting-item-box>
  21 + <setting-item-box name="跳转方式" :alone="true">
  22 + <setting-item>
  23 + <n-input-group>
  24 + <n-select
  25 + v-model:value="optionData.linkMethod"
  26 + size="small"
  27 + :style="{ width: '80%' }"
  28 + :options="linkMethodOptions"
  29 + />
  30 + <n-button
  31 + :disabled="!optionData.linkMethod"
  32 + secondary
  33 + size="small"
  34 + @click="handleLinkClick(optionData.linkMethod)"
  35 + >跳转</n-button
  36 + >
  37 + </n-input-group>
  38 + </setting-item>
  39 + </setting-item-box>
  40 + </collapse-item>
  41 +
  42 + <collapse-item name="样式" :expanded="true">
  43 + <setting-item-box name="文字">
  44 + <setting-item name="颜色">
  45 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.fontColor"></n-color-picker>
  46 + </setting-item>
  47 + <setting-item name="字体大小">
  48 + <n-input-number v-model:value="optionData.fontSize" size="small" placeholder="字体大小"></n-input-number>
  49 + </setting-item>
  50 + <setting-item name="字体粗细">
  51 + <n-select v-model:value="optionData.fontWeight" size="small" :options="fontWeightOptions" />
  52 + </setting-item>
  53 + <setting-item name="X轴内边距">
  54 + <n-input-number v-model:value="optionData.paddingX" size="small" placeholder="输入内边距"></n-input-number>
  55 + </setting-item>
  56 + <setting-item name="Y轴内边距">
  57 + <n-input-number v-model:value="optionData.paddingY" size="small" placeholder="输入内边距"></n-input-number>
  58 + </setting-item>
  59 +
  60 + <setting-item name="水平对齐">
  61 + <n-select v-model:value="optionData.textAlign" size="small" :options="textAlignOptions" />
  62 + </setting-item>
  63 + <setting-item name="文本方向">
  64 + <n-select v-model:value="optionData.writingMode" size="small" :options="verticalOptions" />
  65 + </setting-item>
  66 +
  67 + <setting-item name="字间距">
  68 + <n-input-number v-model:value="optionData.letterSpacing" size="small" placeholder="输入字间距"></n-input-number>
  69 + </setting-item>
  70 + </setting-item-box>
  71 +
  72 + <setting-item-box name="边框">
  73 + <setting-item name="宽度">
  74 + <n-input-number
  75 + v-model:value="optionData.borderWidth"
  76 + size="small"
  77 + :min="0"
  78 + placeholder="宽度"
  79 + ></n-input-number>
  80 + </setting-item>
  81 + <setting-item name="颜色">
  82 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.borderColor"></n-color-picker>
  83 + </setting-item>
  84 + <setting-item name="圆角">
  85 + <n-input-number
  86 + v-model:value="optionData.borderRadius"
  87 + size="small"
  88 + :min="0"
  89 + placeholder="圆角"
  90 + ></n-input-number>
  91 + </setting-item>
  92 + </setting-item-box>
  93 +
  94 + <setting-item-box name="背景" :alone="true">
  95 + <setting-item name="背景颜色">
  96 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.backgroundColor"></n-color-picker>
  97 + </setting-item>
  98 + </setting-item-box>
  99 + </collapse-item>
  100 +</template>
  101 +
  102 +<script setup lang="ts">
  103 +import { PropType } from 'vue'
  104 +import { option, WritingModeEnum, WritingModeObject, FontWeightEnum, FontWeightObject } from './config'
  105 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  106 +const props = defineProps({
  107 + optionData: {
  108 + type: Object as PropType<typeof option>,
  109 + required: true
  110 + }
  111 +})
  112 +
  113 +const textAlignOptions = [
  114 + { label: '左对齐', value: 'start' },
  115 + { label: '居中', value: 'center' },
  116 + { label: '右对齐', value: 'end' }
  117 +]
  118 +
  119 +const linkMethodOptions = [
  120 + { label: '默认', value: 'default' },
  121 + { label: '新开窗口', value: 'open' }
  122 +]
  123 +
  124 +const verticalOptions = [
  125 + {
  126 + label: WritingModeEnum.HORIZONTAL,
  127 + value: WritingModeObject[WritingModeEnum.HORIZONTAL]
  128 + },
  129 + {
  130 + label: WritingModeEnum.VERTICAL,
  131 + value: WritingModeObject[WritingModeEnum.VERTICAL]
  132 + }
  133 +]
  134 +const fontWeightOptions = [
  135 + {
  136 + label: FontWeightEnum.NORMAL,
  137 + value: FontWeightObject[FontWeightEnum.NORMAL]
  138 + },
  139 + {
  140 + label: FontWeightEnum.BOLD,
  141 + value: FontWeightObject[FontWeightEnum.BOLD]
  142 + }
  143 +]
  144 +const handleLinkClick = (target: string) => {
  145 + const hrefStr = props.optionData.linkHead + props.optionData.link
  146 + if (target === 'open') window.open(hrefStr)
  147 + else window.location.href = hrefStr
  148 +}
  149 +const linkHeadOptions = [
  150 + { label: 'http://', value: 'http://' },
  151 + { label: 'https://', value: 'https://' }
  152 +]
  153 +</script>
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Informations/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, conKey, chartKey } = useWidgetKey('OverrideTextEnumCommon', true)
  6 +
  7 +export const OverrideTextEnumCommonConfig: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '自定义文字(支持枚举)',
  12 + category: ChatCategoryEnum.TEXT,
  13 + categoryName: ChatCategoryEnumName.TEXT,
  14 + package: PackagesCategoryEnum.INFORMATIONS,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'text_static.png'
  17 +}
  1 +<template>
  2 + <div class="go-text-box">
  3 + <div class="content">
  4 + <span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click">{{ option.dataset }}</span>
  5 + <span style="white-space: pre-wrap" v-else>{{ option.dataset }}</span>
  6 + </div>
  7 + </div>
  8 +</template>
  9 +
  10 +<script setup lang="ts">
  11 +import { PropType, toRefs, shallowReactive } from 'vue'
  12 +import { CreateComponentType } from '@/packages/index.d'
  13 +import { useChartDataFetch } from '@/hooks'
  14 +import { useTsl } from '@/hooks/external/useTsl'
  15 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  16 +import { option as configOption } from './config'
  17 +
  18 +const props = defineProps({
  19 + chartConfig: {
  20 + type: Object as PropType<CreateComponentType & typeof option>,
  21 + required: true
  22 + }
  23 +})
  24 +
  25 +const { handleDeviceProfileAttributes } = useTsl()
  26 +
  27 +const {
  28 + linkHead,
  29 + link,
  30 + fontColor,
  31 + fontSize,
  32 + letterSpacing,
  33 + paddingY,
  34 + paddingX,
  35 + textAlign,
  36 + borderWidth,
  37 + borderColor,
  38 + borderRadius,
  39 + writingMode,
  40 + backgroundColor,
  41 + fontWeight,
  42 + linkMethod
  43 +} = toRefs(props.chartConfig.option)
  44 +
  45 +const option = shallowReactive({
  46 + dataset: configOption.dataset
  47 +})
  48 +
  49 +//动态请求物模型
  50 +const fetchTsl = (entityId: string) => {
  51 + return handleDeviceProfileAttributes(entityId)
  52 +}
  53 +
  54 +//解构设备和属性参数
  55 +const deconstructionParams = (chartConfig: CreateComponentType) => {
  56 + const { request } = chartConfig
  57 + const { requestParams } = request
  58 + const { Params } = requestParams
  59 + const { entityId, keys } = Params
  60 + return { entityId, keys }
  61 +}
  62 +
  63 +//找到枚举值name,属性暂时只选择一个
  64 +const findEnumName = (attribute: Recordable[], keys: string[], newData: Recordable) => {
  65 + const findCurrentAttr = attribute.find(findAttrItem => findAttrItem.identifier === keys.at(0))?.detail?.dataType
  66 + ?.specsList
  67 + return findCurrentAttr.find(
  68 + (findCurrentItem: Recordable) => findCurrentItem.value === Number(newData.data[keys.at(0)!][0][1])
  69 + )?.name
  70 +}
  71 +
  72 +// 预览更新
  73 +useChartDataFetch(props.chartConfig, useChartEditStore, async (newData: string) => {
  74 + const { entityId, keys } = deconstructionParams(props.chartConfig) as Recordable
  75 + const { attribute } = (await fetchTsl(entityId)) as unknown as Recordable
  76 + if (Object.prototype.toString.call(newData) !== '[object Object]') {
  77 + option.dataset = newData
  78 + } else if ('subscriptionId' in (newData as unknown as Recordable)) {
  79 + // ws
  80 + option.dataset = findEnumName(attribute, keys, newData as unknown as Recordable) || '暂无数据'
  81 + }
  82 +})
  83 +
  84 +//打开链接
  85 +const click = () => {
  86 + const hrefStr = linkHead.value + link.value
  87 + if (linkMethod.value === 'open') window.open(hrefStr)
  88 + else window.location.href = hrefStr
  89 +}
  90 +</script>
  91 +
  92 +<style lang="scss" scoped>
  93 +@include go('text-box') {
  94 + display: flex;
  95 + align-items: center;
  96 + justify-content: v-bind('textAlign');
  97 +
  98 + .content {
  99 + color: v-bind('fontColor');
  100 + padding: v-bind('`${paddingY}px ${paddingX}px`');
  101 + font-size: v-bind('fontSize + "px"');
  102 + letter-spacing: v-bind('letterSpacing + "px"');
  103 + writing-mode: v-bind('writingMode');
  104 + font-weight: v-bind('fontWeight');
  105 + border-style: solid;
  106 + border-width: v-bind('borderWidth + "px"');
  107 + border-radius: v-bind('borderRadius + "px"');
  108 + border-color: v-bind('borderColor');
  109 +
  110 + background-color: v-bind('backgroundColor');
  111 + }
  112 +}
  113 +</style>
@@ -351,8 +351,9 @@ useChartDataFetch(props.chartConfig, useChartEditStore, async (resData: any[], r @@ -351,8 +351,9 @@ useChartDataFetch(props.chartConfig, useChartEditStore, async (resData: any[], r
351 const { requestParams } = res 351 const { requestParams } = res
352 if (!requestParams) return 352 if (!requestParams) return
353 const { Params } = requestParams 353 const { Params } = requestParams
354 - if (!Params) return 354 + if (!Params) return
355 const { entityId } = Params 355 const { entityId } = Params
  356 + if(!entityId) return window['$message'].warning('您选择的公共接口不适合此组件,请选择匹配此组件的公共接口')
356 const thingsModel = await handleDeviceProfileAttributes(entityId) 357 const thingsModel = await handleDeviceProfileAttributes(entityId)
357 const { attribute } = thingsModel as any 358 const { attribute } = thingsModel as any
358 const resDataFormat = resData.reduce((acc, curr) => { 359 const resDataFormat = resData.reduce((acc, curr) => {
@@ -373,6 +374,7 @@ onUnmounted(() => { @@ -373,6 +374,7 @@ onUnmounted(() => {
373 }) 374 })
374 375
375 const handleDeviceProfileAttributes = async (entityId: string) => { 376 const handleDeviceProfileAttributes = async (entityId: string) => {
  377 + if(!entityId) return window['$message'].warning('您选择的公共接口不适合此组件,请选择匹配此组件的公共接口')
376 const deviceDetailRes = await getDeviceDetail(entityId) 378 const deviceDetailRes = await getDeviceDetail(entityId)
377 const { deviceProfileId } = deviceDetailRes 379 const { deviceProfileId } = deviceDetailRes
378 if (!deviceProfileId) return 380 if (!deviceProfileId) return
@@ -9,6 +9,7 @@ import { OverrideInputsDateConfig } from '@/packages/components/external/Informa @@ -9,6 +9,7 @@ import { OverrideInputsDateConfig } from '@/packages/components/external/Informa
9 import { OverrideInputsTabConfig } from '@/packages/components/external/Informations/Inputs/OverrideInputsTab' 9 import { OverrideInputsTabConfig } from '@/packages/components/external/Informations/Inputs/OverrideInputsTab'
10 import { OverrideIframeConfig } from '@/packages/components/external/Informations/Mores/OverrideIframe' 10 import { OverrideIframeConfig } from '@/packages/components/external/Informations/Mores/OverrideIframe'
11 import { OverrideTextCommonConfig } from '@/packages/components/external/Informations/Texts/OverrideTextCommon' 11 import { OverrideTextCommonConfig } from '@/packages/components/external/Informations/Texts/OverrideTextCommon'
  12 +import { OverrideTextEnumCommonConfig } from '@/packages/components/external/Informations/Texts/OverrideTextEnumCommon'
12 import { OverrideTextBarrageConfig } from '@/packages/components/external/Informations/Texts/OverrideTextBarrage' 13 import { OverrideTextBarrageConfig } from '@/packages/components/external/Informations/Texts/OverrideTextBarrage'
13 import { OverrideTextGradientConfig } from '@/packages/components/external/Informations/Texts/OverrideTextGradient' 14 import { OverrideTextGradientConfig } from '@/packages/components/external/Informations/Texts/OverrideTextGradient'
14 import { OverrideVideoConfig } from '@/packages/components/external/Informations/Mores/OverrideVideo' 15 import { OverrideVideoConfig } from '@/packages/components/external/Informations/Mores/OverrideVideo'
@@ -68,6 +69,10 @@ import { Decorates23Config } from '@/packages/components/external/Decorates/Deco @@ -68,6 +69,10 @@ import { Decorates23Config } from '@/packages/components/external/Decorates/Deco
68 import { Decorates24Config } from '@/packages/components/external/Decorates/Decorates/Decorates24' 69 import { Decorates24Config } from '@/packages/components/external/Decorates/Decorates/Decorates24'
69 import { Decorates25Config } from '@/packages/components/external/Decorates/Decorates/Decorates25' 70 import { Decorates25Config } from '@/packages/components/external/Decorates/Decorates/Decorates25'
70 import { Decorates26Config } from '@/packages/components/external/Decorates/Decorates/Decorates26' 71 import { Decorates26Config } from '@/packages/components/external/Decorates/Decorates/Decorates26'
  72 +import { Decorates27Config } from '@/packages/components/external/Decorates/Decorates/Decorates27'
  73 +import { Decorates28Config } from '@/packages/components/external/Decorates/Decorates/Decorates28'
  74 +import { Decorates29Config } from '@/packages/components/external/Decorates/Decorates/Decorates29'
  75 +import { Decorates30Config } from '@/packages/components/external/Decorates/Decorates/Decorates30'
71 import { OverrideTableScrollBoardConfig } from '@/packages/components/external/Tables/Tables/OverrideTableScrollBoard' 76 import { OverrideTableScrollBoardConfig } from '@/packages/components/external/Tables/Tables/OverrideTableScrollBoard'
72 import { OverrideTablesBasicConfig } from '@/packages/components/external/Tables/Tables/OverrideTablesBasic' 77 import { OverrideTablesBasicConfig } from '@/packages/components/external/Tables/Tables/OverrideTablesBasic'
73 78
@@ -114,6 +119,10 @@ export function useInjectLib(packagesList: EPackagesType) { @@ -114,6 +119,10 @@ export function useInjectLib(packagesList: EPackagesType) {
114 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates24Config)//新增动画装饰装饰24 119 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates24Config)//新增动画装饰装饰24
115 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates25Config)//新增动画装饰装饰25 120 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates25Config)//新增动画装饰装饰25
116 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates26Config)//新增动画装饰装饰26 121 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates26Config)//新增动画装饰装饰26
  122 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates27Config)//新增动画装饰装饰27
  123 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates28Config)//新增动画装饰装饰28
  124 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates29Config)//新增动画装饰装饰29
  125 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, Decorates30Config)//新增动画装饰装饰30
117 // 126 //
118 127
119 //信息 128 //信息
@@ -128,6 +137,7 @@ export function useInjectLib(packagesList: EPackagesType) { @@ -128,6 +137,7 @@ export function useInjectLib(packagesList: EPackagesType) {
128 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsDateConfig)//重写信息下的日期 137 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsDateConfig)//重写信息下的日期
129 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsTabConfig)//重写信息下的tab 138 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsTabConfig)//重写信息下的tab
130 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextCommonConfig)//重写信息下的文字 139 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextCommonConfig)//重写信息下的文字
  140 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextEnumCommonConfig)//重写信息下的文字(支持枚举)
131 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextBarrageConfig)//重写信息下的弹幕文字 141 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextBarrageConfig)//重写信息下的弹幕文字
132 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextGradientConfig)//重写信息下的渐变文字 142 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextGradientConfig)//重写信息下的渐变文字
133 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideVideoConfig)//重写信息下的视频 143 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideVideoConfig)//重写信息下的视频
@@ -9,6 +9,7 @@ const getAllConfigFile = async () => { @@ -9,6 +9,7 @@ const getAllConfigFile = async () => {
9 9
10 const getChartConfigFile = async (path: string) => { 10 const getChartConfigFile = async (path: string) => {
11 const fileList = await getAllConfigFile() 11 const fileList = await getAllConfigFile()
  12 + if (path.includes('group')) return // 分组则终止
12 return fileList[path]() as any 13 return fileList[path]() as any
13 } 14 }
14 15
@@ -41,6 +42,7 @@ export const createComponent = async (configType: ConfigType) => { @@ -41,6 +42,7 @@ export const createComponent = async (configType: ConfigType) => {
41 // 42 //
42 const hasExternalPrefix = matchExternalPrefixReg.test(chartKey) 43 const hasExternalPrefix = matchExternalPrefixReg.test(chartKey)
43 const filePath = `../components${hasExternalPrefix ? '/external' : ''}/${packageName}/${category}/${key}/config.ts` 44 const filePath = `../components${hasExternalPrefix ? '/external' : ''}/${packageName}/${category}/${key}/config.ts`
  45 + if (filePath.includes('group')) return // 分组则终止
44 const chart = await getChartConfigFile(filePath) 46 const chart = await getChartConfigFile(filePath)
45 return new chart.default() 47 return new chart.default()
46 } 48 }
@@ -41,7 +41,30 @@ export const requestConfig: RequestConfigType = { @@ -41,7 +41,30 @@ export const requestConfig: RequestConfigType = {
41 }, 41 },
42 Header: {}, 42 Header: {},
43 Params: {} 43 Params: {}
44 - } 44 + },
  45 + pondRequestOriginUrl: '',
  46 + pondRequestInterval: 0,
  47 + pondRequestIntervalUnit: '',
  48 + pondRequestGlobalTokenSuffix: '',
  49 + pondRequestGlobalTokenKey: '',
  50 + pondRequestHttpType: RequestHttpEnum.GET,
  51 + pondRequestContentType: RequestContentTypeEnum.DEFAULT,
  52 + pondRequestUrl:'',
  53 + pondRequestSQLContent: {
  54 + sql: ''
  55 + },
  56 + pondRequestParamsBodyType: RequestBodyEnum.NONE,
  57 + pondRequestParams: {
  58 + "Body": {
  59 + "form-data": {},
  60 + "x-www-form-urlencoded": {},
  61 + "json": "",
  62 + "xml": ""
  63 + },
  64 + "Header": {},
  65 + "Params": {}
  66 + },
  67 + pondRequestGlobalIsToken: true
45 } 68 }
46 69
47 // 单实例类 70 // 单实例类
@@ -48,9 +48,9 @@ @@ -48,9 +48,9 @@
48 } 48 }
49 }, 49 },
50 "yAxis": { 50 "yAxis": {
51 - "showRange":true,  
52 - "min": 0,  
53 - "max": 200, 51 + "showRange": false,
  52 + "minData": 0,
  53 + "maxData": 350,
54 "show": true, 54 "show": true,
55 "name": "", 55 "name": "",
56 "nameGap": 15, 56 "nameGap": 15,
@@ -32,6 +32,7 @@ interface UserState { @@ -32,6 +32,7 @@ interface UserState {
32 shareJwtToken?: string; 32 shareJwtToken?: string;
33 shareRefreshToken?: string; 33 shareRefreshToken?: string;
34 outTarget?: string; 34 outTarget?: string;
  35 + thirdTokenIsExp?: boolean;
35 } 36 }
36 37
37 const storage = createLocalStorage(); 38 const storage = createLocalStorage();
@@ -57,9 +58,14 @@ export const useUserStore = defineStore({ @@ -57,9 +58,14 @@ export const useUserStore = defineStore({
57 sessionTimeout: false, 58 sessionTimeout: false,
58 // Last fetch time 59 // Last fetch time
59 lastUpdateTime: 0, 60 lastUpdateTime: 0,
  61 + // 用于三方接口Token是否过期
  62 + thirdTokenIsExp: false
60 }), 63 }),
61 64
62 getters: { 65 getters: {
  66 + getThirdTokenIsExp(): boolean {
  67 + return this.thirdTokenIsExp!;
  68 + },
63 getPlatInfo(): any { 69 getPlatInfo(): any {
64 return this.platInfo; 70 return this.platInfo;
65 }, 71 },
@@ -87,6 +93,9 @@ export const useUserStore = defineStore({ @@ -87,6 +93,9 @@ export const useUserStore = defineStore({
87 }, 93 },
88 }, 94 },
89 actions: { 95 actions: {
  96 + setThirdTokenIsExp(expStatus:boolean) {
  97 + this.thirdTokenIsExp = expStatus
  98 + },
90 setPlatInfo(platInfo: any) { 99 setPlatInfo(platInfo: any) {
91 this.platInfo = platInfo; 100 this.platInfo = platInfo;
92 }, 101 },
@@ -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,18 @@ export interface RequestGlobalConfigType extends RequestPublicConfigType { @@ -189,6 +188,18 @@ 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,
  199 + // 全局配置Token前缀
  200 + requestGlobalTokenSuffix?: string,
  201 + // 全局配置Token键
  202 + requestGlobalTokenKey?: string,
192 } 203 }
193 204
194 // 单个图表请求配置 205 // 单个图表请求配置
@@ -211,6 +222,36 @@ export interface RequestConfigType extends RequestPublicConfigType { @@ -211,6 +222,36 @@ export interface RequestConfigType extends RequestPublicConfigType {
211 requestSQLContent: { 222 requestSQLContent: {
212 sql: string 223 sql: string
213 } 224 }
  225 +
  226 + // 三方Token相关
  227 + requestVerificationToken?: string
  228 + // 请求头里的Token键
  229 + requestTokenKey?: string
  230 + // 请求头里的Token前缀
  231 + requestTokenSuffix?: string
  232 + pondRequestOriginUrl?: string
  233 + pondRequestGlobalInterval?: number
  234 + pondRequestGlobalIntervalUnit?: string
  235 + pondRequestGlobalTokenSuffix?: string
  236 + pondRequestGlobalTokenKey?: string
  237 + pondRequestGlobalCascaderOption?: Recordable
  238 + pondRequestGlobalCascaderKey?: string
  239 + pondRequestHttpType?: RequestHttpEnum
  240 + pondRequestInterval?: number
  241 + pondRequestIntervalUnit?: string
  242 + pondRequestContentType?: number
  243 + pondRequestParams?: RequestParams
  244 + pondRequestParamsBodyType?: RequestBodyEnum
  245 + pondRequestUrl?: string
  246 + pondRequestSQLContent?: {
  247 + sql: string
  248 + }
  249 + thirdTokenIsExp?: boolean
  250 + thirdSelectCascaderLabel?: string
  251 + publicInterfaceSelectId?: string
  252 + thirdRequestDataPondId?: string
  253 + pondRequestGlobalIsToken?: boolean
  254 + //
214 } 255 }
215 256
216 // Store 类型 257 // 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: []
@@ -4,6 +4,30 @@ import type { GlobEnvConfig } from '/#/external/config'; @@ -4,6 +4,30 @@ import type { GlobEnvConfig } from '/#/external/config';
4 import { getGlobalConfigName } from '../../../../build/external/vite/plugins/globConfig/getGlobConfigName'; 4 import { getGlobalConfigName } from '../../../../build/external/vite/plugins/globConfig/getGlobConfigName';
5 import { ProjectRuntimeEnvEnum } from '@/enums/external/envEnum'; 5 import { ProjectRuntimeEnvEnum } from '@/enums/external/envEnum';
6 6
  7 +const stringToJSONParse = (string: string) => {
  8 + try {
  9 + return JSON.parse(string);
  10 + } catch (error) {
  11 + return string;
  12 + }
  13 +};
  14 +
  15 +export function parseEnv(env: Record<string, string>) {
  16 + const res: Record<string, string> = {};
  17 +
  18 + Object.keys(env).forEach((key) => {
  19 + try {
  20 + const value = env[key];
  21 + res[key] = stringToJSONParse(value);
  22 + } catch (err) {
  23 + // eslint-disable-next-line no-console
  24 + console.log(`env variable ${key} can't serialization!`);
  25 + }
  26 + });
  27 +
  28 + return res;
  29 +}
  30 +
7 31
8 export function getCommonStoragePrefix() { 32 export function getCommonStoragePrefix() {
9 // const { VITE_GLOB_APP_SHORT_NAME } = getAppEnvConfig(); 33 // const { VITE_GLOB_APP_SHORT_NAME } = getAppEnvConfig();
@@ -23,7 +47,7 @@ export function getAppEnvConfig() { @@ -23,7 +47,7 @@ export function getAppEnvConfig() {
23 47
24 const ENV = (import.meta.env.DEV 48 const ENV = (import.meta.env.DEV
25 ? // Get the global configuration (the configuration will be extracted independently when packaging) 49 ? // Get the global configuration (the configuration will be extracted independently when packaging)
26 - (import.meta.env as unknown as GlobEnvConfig) 50 + (parseEnv(import.meta.env) as unknown as GlobEnvConfig)
27 : window[ENV_NAME as any]) as unknown as GlobEnvConfig; 51 : window[ENV_NAME as any]) as unknown as GlobEnvConfig;
28 52
29 const { 53 const {
@@ -35,7 +59,7 @@ export function getAppEnvConfig() { @@ -35,7 +59,7 @@ export function getAppEnvConfig() {
35 VITE_GLOB_WEB_SOCKET, 59 VITE_GLOB_WEB_SOCKET,
36 VITE_GLOB_ALARM_NOTIFY_DURATION, 60 VITE_GLOB_ALARM_NOTIFY_DURATION,
37 VITE_GLOB_CONTENT_SECURITY_POLICY, 61 VITE_GLOB_CONTENT_SECURITY_POLICY,
38 - VITE_GLOB_PUBLIC_PATH 62 + VITE_GLOB_PUBLIC_PATH,
39 } = ENV; 63 } = ENV;
40 64
41 if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) { 65 if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) {
@@ -53,7 +77,7 @@ export function getAppEnvConfig() { @@ -53,7 +77,7 @@ export function getAppEnvConfig() {
53 VITE_GLOB_WEB_SOCKET, 77 VITE_GLOB_WEB_SOCKET,
54 VITE_GLOB_ALARM_NOTIFY_DURATION, 78 VITE_GLOB_ALARM_NOTIFY_DURATION,
55 VITE_GLOB_CONTENT_SECURITY_POLICY, 79 VITE_GLOB_CONTENT_SECURITY_POLICY,
56 - VITE_GLOB_PUBLIC_PATH 80 + VITE_GLOB_PUBLIC_PATH,
57 }; 81 };
58 } 82 }
59 83
@@ -11,6 +11,7 @@ import { ContentTypeEnum, RequestEnum } from '@/enums/external/httpEnum'; @@ -11,6 +11,7 @@ import { ContentTypeEnum, RequestEnum } from '@/enums/external/httpEnum';
11 import omit from 'lodash/omit'; 11 import omit from 'lodash/omit';
12 import cloneDeep from 'lodash/cloneDeep'; 12 import cloneDeep from 'lodash/cloneDeep';
13 import { useUserStore } from '@/store/external/modules/user'; 13 import { useUserStore } from '@/store/external/modules/user';
  14 +import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook';
14 15
15 export * from './axiosTransform'; 16 export * from './axiosTransform';
16 17
@@ -115,11 +116,25 @@ export class VAxios { @@ -115,11 +116,25 @@ export class VAxios {
115 this.axiosInstance.interceptors.request.use(async (config: AxiosRequestConfig) => { 116 this.axiosInstance.interceptors.request.use(async (config: AxiosRequestConfig) => {
116 // If cancel repeat request is turned on, then cancel repeat request is prohibited 117 // If cancel repeat request is turned on, then cancel repeat request is prohibited
117 const userStore = useUserStore(); 118 const userStore = useUserStore();
  119 + const { targetData } = useTargetData()
  120 +
118 // if (userStore && (userStore.jwtToken || userStore.shareJwtToken)) { 121 // if (userStore && (userStore.jwtToken || userStore.shareJwtToken)) {
119 if (userStore) { 122 if (userStore) {
120 try { 123 try {
121 const { requestOptions = {} } = config 124 const { requestOptions = {} } = config
122 - const { withShareToken, withToken } = requestOptions 125 + const { withShareToken, withToken, withThirdTokenString } = requestOptions
  126 + if (withThirdTokenString) {
  127 + //三方平台逻辑
  128 + const res = jwt_decode(withThirdTokenString) as Recordable;
  129 + const currentTime = (new Date().getTime() + (config.timeout || 0)) / 1000;
  130 + if (currentTime >= res?.exp) {
  131 + targetData.value.request.thirdTokenIsExp = true
  132 + userStore.setThirdTokenIsExp(true)
  133 + }else{
  134 + userStore.setThirdTokenIsExp(false)
  135 + }
  136 + } else {
  137 + //此平台逻辑
123 const token = withShareToken && withToken ? userStore.shareJwtToken : userStore.jwtToken 138 const token = withShareToken && withToken ? userStore.shareJwtToken : userStore.jwtToken
124 const doRefresh = withShareToken && withToken ? userStore.doShareRefresh : userStore.doRefresh 139 const doRefresh = withShareToken && withToken ? userStore.doShareRefresh : userStore.doRefresh
125 if (token) { 140 if (token) {
@@ -129,7 +144,8 @@ export class VAxios { @@ -129,7 +144,8 @@ export class VAxios {
129 await this.refreshTokenBeforeReq(doRefresh); 144 await this.refreshTokenBeforeReq(doRefresh);
130 } 145 }
131 } 146 }
132 - 147 + //
  148 + }
133 } catch (error) { 149 } catch (error) {
134 userStore.logout(); 150 userStore.logout();
135 } 151 }
@@ -38,3 +38,46 @@ export const parseWebUrl = (str = window.location.search) => { @@ -38,3 +38,46 @@ 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 +}
  68 +
  69 +// 递归查找
  70 +export const findItemByLabel = (list:Recordable[], label:string) :Recordable | null => {
  71 + let res = list.find((item) => item.label == label) as Recordable | null;
  72 + if (res) {
  73 + return res;
  74 + } else {
  75 + for (let i = 0; i < list.length; i++) {
  76 + if (list[i].children instanceof Array && list[i].children.length > 0) {
  77 + res = findItemByLabel(list[i].children, label);
  78 + if (res) return res;
  79 + }
  80 + }
  81 + return null;
  82 + }
  83 +};
@@ -158,7 +158,7 @@ const { @@ -158,7 +158,7 @@ const {
158 } = toRefs((props.targetData as RequestDataPondItemType).dataPondRequestConfig) 158 } = toRefs((props.targetData as RequestDataPondItemType).dataPondRequestConfig)
159 159
160 const tabs = [RequestParamsTypeEnum.HEADER] 160 const tabs = [RequestParamsTypeEnum.HEADER]
161 -const requestContentTypeObj = { 161 +const requestContentTypeObj: Recordable = {
162 [RequestContentTypeEnum.DEFAULT]: '普通请求', 162 [RequestContentTypeEnum.DEFAULT]: '普通请求',
163 [RequestContentTypeEnum.SQL]: 'SQL 请求' 163 [RequestContentTypeEnum.SQL]: 'SQL 请求'
164 } 164 }
@@ -101,7 +101,7 @@ watch( @@ -101,7 +101,7 @@ watch(
101 ) 101 )
102 102
103 // 打开/编辑 103 // 打开/编辑
104 -const openPond = (isEditFlag: boolean = false) => { 104 +const openPond = (isEditFlag = false) => {
105 isEdit.value = !!isEditFlag 105 isEdit.value = !!isEditFlag
106 requestShow.value = true 106 requestShow.value = true
107 } 107 }
@@ -41,6 +41,14 @@ @@ -41,6 +41,14 @@
41 编辑配置 41 编辑配置
42 </n-button> 42 </n-button>
43 </setting-item-box> 43 </setting-item-box>
  44 + <setting-item-box name="配置">
  45 + <setting-item name="Token前缀">
  46 + <n-input :disabled="editDisabled" v-model:value.trim="requestGlobalTokenSuffix" type="text" placeholder="例如:Bearer" />
  47 + </setting-item>
  48 + <setting-item name="Token键值">
  49 + <n-input :disabled="editDisabled" v-model:value.trim="requestGlobalTokenKey" type="text" placeholder="例如:Token" />
  50 + </setting-item>
  51 + </setting-item-box>
44 <!-- table 内容体 --> 52 <!-- table 内容体 -->
45 <n-collapse-transition :show="showTable"> 53 <n-collapse-transition :show="showTable">
46 <request-global-header-table :editDisabled="editDisabled"></request-global-header-table> 54 <request-global-header-table :editDisabled="editDisabled"></request-global-header-table>
@@ -69,13 +77,13 @@ import { ref, toRefs, computed } from 'vue' @@ -69,13 +77,13 @@ import { ref, toRefs, computed } from 'vue'
69 import { useDesignStore } from '@/store/modules/designStore/designStore' 77 import { useDesignStore } from '@/store/modules/designStore/designStore'
70 import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' 78 import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
71 import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook' 79 import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
72 -import { selectTypeOptions, selectTimeOptions } from '@/views/chart/ContentConfigurations/components/ChartData/index.d' 80 +import { selectTimeOptions } from '@/views/chart/ContentConfigurations/components/ChartData/index.d'
73 import { RequestGlobalHeaderTable } from '../RequestGlobalHeaderTable' 81 import { RequestGlobalHeaderTable } from '../RequestGlobalHeaderTable'
74 import { icon } from '@/plugins' 82 import { icon } from '@/plugins'
75 83
76 const { PencilIcon, ChevronDownOutlineIcon, ChevronUpOutlineIcon } = icon.ionicons5 84 const { PencilIcon, ChevronDownOutlineIcon, ChevronUpOutlineIcon } = icon.ionicons5
77 const { chartEditStore } = useTargetData() 85 const { chartEditStore } = useTargetData()
78 -const { requestOriginUrl, requestInterval, requestIntervalUnit } = toRefs(chartEditStore.getRequestGlobalConfig) 86 +const { requestOriginUrl, requestInterval, requestIntervalUnit, requestGlobalTokenSuffix, requestGlobalTokenKey } = toRefs(chartEditStore.getRequestGlobalConfig)
79 const editDisabled = ref(true) 87 const editDisabled = ref(true)
80 88
81 const designStore = useDesignStore() 89 const designStore = useDesignStore()
@@ -47,7 +47,7 @@ const emit = defineEmits(['update:modelShow', 'sendHandle']) @@ -47,7 +47,7 @@ const emit = defineEmits(['update:modelShow', 'sendHandle'])
47 const { chartConfig } = toRefs(props.targetData as CreateComponentType) 47 const { chartConfig } = toRefs(props.targetData as CreateComponentType)
48 const { requestContentType } = toRefs((props.targetData as CreateComponentType).request) 48 const { requestContentType } = toRefs((props.targetData as CreateComponentType).request)
49 const modelShowRef = ref(false) 49 const modelShowRef = ref(false)
50 -const requestContentTypeObj = { 50 +const requestContentTypeObj: Recordable = {
51 [RequestContentTypeEnum.DEFAULT]: '普通请求', 51 [RequestContentTypeEnum.DEFAULT]: '普通请求',
52 [RequestContentTypeEnum.SQL]: 'SQL 请求' 52 [RequestContentTypeEnum.SQL]: 'SQL 请求'
53 } 53 }
@@ -58,16 +58,36 @@ @@ -58,16 +58,36 @@
58 <NSpace :size="15" vertical> 58 <NSpace :size="15" vertical>
59 <div class="editor-data-show"> 59 <div class="editor-data-show">
60 <NSpace> 60 <NSpace>
  61 + <NText depth="3">原始数据:</NText>
  62 + <n-collapse :default-expanded-names="['1']">
  63 + <n-collapse-item name="1">
  64 + <NScrollbar style="max-height: 300px;">
  65 + <NCode :code="toString(cacheConfig) || '暂无'" language="json" :word-wrap="true"></NCode>
  66 + </NScrollbar>
  67 + </n-collapse-item>
  68 + </n-collapse>
  69 + </NSpace>
  70 + </div>
  71 + <div class="editor-data-show">
  72 + <NSpace>
61 <NText depth="3">接口返回数据(res):</NText> 73 <NText depth="3">接口返回数据(res):</NText>
62 - <NScrollbar style="max-height: 300px;">  
63 - <NCode :code="toString(isSocketRequest ? targetData.wsOriginalMessage : sourceData) || '暂无'" language="json" :word-wrap="true"></NCode>  
64 - </NScrollbar> 74 + <n-collapse>
  75 + <n-collapse-item name="2">
  76 + <NScrollbar style="max-height: 300px;">
  77 + <NCode :code="toString(isSocketRequest ? targetData.wsOriginalMessage : sourceData) || '暂无'" language="json" :word-wrap="true"></NCode>
  78 + </NScrollbar>
  79 + </n-collapse-item>
  80 + </n-collapse>
65 </NSpace> 81 </NSpace>
66 </div> 82 </div>
67 <div class="editor-data-show"> 83 <div class="editor-data-show">
68 <NSpace> 84 <NSpace>
69 <NText depth="3">过滤器结果:</NText> 85 <NText depth="3">过滤器结果:</NText>
70 - <NCode :code="filterRes || '暂无'" language="json" :word-wrap="true"></NCode> 86 + <n-collapse>
  87 + <n-collapse-item name="3">
  88 + <NCode :code="filterRes || '暂无'" language="json" :word-wrap="true"></NCode>
  89 + </n-collapse-item>
  90 + </n-collapse>
71 </NSpace> 91 </NSpace>
72 </div> 92 </div>
73 </NSpace> 93 </NSpace>
@@ -97,7 +117,7 @@ @@ -97,7 +117,7 @@
97 </template> 117 </template>
98 118
99 <script lang="ts" setup> 119 <script lang="ts" setup>
100 -import { ref, computed, watch, unref } from 'vue' 120 +import { ref, computed, watch, unref, onMounted } from 'vue'
101 import { MonacoEditor } from '@/components/Pages/MonacoEditor' 121 import { MonacoEditor } from '@/components/Pages/MonacoEditor'
102 import { icon } from '@/plugins' 122 import { icon } from '@/plugins'
103 import { goDialog, toString } from '@/utils' 123 import { goDialog, toString } from '@/utils'
@@ -106,6 +126,7 @@ import { NButton, NCard, NCode, NDivider, NIcon, NModal, NScrollbar, NSpace, NTa @@ -106,6 +126,7 @@ import { NButton, NCard, NCode, NDivider, NIcon, NModal, NScrollbar, NSpace, NTa
106 import { useFilterFn } from '@/hooks/external/useFilterFn' 126 import { useFilterFn } from '@/hooks/external/useFilterFn'
107 import { useFetchTargetData } from '@/hooks/external/useFetchTargetData' 127 import { useFetchTargetData } from '@/hooks/external/useFetchTargetData'
108 import { RequestContentTypeEnum } from '@/enums/external/httpEnum' 128 import { RequestContentTypeEnum } from '@/enums/external/httpEnum'
  129 +import { createComponent } from '@/packages/external/override'
109 130
110 const { DocumentTextIcon } = icon.ionicons5 131 const { DocumentTextIcon } = icon.ionicons5
111 const { FilterIcon, FilterEditIcon } = icon.carbon 132 const { FilterIcon, FilterEditIcon } = icon.carbon
@@ -166,6 +187,20 @@ const closeFilter = () => { @@ -166,6 +187,20 @@ const closeFilter = () => {
166 showModal.value = false 187 showModal.value = false
167 } 188 }
168 189
  190 +// 发送请求
  191 +const sendHandle = async () => {
  192 + try {
  193 + const res = await fetchHandle()
  194 + if (res) {
  195 + const { value } = useFilterFn(targetData.value.filter, res)
  196 + targetData.value.option.dataset = value
  197 + return
  198 + }
  199 + } catch(e) {
  200 + console.error(e)
  201 + }
  202 +}
  203 +
169 // 新增过滤器 204 // 新增过滤器
170 const saveFilter = () => { 205 const saveFilter = () => {
171 if (errorFlag.value) { 206 if (errorFlag.value) {
@@ -174,6 +209,7 @@ const saveFilter = () => { @@ -174,6 +209,7 @@ const saveFilter = () => {
174 } 209 }
175 targetData.value.filter = filter.value 210 targetData.value.filter = filter.value
176 closeFilter() 211 closeFilter()
  212 + sendHandle()
177 } 213 }
178 214
179 watch( 215 watch(
@@ -185,6 +221,19 @@ watch( @@ -185,6 +221,19 @@ watch(
185 } 221 }
186 } 222 }
187 ) 223 )
  224 +
  225 +const cacheConfig = ref()
  226 +
  227 +const fetchComponentConfig = async () => {
  228 + const config = await createComponent(targetData.value.chartConfig)
  229 + return config
  230 +}
  231 +
  232 +
  233 +onMounted(async ()=> {
  234 + const config = await fetchComponentConfig()
  235 + cacheConfig.value = config?.option?.dataset
  236 +})
188 </script> 237 </script>
189 238
190 <style lang="scss" scoped> 239 <style lang="scss" scoped>
  1 +<template>
  2 + <n-table
  3 + :bordered="false"
  4 + :single-line="false"
  5 + size="small"
  6 + style="border-bottom-right-radius: 7px; border-bottom-left-radius: 7px"
  7 + >
  8 + <thead>
  9 + <tr>
  10 + <th>key</th>
  11 + <th>value</th>
  12 + </tr>
  13 + </thead>
  14 + <tbody>
  15 + <tr v-for="(item, index) in tableArray.content" :key="index">
  16 + <td>
  17 + {{ item.key || '暂无'}}
  18 + </td>
  19 + <td>
  20 + {{ item.value || '暂无'}}
  21 + </td>
  22 + </tr>
  23 + </tbody>
  24 + </n-table>
  25 +</template>
  26 +
  27 +<script setup lang="ts">
  28 +import { PropType, reactive, ref, toRefs, watch } from 'vue'
  29 +import { RequestParamsObjType } from '@/enums/httpEnum'
  30 +import noData from '@/assets/images/canvas/noData.png'
  31 +
  32 +const props = defineProps({
  33 + target: Object as PropType<RequestParamsObjType>
  34 +})
  35 +
  36 +// 默认表格
  37 +const defaultItem = {
  38 + key: '',
  39 + value: ''
  40 +}
  41 +const tableArray = reactive<{
  42 + content: typeof defaultItem[]
  43 +}>({ content: [] })
  44 +
  45 +// 监听选项
  46 +watch(
  47 + () => props.target as RequestParamsObjType,
  48 + (target: RequestParamsObjType) => {
  49 + tableArray.content = []
  50 + for (const k in target) {
  51 + tableArray.content.push({
  52 + key: k,
  53 + value: target[k]
  54 + })
  55 + }
  56 + // 默认值
  57 + if (!tableArray.content.length) tableArray.content = [JSON.parse(JSON.stringify(defaultItem))]
  58 + },
  59 + {
  60 + immediate: true,
  61 + deep: true
  62 + }
  63 +)
  64 +</script>
  1 +<template>
  2 + <div class="go-chart-data-display">
  3 + <n-scrollbar style="max-height: 570px">
  4 + <div class="go-mr-3">
  5 + <div>
  6 + <setting-item-box name="主体信息">
  7 + <setting-item name="接口名称">
  8 + <n-input size="small" :placeholder="targetData?.dataPondName || '暂无'" :disabled="true"> </n-input>
  9 + </setting-item>
  10 + <setting-item name="接口类型">
  11 + <n-input size="small" :placeholder="pondRequestHttpType || '暂无'" :disabled="true"></n-input>
  12 + </setting-item>
  13 + </setting-item-box>
  14 +
  15 + <setting-item-box>
  16 + <setting-item name="组件间隔">
  17 + <n-input size="small" :placeholder="`${requestInterval || '暂无'}`" :disabled="true">
  18 + <template #suffix>
  19 + {{ targetData && SelectHttpTimeNameObj[requestIntervalUnit] }}
  20 + </template>
  21 + </n-input>
  22 + </setting-item>
  23 + <setting-item name="全局间隔(默认)">
  24 + <n-input size="small" :placeholder="`${globalData?.requestInterval || '暂无'}`" :disabled="true">
  25 + <template #suffix> {{ globalData && SelectHttpTimeNameObj[globalData.requestIntervalUnit] }} </template>
  26 + </n-input>
  27 + </setting-item>
  28 + </setting-item-box>
  29 +
  30 + <setting-item-box name="源地址" :alone="true">
  31 + <n-input size="small" :placeholder="pondRequestOriginUrl || '暂无'" :disabled="true">
  32 + <template #prefix>
  33 + <n-icon :component="PulseIcon" />
  34 + </template>
  35 + </n-input>
  36 + </setting-item-box>
  37 +
  38 + <setting-item-box name="接口地址" :alone="true">
  39 + <n-input
  40 + size="small"
  41 + :placeholder="pondRequestUrl || '暂无'"
  42 + :disabled="true"
  43 + >
  44 + <template #prefix>
  45 + <n-icon :component="FlashIcon" />
  46 + </template>
  47 + </n-input>
  48 + </setting-item-box>
  49 + </div>
  50 + <n-divider />
  51 + <setting-item-box name="类型">
  52 + <setting-item name="配置类型">
  53 + <n-input
  54 + size="small"
  55 + :placeholder="targetData && requestContentTypeObj[pondRequestContentType!]"
  56 + :disabled="true"
  57 + ></n-input>
  58 + </setting-item>
  59 + <setting-item name="body 类型" v-if="pondRequestContentType === RequestContentTypeEnum.DEFAULT">
  60 + <n-input size="small" :placeholder="targetData && requestParamsBodyType" :disabled="true"></n-input>
  61 + </setting-item>
  62 + </setting-item-box>
  63 + <div v-if="pondRequestContentType === RequestContentTypeEnum.DEFAULT">
  64 + <n-tabs type="line" animated v-model:value="tabValue">
  65 + <n-tab v-for="item in RequestParamsTypeEnum" :key="item" :name="item" :tab="item"> {{ item }} </n-tab>
  66 + </n-tabs>
  67 + <!-- 各个页面 -->
  68 + <div class="go-mt-3">
  69 + <div v-if="tabValue !== RequestParamsTypeEnum.BODY">
  70 + <display-table class="go-my-3" :target="pondRequestParams![tabValue]"> </display-table>
  71 + </div>
  72 +
  73 + <!-- 选择了 body -->
  74 + <div v-else>
  75 + <!-- 为 none 时 -->
  76 + <n-card class="go-mt-3 go-pb-3" v-if="pondRequestParamsBodyType === RequestBodyEnum['NONE']">
  77 + <n-text depth="3">该接口没有 Body 体</n-text>
  78 + </n-card>
  79 +
  80 + <!-- 具有对象属性时 -->
  81 + <template
  82 + v-else-if="
  83 + pondRequestParamsBodyType === RequestBodyEnum['FORM_DATA'] ||
  84 + pondRequestParamsBodyType === RequestBodyEnum['X_WWW_FORM_URLENCODED']
  85 + "
  86 + >
  87 + <display-table
  88 + class="go-my-3"
  89 + :target="pondRequestParams![RequestParamsTypeEnum.BODY][pondRequestParamsBodyType]"
  90 + ></display-table>
  91 + </template>
  92 +
  93 + <!-- json -->
  94 + <template v-else-if="pondRequestParamsBodyType === RequestBodyEnum['JSON']">
  95 + <n-card size="small" style="padding-bottom: 7px">
  96 + <n-code
  97 + :code="pondRequestParams![RequestParamsTypeEnum.BODY][pondRequestParamsBodyType] || '暂无内容'"
  98 + language="json"
  99 + ></n-code>
  100 + </n-card>
  101 + </template>
  102 +
  103 + <!-- xml -->
  104 + <template v-else-if="pondRequestParamsBodyType === RequestBodyEnum['XML']">
  105 + <n-code
  106 + :code="pondRequestParams![RequestParamsTypeEnum.BODY][pondRequestParamsBodyType!] || ''"
  107 + language="html"
  108 + ></n-code>
  109 + </template>
  110 + </div>
  111 + </div>
  112 + </div>
  113 + <!-- SQL 请求 -->
  114 + <div v-else>
  115 + <setting-item-box name="键名">
  116 + <n-text>sql</n-text>
  117 + </setting-item-box>
  118 + <setting-item-box name="键值">
  119 + <n-code :code="requestSQLContent.sql || ''" language="sql"></n-code>
  120 + </setting-item-box>
  121 + </div>
  122 + </div>
  123 + </n-scrollbar>
  124 + </div>
  125 +</template>
  126 +
  127 +<script setup lang="ts">
  128 +import { PropType, ref, toRefs } from 'vue'
  129 +import { icon } from '@/plugins'
  130 +import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  131 +import { RequestDataPondItemType, RequestGlobalConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
  132 +import displayTable from './displayTable.vue'
  133 +import {
  134 + RequestBodyEnum,
  135 + RequestParamsTypeEnum,
  136 + SelectHttpTimeNameObj,
  137 + RequestContentTypeEnum,
  138 +} from '@/enums/httpEnum'
  139 +
  140 +const props = defineProps({
  141 + globalData: Object as PropType<RequestGlobalConfigType>,
  142 + targetData: Object as PropType<RequestDataPondItemType>
  143 +})
  144 +
  145 +const { FlashIcon, PulseIcon } = icon.ionicons5
  146 +
  147 +const {
  148 + requestInterval,
  149 + requestSQLContent,
  150 + requestParamsBodyType,
  151 + requestIntervalUnit,
  152 + pondRequestOriginUrl,
  153 + pondRequestUrl,
  154 + pondRequestHttpType,
  155 + pondRequestContentType,
  156 + pondRequestParamsBodyType,
  157 + pondRequestParams,
  158 +} = toRefs((props.targetData as RequestDataPondItemType).dataPondRequestConfig)
  159 +
  160 +const requestContentTypeObj = {
  161 + [RequestContentTypeEnum.DEFAULT]: '普通请求',
  162 + [RequestContentTypeEnum.SQL]: 'SQL 请求'
  163 +} as Recordable
  164 +
  165 +const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.PARAMS)
  166 +
  167 +</script>
  168 +
  169 +<style lang="scss" scoped>
  170 +@include go('chart-data-display') {
  171 + flex: 1;
  172 +}
  173 +</style>
  1 +import ChartDataPondControl from './index.vue'
  2 +
  3 +export { ChartDataPondControl }
  1 +<template>
  2 + <n-modal class="go-chart-data-pond-control" v-model:show="modelShow" :mask-closable="false">
  3 + <n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 900px; height: 650px">
  4 + <template #header></template>
  5 + <template #header-extra> </template>
  6 + <div class="pond-content">
  7 + <!-- 展示区域 -->
  8 + <chart-data-display
  9 + v-if="pondData && !loading"
  10 + :targetData="pondData"
  11 + :globalData="chartEditStore.getRequestGlobalConfig"
  12 + ></chart-data-display>
  13 + <!-- 无数据 -->
  14 + <div v-else class="no-data go-flex-center">
  15 + <img :src="noData" alt="暂无数据" />
  16 + <n-text :depth="3">暂未选择公共接口</n-text>
  17 + </div>
  18 + <!-- 左侧列表 -->
  19 + <chart-data-pond-list @createPond="createPond" @deletePond="deletePond"></chart-data-pond-list>
  20 + </div>
  21 + <!-- 底部 -->
  22 + <template #action>
  23 + <n-space justify="space-between">
  24 + <n-button type="info" secondary :disabled="!pondData" @click="openPond(true)">
  25 + 编辑内容
  26 + <template #icon>
  27 + <n-icon>
  28 + <pencil-icon />
  29 + </n-icon>
  30 + </template>
  31 + </n-button>
  32 + <n-button type="primary" @click="closeHandle">保存 & 关闭</n-button>
  33 + </n-space>
  34 + </template>
  35 + </n-card>
  36 + </n-modal>
  37 + <!-- 请求配置model -->
  38 + <pond-data-request
  39 + v-model:modelShow="requestShow"
  40 + :targetDataRequest="editData"
  41 + :isEdit="isEdit"
  42 + @editSaveHandle="saveHandle"
  43 + ></pond-data-request>
  44 +</template>
  45 +
  46 +<script setup lang="ts">
  47 +import { ref, toRefs, computed, nextTick, watch, toRaw } from 'vue'
  48 +import noData from '@/assets/images/canvas/noData.png'
  49 +import { ChartDataPondList } from '../ChartDataPondList'
  50 +import PondDataRequest from '../../../RequestModal/PondDataRequest.vue'
  51 +import { ChartDataDisplay } from '../ChartDataDisplay'
  52 +import { requestConfig } from '@/packages/public/publicConfig'
  53 +import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
  54 +import { RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
  55 +import { RequestDataTypeEnum } from '@/enums/httpEnum'
  56 +import { icon } from '@/plugins'
  57 +import { getUUID, goDialog } from '@/utils'
  58 +import { cloneDeep } from 'lodash'
  59 +
  60 +defineProps({
  61 + modelShow: Boolean
  62 +})
  63 +
  64 +const emit = defineEmits(['update:modelShow', 'sendHandle'])
  65 +
  66 +const { PencilIcon } = icon.ionicons5
  67 +
  68 +const { chartEditStore, targetData } = useTargetData()
  69 +
  70 +const { requestDataPond } = toRefs(chartEditStore.getRequestGlobalConfig)
  71 +
  72 +const requestShow = ref(false)
  73 +
  74 +const loading = ref(false)
  75 +
  76 +const isEdit = ref(false)
  77 +
  78 +const editData = ref<RequestDataPondItemType>()
  79 +
  80 +// 所选数据池
  81 +const pondData = computed(() => {
  82 + const selectId = targetData?.value?.request?.requestDataPondId
  83 + if (!selectId) return undefined
  84 + const data = requestDataPond.value.filter(item => {
  85 + return selectId === item.dataPondId
  86 + })
  87 + return data[0]
  88 +})
  89 +
  90 +const cacheEditData = ref<RequestDataPondItemType>()
  91 +
  92 +watch(
  93 + () => pondData.value,
  94 + newValue => {
  95 + loading.value = true
  96 + editData.value = newValue
  97 + cacheEditData.value = editData.value
  98 + nextTick(() => {
  99 + loading.value = false
  100 + })
  101 + },
  102 + {
  103 + immediate: true
  104 + }
  105 +)
  106 +
  107 +// 打开/编辑
  108 +const openPond = (isEditFlag = false) => {
  109 + isEdit.value = !!isEditFlag
  110 + requestShow.value = true
  111 + if (isEditFlag) {
  112 + editData.value = cacheEditData.value
  113 + targetData.value.request.pondRequestGlobalIsToken = editData.value?.dataPondRequestConfig.pondRequestGlobalIsToken
  114 + }
  115 +}
  116 +
  117 +// 创建
  118 +const createPond = () => {
  119 + const id = getUUID()
  120 + editData.value = {
  121 + dataPondId: id,
  122 + dataPondName: id,
  123 + dataPondRequestConfig: cloneDeep({ ...requestConfig, requestDataType: RequestDataTypeEnum.AJAX })
  124 + }
  125 + targetData.value.request.pondRequestGlobalIsToken = true
  126 + openPond()
  127 +}
  128 +
  129 +// 完成创建/编辑
  130 +const saveHandle = (newData: RequestDataPondItemType) => {
  131 + // 走创建
  132 + if (isEdit.value) {
  133 + editSaveHandle(newData)
  134 + } else {
  135 + createSaveHandle(newData)
  136 + }
  137 + isEdit.value = false
  138 + requestShow.value = false
  139 +}
  140 +
  141 +// 编辑保存之后
  142 +const editSaveHandle = (newData: RequestDataPondItemType) => {
  143 + try {
  144 + const targetIndex = requestDataPond.value.findIndex(item => item.dataPondId === newData.dataPondId)
  145 + if (targetIndex !== -1) {
  146 + requestDataPond.value.splice(targetIndex, 1, newData)
  147 + // 修改数据池后, 修改所有关联的组件
  148 + chartEditStore.getComponentList.forEach(item => {
  149 + if (
  150 + item.request.requestDataType === RequestDataTypeEnum.Pond &&
  151 + item.request.requestDataPondId === newData.dataPondId
  152 + ) {
  153 + item.request = {
  154 + ...toRaw(newData.dataPondRequestConfig),
  155 + requestDataPondId: newData.dataPondId
  156 + }
  157 + }
  158 + })
  159 + window.$message.success('保存成功!')
  160 + } else {
  161 + window.$message.error('编辑失败,请稍后重试!')
  162 + }
  163 + } catch (error) {
  164 + window.$message.error('编辑失败,请稍后重试!')
  165 + }
  166 +}
  167 +
  168 +// 创建保存成功之后
  169 +const createSaveHandle = (newData: RequestDataPondItemType) => {
  170 + try {
  171 + if (editData.value) {
  172 + requestDataPond.value.unshift(newData)
  173 + window.$message.success('创建成功!')
  174 + } else {
  175 + window.$message.error('创建失败,请稍后重试!')
  176 + }
  177 + } catch (error) {
  178 + window.$message.error('创建失败,请稍后重试!')
  179 + }
  180 +}
  181 +
  182 +// 删除数据池
  183 +const deletePond = (targetData: RequestDataPondItemType) => {
  184 + goDialog({
  185 + message: '删除数据后,需手动处理使用改接口的组件,是否继续?',
  186 + isMaskClosable: true,
  187 + transformOrigin: 'center',
  188 + onPositiveCallback: () => {
  189 + const targetIndex = requestDataPond.value.findIndex(item => item.dataPondId === targetData.dataPondId)
  190 + if (targetIndex !== -1) {
  191 + requestDataPond.value.splice(targetIndex, 1)
  192 + window.$message.success('删除成功!')
  193 + } else {
  194 + window.$message.error('删除失败,请稍后重试!')
  195 + }
  196 + }
  197 + })
  198 +}
  199 +
  200 +// 关闭
  201 +const closeHandle = () => {
  202 + // 将所选内容赋值给对象
  203 + if (pondData.value) {
  204 + // targetData.value.request = {
  205 + // ...toRaw(pondData.value.dataPondRequestConfig),
  206 + // requestDataPondId: pondData.value.dataPondId
  207 + // }
  208 + }
  209 + emit('update:modelShow', false)
  210 +}
  211 +</script>
  212 +
  213 +<style lang="scss" scoped>
  214 +@include go('chart-data-pond-control') {
  215 + /* 中间 */
  216 + .pond-content {
  217 + display: flex;
  218 + }
  219 + .no-data {
  220 + flex-direction: column;
  221 + width: 100%;
  222 + img {
  223 + width: 200px;
  224 + }
  225 + }
  226 + &.n-card.n-modal,
  227 + .n-card {
  228 + @extend .go-background-filter;
  229 + }
  230 + .n-card-shallow {
  231 + background-color: rgba(0, 0, 0, 0) !important;
  232 + }
  233 + @include deep() {
  234 + & > .n-card__content {
  235 + padding-right: 0;
  236 + }
  237 + .n-card__content {
  238 + padding-bottom: 5px;
  239 + }
  240 + }
  241 +}
  242 +</style>
  1 +<template>
  2 + <div class="go-chart-data-pond-list">
  3 + <n-timeline class="pond-item-timeline" style="width: 20px">
  4 + <n-timeline-item type="info"> </n-timeline-item>
  5 + <n-timeline-item type="success"></n-timeline-item>
  6 + </n-timeline>
  7 + <div class="pond-item-box">
  8 + <!-- 新增 -->
  9 + <n-button class="create-btn go-py-4" ghost @click="createPond">
  10 + <span> 创建 </span>
  11 + <template #icon>
  12 + <n-icon>
  13 + <DuplicateOutlineIcon></DuplicateOutlineIcon>
  14 + </n-icon>
  15 + </template>
  16 + </n-button>
  17 + <n-divider style="margin: 10px 0"></n-divider>
  18 + <n-space v-if="!requestDataPond.length" justify="center">
  19 + <n-text class="not-layer-text" :depth="3">
  20 + 暂无数据内容,
  21 + <n-a @click="createPond">立即创建</n-a>
  22 + </n-text>
  23 + </n-space>
  24 + <n-scrollbar style="max-height: 490px">
  25 + <div
  26 + v-for="item in requestDataPond"
  27 + :key="item.dataPondId"
  28 + :class="{ select: item.dataPondId === selectPondId }"
  29 + class="pond-item"
  30 + @click="clickHandle(item)"
  31 + >
  32 + <div class="item-content">
  33 + <div class="item-content-body">
  34 + <div>
  35 + <n-tag class="go-mr-1" :type="item.dataPondId === selectPondId ? 'warning' : ''" :bordered="false">
  36 + 名称
  37 + </n-tag>
  38 + <n-ellipsis style="max-width: 180px">
  39 + {{ item.dataPondName || '暂无' }}
  40 + </n-ellipsis>
  41 + </div>
  42 + <div>
  43 + <n-tag class="go-mr-1" :type="item.dataPondId === selectPondId ? 'warning' : ''" :bordered="false">
  44 + 地址
  45 + </n-tag>
  46 + <n-ellipsis style="max-width: 180px">
  47 + {{ item.dataPondRequestConfig.pondRequestUrl || '暂无' }}
  48 + </n-ellipsis>
  49 + </div>
  50 + </div>
  51 + <div class="item-content-icon go-transition-quick" @click="deletePond($event, item)">
  52 + <n-icon>
  53 + <trash-icon></trash-icon>
  54 + </n-icon>
  55 + </div>
  56 + </div>
  57 + <div :class="{ 'select-modal': item.dataPondId === selectPondId }"></div>
  58 + </div>
  59 + </n-scrollbar>
  60 + </div>
  61 + </div>
  62 +</template>
  63 +
  64 +<script setup lang="ts">
  65 +import { toRefs, computed } from 'vue'
  66 +import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
  67 +import { useDesignStore } from '@/store/modules/designStore/designStore'
  68 +import { RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
  69 +import { icon } from '@/plugins'
  70 +
  71 +const emit = defineEmits(['createPond', 'deletePond'])
  72 +
  73 +const { DuplicateOutlineIcon, TrashIcon } = icon.ionicons5
  74 +const designStore = useDesignStore()
  75 +const { chartEditStore, targetData } = useTargetData()
  76 +const { requestDataPond } = toRefs(chartEditStore.getRequestGlobalConfig)
  77 +
  78 +// 选中的全局数据
  79 +const selectPondId = computed(() => {
  80 + return targetData.value.request.requestDataPondId
  81 +})
  82 +
  83 +// 颜色
  84 +const themeColor = computed(() => {
  85 + return designStore.getAppTheme
  86 +})
  87 +
  88 +// 创建数据池
  89 +const createPond = () => {
  90 + emit('createPond', true)
  91 +}
  92 +
  93 +// 删除数据池
  94 +const deletePond = (target: Event, targetData: RequestDataPondItemType) => {
  95 + target.stopPropagation()
  96 + target.preventDefault()
  97 + emit('deletePond', targetData)
  98 +}
  99 +
  100 +// 选中
  101 +const clickHandle = (item: RequestDataPondItemType) => {
  102 + targetData.value.request.requestDataPondId = item.dataPondId
  103 + targetData.value.request.pondRequestGlobalIsToken = item.dataPondRequestConfig.pondRequestGlobalIsToken
  104 +}
  105 +</script>
  106 +
  107 +<style scoped lang="scss">
  108 +$height: 530px;
  109 +$listWidth: 280px;
  110 +$centerHeight: 60px;
  111 +$centerMiniHeight: 28px;
  112 +$textSize: 10px;
  113 +
  114 +@include go('chart-data-pond-list') {
  115 + padding-top: 10px;
  116 + padding-bottom: 5px;
  117 + margin-right: 5px;
  118 + display: flex;
  119 + .pond-item-timeline > .n-timeline-item {
  120 + &:first-child {
  121 + height: $height;
  122 + }
  123 + }
  124 + .pond-item-box {
  125 + width: $listWidth;
  126 + position: relative;
  127 + .create-btn {
  128 + width: calc(#{$listWidth - 15px});
  129 + margin-right: 15px;
  130 + }
  131 + .pond-item {
  132 + position: relative;
  133 + height: $centerHeight;
  134 + padding: 5px;
  135 + margin-bottom: 10px;
  136 + margin-right: 15px;
  137 + border-radius: 5px;
  138 + cursor: pointer;
  139 + border: 1px solid rgba(0, 0, 0, 0);
  140 + @include fetch-bg-color('background-color3');
  141 + @extend .go-transition-quick;
  142 + &.hover,
  143 + &:hover {
  144 + @include fetch-bg-color('background-color4');
  145 + }
  146 + &:hover {
  147 + @include deep() {
  148 + .icon-item {
  149 + opacity: 1;
  150 + }
  151 + }
  152 + .item-content-icon {
  153 + opacity: 1 !important;
  154 + }
  155 + }
  156 +
  157 + &.select {
  158 + border: 1px solid v-bind('themeColor');
  159 + background-color: rgba(0, 0, 0, 0);
  160 + .item-content-icon {
  161 + display: none;
  162 + }
  163 + }
  164 +
  165 + .select-modal,
  166 + .item-content {
  167 + position: absolute;
  168 + top: 0;
  169 + left: 0;
  170 + }
  171 +
  172 + .item-content {
  173 + z-index: 1;
  174 + display: flex;
  175 + justify-content: space-between;
  176 + align-items: center;
  177 + padding: 5px;
  178 + .item-content-body {
  179 + width: 230px;
  180 + display: flex;
  181 + flex-direction: column;
  182 + gap: 5px;
  183 + }
  184 + .item-content-icon {
  185 + opacity: 0;
  186 + height: $centerHeight;
  187 + line-height: $centerHeight;
  188 + padding-left: 5px;
  189 + }
  190 + }
  191 +
  192 + .select-modal {
  193 + width: 100%;
  194 + height: 100%;
  195 + opacity: 0.3;
  196 + background-color: v-bind('themeColor');
  197 + }
  198 + }
  199 + }
  200 +}
  201 +</style>
  1 +import ChartDataPond from './index.vue'
  2 +
  3 +export { ChartDataPond }
  1 +<template>
  2 + <!-- 选中内容 -->
  3 + <div class="go-chart-data-pond">
  4 + <n-card class="n-card-shallow">
  5 + <setting-item-box name="请求名称" :alone="true">
  6 + <n-input size="small" :placeholder="pondData?.dataPondName || '暂无'" :disabled="true">
  7 + <template #prefix>
  8 + <n-icon :component="FishIcon" />
  9 + </template>
  10 + </n-input>
  11 + </setting-item-box>
  12 +
  13 + <setting-item-box name="接口地址" :alone="true">
  14 + <n-input size="small" :placeholder="pondData?.dataPondRequestConfig.requestUrl || '暂无'" :disabled="true">
  15 + <template #prefix>
  16 + <n-icon :component="FlashIcon" />
  17 + </template>
  18 + </n-input>
  19 + </setting-item-box>
  20 +
  21 + <div class="edit-text" @click="controlModelHandle">
  22 + <div class="go-absolute-center">
  23 + <n-button type="primary" secondary>编辑配置</n-button>
  24 + </div>
  25 + </div>
  26 + </n-card>
  27 + </div>
  28 +
  29 + <setting-item-box :alone="true">
  30 + <template #name>
  31 + 测试
  32 + <n-tooltip trigger="hover">
  33 + <template #trigger>
  34 + <n-icon size="21" :depth="3">
  35 + <help-outline-icon></help-outline-icon>
  36 + </n-icon>
  37 + </template>
  38 + 默认赋值给 dataset 字段
  39 + </n-tooltip>
  40 + </template>
  41 + <n-button type="primary" ghost @click="sendHandle">
  42 + <template #icon>
  43 + <n-icon>
  44 + <flash-icon />
  45 + </n-icon>
  46 + </template>
  47 + 发送请求
  48 + </n-button>
  49 + </setting-item-box>
  50 +
  51 + <!-- 底部数据展示 -->
  52 + <chart-data-matching-and-show :show="showMatching && !loading" :ajax="true"></chart-data-matching-and-show>
  53 +
  54 + <!-- 骨架图 -->
  55 + <go-skeleton :load="loading" :repeat="3"></go-skeleton>
  56 +
  57 + <!-- 编辑 / 新增弹窗 -->
  58 + <chart-data-pond-control v-model:modelShow="controlModel" @sendHandle="sendHandle"></chart-data-pond-control>
  59 +</template>
  60 +
  61 +<script setup lang="ts">
  62 +import { ref, toRefs, toRaw, onBeforeUnmount, computed, watchEffect } from 'vue'
  63 +import { icon } from '@/plugins'
  64 +import { http, customizeHttp } from '@/api/http'
  65 +import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  66 +import { ChartDataPondControl } from './components/ChartDataPondControl'
  67 +import { useDesignStore } from '@/store/modules/designStore/designStore'
  68 +import { ChartDataMatchingAndShow } from '../ChartDataMatchingAndShow'
  69 +import { newFunctionHandle } from '@/utils'
  70 +import { useTargetData } from '../../../../hooks/useTargetData.hook'
  71 +
  72 +const designStore = useDesignStore()
  73 +const { HelpOutlineIcon, FlashIcon, PulseIcon, FishIcon } = icon.ionicons5
  74 +const { targetData, chartEditStore } = useTargetData()
  75 +
  76 +const {
  77 + requestDataPond,
  78 + requestInterval: GlobalRequestInterval,
  79 + requestIntervalUnit: GlobalRequestIntervalUnit
  80 +} = toRefs(chartEditStore.getRequestGlobalConfig)
  81 +
  82 +const loading = ref(false)
  83 +const controlModel = ref(false)
  84 +const showMatching = ref(false)
  85 +
  86 +let firstFocus = 0
  87 +let lastFilter: any = undefined
  88 +
  89 +// 所选数据池
  90 +const pondData = computed(() => {
  91 + const selectId = targetData.value.request.requestDataPondId
  92 + if (!selectId) return undefined
  93 + const data = requestDataPond.value.filter((item: Recordable) => {
  94 + return selectId === item.dataPondId
  95 + })
  96 + return data[0]
  97 +})
  98 +
  99 +// 颜色
  100 +const themeColor = computed(() => {
  101 + return designStore.getAppTheme
  102 +})
  103 +
  104 +// 请求配置 model
  105 +const controlModelHandle = () => {
  106 + controlModel.value = true
  107 +}
  108 +
  109 +// 发送请求
  110 +const sendHandle = async () => {
  111 + if (!targetData.value?.request) {
  112 + window.$message.warning('请选择一个公共接口!')
  113 + return
  114 + }
  115 + loading.value = true
  116 + try {
  117 + const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
  118 + loading.value = false
  119 + if (res) {
  120 + if (!res?.data && !targetData.value.filter) {
  121 + window['$message'].warning('您的数据不符合默认格式,请配置过滤器!')
  122 + showMatching.value = true
  123 + return
  124 + }
  125 + targetData.value.option.dataset = newFunctionHandle(res?.data, res, targetData.value.filter)
  126 + showMatching.value = true
  127 + return
  128 + }
  129 + window['$message'].warning('没有拿到返回值,请检查接口!')
  130 + } catch (error) {
  131 + console.error(error);
  132 + loading.value = false
  133 + window['$message'].warning('数据异常,请检查参数!')
  134 + }
  135 +}
  136 +
  137 +watchEffect(() => {
  138 + const filter = targetData.value?.filter
  139 + if (lastFilter !== filter && firstFocus) {
  140 + lastFilter = filter
  141 + sendHandle()
  142 + }
  143 + firstFocus++
  144 +})
  145 +
  146 +onBeforeUnmount(() => {
  147 + lastFilter = null
  148 +})
  149 +</script>
  150 +
  151 +<style scoped lang="scss">
  152 +@include go('chart-data-pond') {
  153 + position: relative;
  154 + display: flex;
  155 + flex-direction: column;
  156 + align-items: center;
  157 + .n-card-shallow {
  158 + &.n-card {
  159 + @extend .go-background-filter;
  160 + @include deep() {
  161 + .n-card__content {
  162 + padding: 10px;
  163 + }
  164 + }
  165 + }
  166 + .edit-text {
  167 + position: absolute;
  168 + top: 0px;
  169 + left: 0px;
  170 + width: 325px;
  171 + height: 136px;
  172 + cursor: pointer;
  173 + opacity: 0;
  174 + transition: all 0.3s;
  175 + @extend .go-background-filter;
  176 + backdrop-filter: blur(2px) !important;
  177 + }
  178 + &:hover {
  179 + border-color: v-bind('themeColor');
  180 + .edit-text {
  181 + opacity: 1;
  182 + }
  183 + }
  184 + }
  185 +}
  186 +</style>
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 -import { ref, computed, onBeforeUnmount, watchEffect, unref } from 'vue' 2 +import { ref, computed, onBeforeUnmount, watchEffect, unref, watch } from 'vue'
3 import { icon } from '@/plugins' 3 import { icon } from '@/plugins'
4 import { useDesignStore } from '@/store/modules/designStore/designStore' 4 import { useDesignStore } from '@/store/modules/designStore/designStore'
5 import { SettingItemBox } from '@/components/Pages/ChartItemSetting' 5 import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
6 import { ChartDataMatchingAndShow } from '../../../external/components/ChartDataMatchingAndShow' 6 import { ChartDataMatchingAndShow } from '../../../external/components/ChartDataMatchingAndShow'
  7 +import { ChartDataPondControl } from '../ChartDataPond/components/ChartDataPondControl'
7 import { useTargetData } from '../../../../hooks/useTargetData.hook' 8 import { useTargetData } from '../../../../hooks/useTargetData.hook'
8 import { NButton, NSelect, NTooltip, NIcon, SelectOption } from 'naive-ui' 9 import { NButton, NSelect, NTooltip, NIcon, SelectOption } from 'naive-ui'
9 import { RequestInfoPanel } from '../RequestInfoPanel' 10 import { RequestInfoPanel } from '../RequestInfoPanel'
@@ -11,24 +12,24 @@ import { RequestModal } from '../RequestModal' @@ -11,24 +12,24 @@ import { RequestModal } from '../RequestModal'
11 import { useFetchTargetData } from '@/hooks/external/useFetchTargetData' 12 import { useFetchTargetData } from '@/hooks/external/useFetchTargetData'
12 import { useFilterFn } from '@/hooks/external/useFilterFn' 13 import { useFilterFn } from '@/hooks/external/useFilterFn'
13 import { RequestDataTypeEnum } from '@/enums/external/httpEnum' 14 import { RequestDataTypeEnum } from '@/enums/external/httpEnum'
  15 +import { JSONParse } from '@/utils/external/utils'
  16 +import { CreateComponentGroupType, CreateComponentType } from '@/packages/index.d'
  17 +import { isArray } from '@/utils/external/is'
14 18
15 const { HelpOutlineIcon, FlashIcon } = icon.ionicons5 19 const { HelpOutlineIcon, FlashIcon } = icon.ionicons5
16 const { targetData } = useTargetData() 20 const { targetData } = useTargetData()
17 -  
18 -  
19 21
20 const requestModal = ref<InstanceType<typeof RequestModal>>() 22 const requestModal = ref<InstanceType<typeof RequestModal>>()
21 23
22 const designStore = useDesignStore() 24 const designStore = useDesignStore()
23 25
24 -  
25 /** 26 /**
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 - */ 27 + * ft 修改在公共接口下拉框里默认选择公共接口
  28 + * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
  29 + * 源代码 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.AJAX)
  30 + * 修改后的代码 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.Pond)
  31 + * 修改后代码在//ft之间
  32 + */
32 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.Pond) 33 const selectedRequestType = ref(targetData.value.request.requestDataType || RequestDataTypeEnum.Pond)
33 34
34 const getApiRequestType: SelectOption[] = [ 35 const getApiRequestType: SelectOption[] = [
@@ -43,7 +44,7 @@ const showMatching = ref(false) @@ -43,7 +44,7 @@ const showMatching = ref(false)
43 let firstFocus = 0 44 let firstFocus = 0
44 let lastFilter: any = undefined 45 let lastFilter: any = undefined
45 46
46 -const { fetchTargetData, } = useFetchTargetData() 47 +const { fetchTargetData } = useFetchTargetData()
47 48
48 // 发送请求 49 // 发送请求
49 const sendHandle = async () => { 50 const sendHandle = async () => {
@@ -56,6 +57,19 @@ const sendHandle = async () => { @@ -56,6 +57,19 @@ const sendHandle = async () => {
56 const res = await fetchTargetData() 57 const res = await fetchTargetData()
57 if (res) { 58 if (res) {
58 const { value } = useFilterFn(targetData.value.filter, res) 59 const { value } = useFilterFn(targetData.value.filter, res)
  60 + //分组更新下面子组件
  61 + if(targetData.value.isGroup) {
  62 + if (isArray(targetData.value.saveHistoryInput!)) {
  63 + const parseHistoryInput = JSONParse(targetData.value.saveHistoryInput!)
  64 + parseHistoryInput?.forEach((historyItem:Recordable) => {
  65 + const findCurrentItem = targetData.value.groupList?.find((groupItem:CreateComponentType | CreateComponentGroupType) => groupItem.id === historyItem.id)
  66 + if(findCurrentItem) {
  67 + findCurrentItem.option.dataset = value[historyItem.inputValue]
  68 + }
  69 + })
  70 + }
  71 + }
  72 + //
59 targetData.value.option.dataset = value 73 targetData.value.option.dataset = value
60 showMatching.value = true 74 showMatching.value = true
61 return 75 return
@@ -63,9 +77,9 @@ const sendHandle = async () => { @@ -63,9 +77,9 @@ const sendHandle = async () => {
63 } finally { 77 } finally {
64 loading.value = false 78 loading.value = false
65 } 79 }
66 -  
67 } 80 }
68 81
  82 +
69 // 颜色 83 // 颜色
70 const themeColor = computed(() => { 84 const themeColor = computed(() => {
71 return designStore.getAppTheme 85 return designStore.getAppTheme
@@ -73,6 +87,9 @@ const themeColor = computed(() => { @@ -73,6 +87,9 @@ const themeColor = computed(() => {
73 87
74 const handleClickPanel = () => { 88 const handleClickPanel = () => {
75 unref(requestModal as any)?.openModal?.(true, unref(selectedRequestType)) 89 unref(requestModal as any)?.openModal?.(true, unref(selectedRequestType))
  90 + if (selectedRequestType.value === RequestDataTypeEnum.AJAX) {
  91 + targetData.value.request.requestDataType = RequestDataTypeEnum.AJAX
  92 + }
76 } 93 }
77 94
78 // TODO socket 请求时会触发 95 // TODO socket 请求时会触发
@@ -81,11 +98,11 @@ watchEffect(() => { @@ -81,11 +98,11 @@ watchEffect(() => {
81 /** 98 /**
82 * FT 修改 99 * FT 修改
83 */ 100 */
84 - if(!filter) return 101 + if (!filter) return
85 //ft 102 //ft
86 if (lastFilter !== filter && firstFocus) { 103 if (lastFilter !== filter && firstFocus) {
87 lastFilter = filter 104 lastFilter = filter
88 - sendHandle() 105 + // sendHandle()
89 } 106 }
90 firstFocus++ 107 firstFocus++
91 }) 108 })
@@ -94,6 +111,13 @@ onBeforeUnmount(() => { @@ -94,6 +111,13 @@ onBeforeUnmount(() => {
94 lastFilter = null 111 lastFilter = null
95 }) 112 })
96 113
  114 +const controlModel = ref(false)
  115 +
  116 +const handleOpenChartDataPondModal = () => controlModel.value = true
  117 +
  118 +watch(()=>targetData.value, (newValue) => {
  119 + selectedRequestType.value = newValue?.request?.requestDataType as unknown as any
  120 +})
97 121
98 </script> 122 </script>
99 123
@@ -103,6 +127,10 @@ onBeforeUnmount(() => { @@ -103,6 +127,10 @@ onBeforeUnmount(() => {
103 <NSelect v-model:value="selectedRequestType" :options="getApiRequestType" /> 127 <NSelect v-model:value="selectedRequestType" :options="getApiRequestType" />
104 </SettingItemBox> 128 </SettingItemBox>
105 129
  130 + <SettingItemBox v-if="selectedRequestType === RequestDataTypeEnum.AJAX" name="全局配置" :alone="true">
  131 + <NButton @click="handleOpenChartDataPondModal" type="success">配置</NButton>
  132 + </SettingItemBox>
  133 +
106 <RequestInfoPanel @clickPanel="handleClickPanel" /> 134 <RequestInfoPanel @clickPanel="handleClickPanel" />
107 135
108 <SettingItemBox :alone="true"> 136 <SettingItemBox :alone="true">
@@ -134,11 +162,11 @@ onBeforeUnmount(() => { @@ -134,11 +162,11 @@ onBeforeUnmount(() => {
134 <go-skeleton :load="loading" :repeat="3"></go-skeleton> 162 <go-skeleton :load="loading" :repeat="3"></go-skeleton>
135 163
136 <RequestModal ref="requestModal" /> 164 <RequestModal ref="requestModal" />
  165 +
  166 + <chart-data-pond-control v-model:modelShow="controlModel" @sendHandle="sendHandle"></chart-data-pond-control>
137 </div> 167 </div>
138 </template> 168 </template>
139 169
140 -  
141 -  
142 <style lang="scss" scoped> 170 <style lang="scss" scoped>
143 @include thingsKit('chart-configurations-data-ajax') { 171 @include thingsKit('chart-configurations-data-ajax') {
144 .n-card-shallow { 172 .n-card-shallow {
@@ -174,4 +202,4 @@ onBeforeUnmount(() => { @@ -174,4 +202,4 @@ onBeforeUnmount(() => {
174 } 202 }
175 } 203 }
176 } 204 }
177 -</style> 205 +</style>
@@ -448,9 +448,17 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => { @@ -448,9 +448,17 @@ export const useDynamicPublicForm = (paramsItemList: Ref<ParamsItemType[]>) => {
448 Reflect.deleteProperty(params, key) 448 Reflect.deleteProperty(params, key)
449 }) 449 })
450 params[BuiltInVariable.SELECT_TIME_AGGREGATION] = {} 450 params[BuiltInVariable.SELECT_TIME_AGGREGATION] = {}
  451 + params[BuiltInVariable.SELECT_TIME_AGGREGATION].agg = null
  452 + params[BuiltInVariable.SELECT_TIME_AGGREGATION].limit = 7
  453 + params[BuiltInVariable.SELECT_TIME_AGGREGATION].interval = null
  454 + getSelectDeviceAttr.value.value = null
  455 + getSelectOrgTree.value.value = null
  456 + getSelectDeviceProfile.value.value = null
  457 + getSelectDevice.value.value = null
451 } 458 }
452 459
453 const setDynamicFormValue = (params: Recordable) => { 460 const setDynamicFormValue = (params: Recordable) => {
  461 + clearParams()
454 setParams(params) 462 setParams(params)
455 getOrgOption() 463 getOrgOption()
456 getDeviceProfileOption() 464 getDeviceProfileOption()
@@ -99,6 +99,7 @@ const handleSelectedInterfaceChange = async (_value: string, option: PublicInter @@ -99,6 +99,7 @@ const handleSelectedInterfaceChange = async (_value: string, option: PublicInter
99 const { filter } = option 99 const { filter } = option
100 const { targetData } = useTargetData() 100 const { targetData } = useTargetData()
101 targetData.value.filter = filter ?? 'return res' 101 targetData.value.filter = filter ?? 'return res'
  102 + targetData.value.request.publicInterfaceSelectId = option.id as string
102 //ft 103 //ft
103 setDynamicFormValue(option as unknown as ExtraRequestConfigType) 104 setDynamicFormValue(option as unknown as ExtraRequestConfigType)
104 } 105 }
@@ -154,7 +155,7 @@ const getConfigurationData = () => { @@ -154,7 +155,7 @@ const getConfigurationData = () => {
154 155
155 const setConfigurationData = async (request: ExtraRequestConfigType) => { 156 const setConfigurationData = async (request: ExtraRequestConfigType) => {
156 await getPublicInterfaceList() 157 await getPublicInterfaceList()
157 - const { requestDataPondId, requestParams, requestParamsBodyType, requestContentType, requestHttpType, requestIntervalUnit, requestInterval } = request 158 + const { requestDataPondId, requestParams, requestParamsBodyType, requestContentType, requestHttpType, requestIntervalUnit, requestInterval, publicInterfaceSelectId } = request
158 const { Header } = requestParams 159 const { Header } = requestParams
159 /** 160 /**
160 * ft 修改 161 * ft 修改
@@ -162,7 +163,8 @@ const setConfigurationData = async (request: ExtraRequestConfigType) => { @@ -162,7 +163,8 @@ const setConfigurationData = async (request: ExtraRequestConfigType) => {
162 * 源代码 selectedPublicInterface.value = requestDataPondId 163 * 源代码 selectedPublicInterface.value = requestDataPondId
163 * 修改后代码 selectedPublicInterface.value = publicInterfaceList.value.find(it=>it.id === requestDataPondId)?.id||'' 164 * 修改后代码 selectedPublicInterface.value = publicInterfaceList.value.find(it=>it.id === requestDataPondId)?.id||''
164 */ 165 */
165 - selectedPublicInterface.value = publicInterfaceList.value.find(it => it.id === requestDataPondId)?.id || '' 166 + console.log(publicInterfaceList.value)
  167 + selectedPublicInterface.value = publicInterfaceList.value.find(it => it.id === publicInterfaceSelectId)?.id || ''
166 //ft 168 //ft
167 requestContentTypeRef.value = requestContentType 169 requestContentTypeRef.value = requestContentType
168 requestHttpTypeRef.value = requestHttpType 170 requestHttpTypeRef.value = requestHttpType
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 + NDivider,
  18 + CascaderOption,
  19 + NCascader,
  20 +} from 'naive-ui'
  21 +import { computed, onMounted, reactive, ref, unref } from 'vue'
6 import GlobalParamsConfiguration from './GlobalParamsConfiguration.vue' 22 import GlobalParamsConfiguration from './GlobalParamsConfiguration.vue'
7 import { ChevronDown, ChevronUp } from '@vicons/carbon' 23 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'; 24 +import { useDesignStore } from '@/store/modules/designStore/designStore'
  25 +import { selectTimeOptions } from '../../../index.d'
  26 +import { useTargetData } from '../../../../hooks/useTargetData.hook'
  27 +import { RequestDataTypeEnum, RequestHttpIntervalEnum } from '@/enums/httpEnum'
  28 +import { RequestConfigType, RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
  29 +import { convertToCascadingData } from '@/utils/external/utils'
  30 +import { customThirdInterfaceRequest, thirdInterfaceRequest } from '@/api/external/customRequest'
12 31
13 const { PencilIcon } = icon.ionicons5 32 const { PencilIcon } = icon.ionicons5
  33 +
14 const designStore = useDesignStore() 34 const designStore = useDesignStore()
  35 +
15 const editDisabled = ref(false) 36 const editDisabled = ref(false)
  37 +
16 const collapseHeaderTable = ref(false) 38 const collapseHeaderTable = ref(false)
17 39
18 -const { chartEditStore } = useTargetData() 40 +const { targetData, chartEditStore } = useTargetData()
19 41
20 const handleCollapse = () => { 42 const handleCollapse = () => {
21 collapseHeaderTable.value = !unref(collapseHeaderTable) 43 collapseHeaderTable.value = !unref(collapseHeaderTable)
22 } 44 }
23 45
  46 +const requestDataPondLength = computed(()=>chartEditStore.getRequestGlobalConfig.requestDataPond.length)
24 47
25 // 颜色 48 // 颜色
26 const themeColor = computed(() => { 49 const themeColor = computed(() => {
27 return designStore.getAppTheme 50 return designStore.getAppTheme
28 }) 51 })
29 52
  53 +const selectGlobalPondValue = ref('')
  54 +
  55 +const selectGlobalPondIsToken = ref(true)
  56 +
  57 +const cacheSelectOption = ref<Recordable>({
  58 + dataPondRequestConfig:{
  59 + pondRequestOriginUrl:'',
  60 + pondRequestUrl:'',
  61 + pondRequestHttpType:'',
  62 + pondRequestParams: {
  63 + "Body": {
  64 + "form-data": {},
  65 + "x-www-form-urlencoded": {},
  66 + "json": "",
  67 + "xml": ""
  68 + },
  69 + "Header": {},
  70 + "Params": {}
  71 + },
  72 + requestVerificationToken:'',
  73 + }
  74 +})
30 75
  76 +const selectGlobalPondOptions = computed(() => {
  77 + return chartEditStore.getRequestGlobalConfig.requestDataPond.map(dataPond=>({
  78 + value:dataPond.dataPondId,
  79 + label:dataPond.dataPondName,
  80 + ...dataPond
  81 + }))
  82 +})
  83 +
  84 +const getTokenString = ref()
  85 +
  86 +const resOptions = ref<CascaderOption[]>([])
  87 +
  88 +const resValue = ref()
  89 +
  90 +const cascaderConfig = reactive({
  91 + hoverTrigger: true,
  92 + checkStrategyIsChild: true,
  93 + filterable: false,
  94 + showPath: true
  95 +})
31 96
  97 +const handleResCascader = (value: string | number, options: Recordable) => {
  98 + targetData.value.request.thirdSelectCascaderLabel = options.label
  99 + getTokenString.value = value as string | number
  100 + targetData.value.request.requestVerificationToken = value as string
  101 + targetData.value.request.requestDataType = RequestDataTypeEnum.AJAX
  102 +}
  103 +
  104 +const findCurrentPond = () => {
  105 + return selectGlobalPondOptions.value.find((pondItem: RequestDataPondItemType & {label: string, value: string}) => pondItem.dataPondId === targetData.value?.request?.requestDataPondId)
  106 +}
  107 +
  108 +const handleSelectGlobalPond = (_:string, options:RequestDataPondItemType & {label: string, value: string}) => {
  109 + selectGlobalPondIsToken.value = options.dataPondRequestConfig.pondRequestGlobalIsToken!
  110 + cacheSelectOption.value = options
  111 + targetData.value.request = options.dataPondRequestConfig
  112 + targetData.value.request.requestDataPondId = options.dataPondId
  113 + getTokenString.value =''
  114 + resOptions.value = []
  115 + resValue.value = null
  116 + handleExecuteRequest()
  117 +}
  118 +
  119 +//执行请求获取三方Token
  120 +const handleExecuteRequest = async () => {
  121 + try {
  122 + const originUrlString = cacheSelectOption.value?.dataPondRequestConfig?.pondRequestOriginUrl
  123 + const requestUrlString = cacheSelectOption.value?.dataPondRequestConfig?.pondRequestUrl
  124 + const body = cacheSelectOption.value?.dataPondRequestConfig?.pondRequestParams['Body']['json']
  125 + if(originUrlString && requestUrlString){
  126 + const request = {
  127 + requestOriginUrl: `${originUrlString}${requestUrlString}`,
  128 + body
  129 + }
  130 + const res = await customThirdInterfaceRequest(request as unknown as thirdInterfaceRequest)
  131 + resOptions.value = convertToCascadingData(res) as unknown as CascaderOption[]
  132 + resValue.value = targetData.value?.request?.thirdSelectCascaderLabel
  133 + }
  134 + } catch (e) {
  135 + getTokenString.value = JSON.stringify(e) as string
  136 + }
  137 +}
  138 +
  139 +onMounted(()=>{
  140 + getTokenString.value = targetData.value?.request?.requestVerificationToken
  141 + selectGlobalPondValue.value = findCurrentPond()?.dataPondId as string
  142 + selectGlobalPondIsToken.value = findCurrentPond()?.dataPondRequestConfig.pondRequestGlobalIsToken as boolean
  143 + cacheSelectOption.value = findCurrentPond() as RequestDataPondItemType
  144 + resValue.value = targetData.value?.request?.thirdSelectCascaderLabel
  145 + targetData.value.request.pondRequestOriginUrl = findCurrentPond()?.dataPondRequestConfig?.pondRequestOriginUrl
  146 + targetData.value.request.pondRequestGlobalTokenKey = findCurrentPond()?.dataPondRequestConfig?.pondRequestGlobalTokenKey
  147 + targetData.value.request.pondRequestGlobalTokenSuffix = findCurrentPond()?.dataPondRequestConfig?.pondRequestGlobalTokenSuffix
  148 + targetData.value.request.pondRequestInterval = findCurrentPond()?.dataPondRequestConfig?.pondRequestInterval
  149 + targetData.value.request.pondRequestIntervalUnit = findCurrentPond()?.dataPondRequestConfig?.pondRequestIntervalUnit
  150 + targetData.value.request.pondRequestGlobalInterval = findCurrentPond()?.dataPondRequestConfig?.pondRequestGlobalInterval
  151 + targetData.value.request.pondRequestGlobalIntervalUnit = findCurrentPond()?.dataPondRequestConfig?.pondRequestGlobalIntervalUnit
  152 + handleExecuteRequest()
  153 +})
32 </script> 154 </script>
33 155
34 <template> 156 <template>
@@ -36,24 +158,44 @@ const themeColor = computed(() => { @@ -36,24 +158,44 @@ const themeColor = computed(() => {
36 <template #header> 158 <template #header>
37 <NTag type="info">全局公共配置</NTag> 159 <NTag type="info">全局公共配置</NTag>
38 </template> 160 </template>
39 - <NSpace vertical>  
40 - <SettingItemBox name="服务" :itemRightStyle="{  
41 - gridTemplateColumns: '5fr 2fr 1fr'  
42 - }"> 161 + <NSpace v-if="requestDataPondLength<=0" vertical>
  162 + <SettingItemBox
  163 + name="服务"
  164 + :itemRightStyle="{
  165 + gridTemplateColumns: '5fr 2fr 1fr'
  166 + }"
  167 + >
43 <!-- 源地址 --> 168 <!-- 源地址 -->
44 <SettingItem name="前置 URL"> 169 <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> 170 + <NInput
  171 + v-model:value="chartEditStore.getRequestGlobalConfig.requestOriginUrl"
  172 + default-value="http://127.0.0.1"
  173 + :disabled="editDisabled"
  174 + size="small"
  175 + placeholder="例:http://127.0.0.1"
  176 + ></NInput>
47 </SettingItem> 177 </SettingItem>
48 <SettingItem name="更新间隔,为 0 只会初始化"> 178 <SettingItem name="更新间隔,为 0 只会初始化">
49 <NInputGroup> 179 <NInputGroup>
50 - <NInputNumber v-model:value="chartEditStore.getRequestGlobalConfig.requestInterval" class="select-time-number"  
51 - size="small" min="0" :show-button="false" :disabled="editDisabled" placeholder="请输入数字"> 180 + <NInputNumber
  181 + v-model:value="chartEditStore.getRequestGlobalConfig.requestInterval"
  182 + class="select-time-number"
  183 + size="small"
  184 + min="0"
  185 + :show-button="false"
  186 + :disabled="editDisabled"
  187 + placeholder="请输入数字"
  188 + >
52 </NInputNumber> 189 </NInputNumber>
53 <!-- 单位 --> 190 <!-- 单位 -->
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" /> 191 + <NSelect
  192 + v-model:value="chartEditStore.getRequestGlobalConfig.requestIntervalUnit"
  193 + class="select-time-options"
  194 + size="small"
  195 + :default-value="RequestHttpIntervalEnum.SECOND"
  196 + :options="selectTimeOptions as SelectOption[]"
  197 + :disabled="editDisabled"
  198 + />
57 </NInputGroup> 199 </NInputGroup>
58 </SettingItem> 200 </SettingItem>
59 <NButton v-show="editDisabled" type="primary" ghost @click="editDisabled = false"> 201 <NButton v-show="editDisabled" type="primary" ghost @click="editDisabled = false">
@@ -80,10 +222,68 @@ const themeColor = computed(() => { @@ -80,10 +222,68 @@ const themeColor = computed(() => {
80 </NTooltip> 222 </NTooltip>
81 </section> 223 </section>
82 </NSpace> 224 </NSpace>
  225 + <div v-else>
  226 + <NSelect
  227 + v-model:value="selectGlobalPondValue"
  228 + placeholder="请选择全局公共配置"
  229 + class="select-time-options"
  230 + size="small"
  231 + clearable
  232 + :options="selectGlobalPondOptions"
  233 + @update:value="handleSelectGlobalPond"
  234 + />
  235 + <NDivider />
  236 + <SettingItemBox name="配置信息" v-if="selectGlobalPondValue" :itemRightStyle="{
  237 + gridTemplateColumns: '5fr 2fr 1fr'
  238 + }">
  239 + <SettingItem name="源地址">
  240 + <NInput
  241 + v-model:value="cacheSelectOption.dataPondRequestConfig.pondRequestOriginUrl"
  242 + disabled
  243 + ></NInput>
  244 + </SettingItem>
  245 + <SettingItem name="url地址">
  246 + <NInput
  247 + v-model:value="cacheSelectOption.dataPondRequestConfig.pondRequestUrl"
  248 + disabled
  249 + ></NInput>
  250 + </SettingItem>
  251 + <SettingItem name="请求方式">
  252 + <NInput
  253 + v-model:value="cacheSelectOption.dataPondRequestConfig.pondRequestHttpType"
  254 + disabled
  255 + ></NInput>
  256 + </SettingItem>
  257 + </SettingItemBox>
  258 + <NDivider />
  259 + <div style="margin:0 70px" v-if="selectGlobalPondValue && selectGlobalPondIsToken">
  260 + <n-space vertical>
  261 + <n-button type="primary" @click="handleExecuteRequest">执行请求</n-button>
  262 + <NCascader
  263 + v-model:value="resValue"
  264 + @update:value="handleResCascader"
  265 + :expand-trigger="cascaderConfig.hoverTrigger ? 'hover' : 'click'"
  266 + :check-strategy="cascaderConfig.checkStrategyIsChild ? 'child' : 'all'"
  267 + :show-path="cascaderConfig.showPath"
  268 + :filterable="cascaderConfig.filterable"
  269 + placeholder="请选择"
  270 + :options="resOptions"
  271 + />
  272 + <n-input
  273 + :autosize="{
  274 + minRows: 3,
  275 + maxRows: 9
  276 + }"
  277 + v-model:value="getTokenString"
  278 + type="textarea"
  279 + placeholder="Token:"
  280 + />
  281 + </n-space>
  282 + </div>
  283 + </div>
83 </NCard> 284 </NCard>
84 </template> 285 </template>
85 286
86 -  
87 <style lang="scss" scoped> 287 <style lang="scss" scoped>
88 .arrow { 288 .arrow {
89 display: flex; 289 display: flex;
@@ -93,7 +293,6 @@ const themeColor = computed(() => { @@ -93,7 +293,6 @@ const themeColor = computed(() => {
93 293
94 &:hover { 294 &:hover {
95 color: v-bind('themeColor'); 295 color: v-bind('themeColor');
96 -  
97 } 296 }
98 } 297 }
99 </style> 298 </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 = () => {  
132 - return { id: getUUID(), result: true } as DataSource 176 +const createNewRow = (index?: number) => {
  177 + return { id: getUUID(), result: true, indexName: index, typeName: DataTypeEnum.DATA_INPUT } as DataSource
133 } 178 }
134 179
135 -const dataSource = ref<DataSource[]>([  
136 - createNewRow()  
137 -]) 180 +const dataSource = ref<DataSource[]>([createNewRow(0)])
  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(keyIndex),
  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,22 +201,21 @@ watch( @@ -151,22 +201,21 @@ 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 })
161 207
162 const handleAddRow = (record: DataSource) => { 208 const handleAddRow = (record: DataSource) => {
163 const index = unref(dataSource).findIndex(item => item.id === record.id) 209 const index = unref(dataSource).findIndex(item => item.id === record.id)
164 - unref(dataSource).splice(index + 1, 0, createNewRow()) 210 + unref(dataSource).splice(index + 1, 0, createNewRow(index + 1))
165 } 211 }
166 212
167 const handleSubtractRow = (record: DataSource) => { 213 const handleSubtractRow = (record: DataSource) => {
168 const index = unref(dataSource).findIndex(item => item.id === record.id) 214 const index = unref(dataSource).findIndex(item => item.id === record.id)
169 if (unref(dataSource).length === 1) { 215 if (unref(dataSource).length === 1) {
  216 + unref(dataSource)[0].keyName = ''
  217 + unref(dataSource)[0].value = ''
  218 + unref(dataSource)[0].dateRange = []
170 emit('update:value', {}) 219 emit('update:value', {})
171 } else { 220 } else {
172 unref(dataSource).splice(index, 1) 221 unref(dataSource).splice(index, 1)
@@ -174,23 +223,19 @@ const handleSubtractRow = (record: DataSource) => { @@ -174,23 +223,19 @@ const handleSubtractRow = (record: DataSource) => {
174 } 223 }
175 } 224 }
176 225
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 - } 226 +const handleInputBlur = () => {
  227 + blurFlag.value = true
  228 + emit('update:value', getHeaderConfiguration())
184 } 229 }
185 230
186 const getHeaderConfiguration = () => { 231 const getHeaderConfiguration = () => {
187 return unref(dataSource).reduce((prev, next) => { 232 return unref(dataSource).reduce((prev, next) => {
188 - const { result, value, keyName } = next  
189 - const header = result && value && keyName ? { [keyName]: value } : {} 233 + const { value, keyName, dateRange } = next
  234 + const header = keyName ? { [keyName as unknown as string]: dateRange && isArray(dateRange) ? dateRange: value } : {}
  235 + for (let item in header) if (!Reflect.get(header, item)) Reflect.deleteProperty(header, item)
190 return { ...prev, ...header } 236 return { ...prev, ...header }
191 }, {} as Recordable) 237 }, {} as Recordable)
192 } 238 }
193 -  
194 </script> 239 </script>
195 240
196 <template> 241 <template>
  1 +<template>
  2 + <n-modal
  3 + class="go-chart-data-request"
  4 + v-model:show="modelShowRef"
  5 + :mask-closable="false"
  6 + :closeOnEsc="true"
  7 + :onEsc="onEsc"
  8 + >
  9 + <n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 800px">
  10 + <template #header></template>
  11 + <template #header-extra> </template>
  12 + <n-scrollbar style="max-height: 718px">
  13 + <div class="go-pr-3">
  14 + <n-space vertical>
  15 + <PondPublicConfiguration ref="pondPublicConfigurationRef" />
  16 + <PondRequestConfiguration ref="pondRequestConfigurationRef" />
  17 + </n-space>
  18 + </div>
  19 + </n-scrollbar>
  20 + <!-- 底部 -->
  21 + <template #action>
  22 + <n-space justify="space-between">
  23 + <n-space v-if="targetDataRequest">
  24 + <n-tag :bordered="false" type="primary">名称:</n-tag>
  25 + <n-input
  26 + v-model:value="targetDataRequest.dataPondName"
  27 + ref="inputInstRef"
  28 + type="text"
  29 + size="small"
  30 + :autofocus="true"
  31 + :clearable="true"
  32 + :minlength="1"
  33 + :maxlength="16"
  34 + placeholder="请输入名称"
  35 + ></n-input>
  36 + </n-space>
  37 + <span v-else></span>
  38 + <n-space>
  39 + <n-button @click="closeHandle">取消</n-button>
  40 + <n-button type="primary" @click="closeAndSendHandle">保存</n-button>
  41 + </n-space>
  42 + </n-space>
  43 + </template>
  44 + </n-card>
  45 + </n-modal>
  46 +</template>
  47 +
  48 +<script script lang="ts" setup>
  49 +import { PropType, ref, watch, onMounted, nextTick } from 'vue'
  50 +import { RequestConfigType, RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
  51 +import { goDialog } from '@/utils'
  52 +import PondPublicConfiguration from './PondPublicConfiguration.vue'
  53 +import PondRequestConfiguration from './PondRequestConfiguration.vue'
  54 +import { useTargetData } from '../../../../hooks/useTargetData.hook'
  55 +
  56 +const props = defineProps({
  57 + modelShow: Boolean,
  58 + targetDataRequest: Object as PropType<RequestDataPondItemType>,
  59 +})
  60 +
  61 +const { targetData } = useTargetData()
  62 +
  63 +const pondPublicConfigurationRef = ref<InstanceType<typeof PondPublicConfiguration>>()
  64 +
  65 +const pondRequestConfigurationRef = ref<InstanceType<typeof PondRequestConfiguration>>()
  66 +
  67 +const emit = defineEmits(['update:modelShow', 'editSaveHandle'])
  68 +
  69 +const inputInstRef = ref()
  70 +
  71 +const modelShowRef = ref(false)
  72 +
  73 +watch(
  74 + () => props.modelShow,
  75 + newValue => {
  76 + modelShowRef.value = newValue
  77 + if(newValue) {
  78 + nextTick(() => {
  79 + pondPublicConfigurationRef?.value?.setConfigurationData(props.targetDataRequest?.dataPondRequestConfig as unknown as RequestConfigType)
  80 + pondRequestConfigurationRef?.value?.setConfigurationData(props.targetDataRequest?.dataPondRequestConfig as unknown as RequestDataPondItemType)
  81 + })
  82 + }
  83 + }
  84 +)
  85 +
  86 +const closeHandle = () => {
  87 + emit('update:modelShow', false)
  88 +}
  89 +
  90 +const closeAndSendHandle = () => {
  91 + if (!props.targetDataRequest?.dataPondName) {
  92 + window.$message.warning('请在左下角输入名称!')
  93 + inputInstRef.value?.focus()
  94 + return
  95 + }
  96 + const pondPublicData = pondPublicConfigurationRef?.value?.getConfigurationData()
  97 + const pondRequestData = pondRequestConfigurationRef?.value?.getConfigurationData()
  98 + const mergeTargetDataRequestData = Object.assign(props.targetDataRequest.dataPondRequestConfig, pondPublicData, pondRequestData)
  99 + props.targetDataRequest.dataPondRequestConfig = mergeTargetDataRequestData
  100 + goDialog({
  101 + message: '保存内容将同步修改所有使用此接口的组件, 是否继续?',
  102 + isMaskClosable: true,
  103 + transformOrigin: 'center',
  104 + onPositiveCallback: () => {
  105 + emit('update:modelShow', false)
  106 + emit('editSaveHandle', props.targetDataRequest)
  107 + }
  108 + })
  109 +}
  110 +
  111 +const onEsc = () => {
  112 + closeHandle()
  113 +}
  114 +
  115 +onMounted(()=>{
  116 + pondPublicConfigurationRef?.value?.setConfigurationData(targetData.value.request)
  117 + pondRequestConfigurationRef?.value?.setConfigurationData(targetData.value.request)
  118 +})
  119 +</script>
  120 +
  121 +<style lang="scss" scoped>
  122 +@include go('chart-data-request') {
  123 + &.n-card.n-modal,
  124 + .n-card {
  125 + @extend .go-background-filter;
  126 + }
  127 + .n-card-shallow {
  128 + background-color: rgba(0, 0, 0, 0) !important;
  129 + }
  130 + @include deep() {
  131 + & > .n-card__content {
  132 + padding-right: 0;
  133 + }
  134 + .n-card__content {
  135 + padding-bottom: 5px;
  136 + }
  137 + }
  138 +}
  139 +</style>
  1 +<script lang="ts" setup name="PondPublicConfiguration">
  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 +} from 'naive-ui'
  18 +import { computed, ref, unref } from 'vue'
  19 +import GlobalParamsConfiguration from './GlobalParamsConfiguration.vue'
  20 +import { ChevronDown, ChevronUp } from '@vicons/carbon'
  21 +import { useDesignStore } from '@/store/modules/designStore/designStore'
  22 +import { selectTimeOptions } from '../../../index.d'
  23 +import { RequestHttpIntervalEnum } from '@/enums/httpEnum'
  24 +import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
  25 +import { useTargetData } from '../../../../hooks/useTargetData.hook'
  26 +
  27 +const { PencilIcon } = icon.ionicons5
  28 +
  29 +const designStore = useDesignStore()
  30 +
  31 +const { targetData } = useTargetData()
  32 +
  33 +const editDisabled = ref(false)
  34 +
  35 +const collapseHeaderTable = ref(false)
  36 +
  37 +const pondRequestOriginUrlRef= ref('')
  38 +
  39 +const pondRequestIntervalRef = ref()
  40 +
  41 +const pondRequestIntervalUnitRef = ref(RequestHttpIntervalEnum.SECOND)
  42 +
  43 +const pondRequestGlobalTokenSuffixRef = ref('')
  44 +
  45 +const pondRequestGlobalTokenKeyRef = ref('')
  46 +
  47 +const pondRequestGlobalIsTokenRef = ref(true)
  48 +
  49 +const handleCollapse = () => {
  50 + collapseHeaderTable.value = !unref(collapseHeaderTable)
  51 +}
  52 +
  53 +// 颜色
  54 +const themeColor = computed(() => {
  55 + return designStore.getAppTheme
  56 +})
  57 +
  58 +const handleIsTokenSwitch = (value: boolean) => {
  59 + targetData.value.request.pondRequestGlobalIsToken = value
  60 +}
  61 +
  62 +const getConfigurationData = (): Partial<RequestConfigType> => {
  63 + return {
  64 + pondRequestOriginUrl: unref(pondRequestOriginUrlRef),
  65 + pondRequestGlobalInterval: unref(pondRequestIntervalRef),
  66 + pondRequestGlobalIntervalUnit: unref(pondRequestIntervalUnitRef),
  67 + pondRequestGlobalTokenSuffix: unref(pondRequestGlobalTokenSuffixRef),
  68 + pondRequestGlobalTokenKey: unref(pondRequestGlobalTokenKeyRef),
  69 + pondRequestGlobalIsToken: unref(pondRequestGlobalIsTokenRef),
  70 + }
  71 +}
  72 +
  73 +const setConfigurationData = (request: Partial<RequestConfigType>) => {
  74 + const { pondRequestOriginUrl, pondRequestGlobalInterval, pondRequestGlobalIntervalUnit, pondRequestGlobalTokenSuffix, pondRequestGlobalTokenKey, pondRequestGlobalIsToken } = request
  75 + pondRequestOriginUrlRef.value = pondRequestOriginUrl!
  76 + pondRequestIntervalRef.value = pondRequestGlobalInterval
  77 + pondRequestIntervalUnitRef.value = pondRequestGlobalIntervalUnit! as RequestHttpIntervalEnum
  78 + pondRequestGlobalTokenSuffixRef.value = pondRequestGlobalTokenSuffix!
  79 + pondRequestGlobalTokenKeyRef.value = pondRequestGlobalTokenKey!
  80 + pondRequestGlobalIsTokenRef.value = pondRequestGlobalIsToken!
  81 +}
  82 +
  83 +defineExpose({
  84 + getConfigurationData,
  85 + setConfigurationData
  86 +})
  87 +</script>
  88 +
  89 +<template>
  90 + <NCard>
  91 + <template #header>
  92 + <NTag type="info">全局公共配置</NTag>
  93 + </template>
  94 + <NSpace vertical>
  95 + <SettingItemBox
  96 + name="服务"
  97 + :itemRightStyle="{
  98 + gridTemplateColumns: '5fr 2fr 1fr'
  99 + }"
  100 + >
  101 + <!-- 源地址 -->
  102 + <SettingItem name="前置 URL">
  103 + <NInput
  104 + v-model:value="pondRequestOriginUrlRef"
  105 + default-value="http://127.0.0.1"
  106 + :disabled="editDisabled"
  107 + size="small"
  108 + placeholder="例:http://127.0.0.1"
  109 + ></NInput>
  110 + </SettingItem>
  111 + <SettingItem name="更新间隔,为 0 只会初始化">
  112 + <NInputGroup>
  113 + <NInputNumber
  114 + v-model:value="pondRequestIntervalRef"
  115 + class="select-time-number"
  116 + size="small"
  117 + min="0"
  118 + :show-button="false"
  119 + :disabled="editDisabled"
  120 + placeholder="请输入数字"
  121 + >
  122 + </NInputNumber>
  123 + <!-- 单位 -->
  124 + <NSelect
  125 + v-model:value="pondRequestIntervalUnitRef"
  126 + class="select-time-options"
  127 + size="small"
  128 + :default-value="RequestHttpIntervalEnum.SECOND"
  129 + :options="selectTimeOptions as SelectOption[]"
  130 + :disabled="editDisabled"
  131 + />
  132 + </NInputGroup>
  133 + </SettingItem>
  134 + <NButton v-show="editDisabled" type="primary" ghost @click="editDisabled = false">
  135 + <template #icon>
  136 + <NIcon>
  137 + <PencilIcon />
  138 + </NIcon>
  139 + </template>
  140 + 编辑配置
  141 + </NButton>
  142 + </SettingItemBox>
  143 + <!-- 针对第三方接口 -->
  144 + <SettingItemBox name="Token配置">
  145 + <SettingItem>
  146 + <n-switch @update:value="handleIsTokenSwitch" v-model:value="pondRequestGlobalIsTokenRef"/>
  147 + </SettingItem>
  148 + </SettingItemBox>
  149 + <SettingItemBox v-if="pondRequestGlobalIsTokenRef" name="配置">
  150 + <SettingItem name="请求标头">
  151 + <n-input v-model:value.trim="pondRequestGlobalTokenKeyRef" type="text" placeholder="默认值: X-Authorization " />
  152 + </SettingItem>
  153 + <SettingItem name="Token值前缀">
  154 + <n-input clearable v-model:value.trim="pondRequestGlobalTokenSuffixRef" type="text" placeholder="默认值:Bearer" />
  155 + </SettingItem>
  156 + </SettingItemBox>
  157 + <NCollapseTransition :show="collapseHeaderTable">
  158 + <GlobalParamsConfiguration />
  159 + <!-- 针对第三方接口 -->
  160 + </NCollapseTransition>
  161 + <section class="arrow">
  162 + <NTooltip>
  163 + <template #trigger>
  164 + <NIcon @click="handleCollapse" size="30">
  165 + <ChevronDown v-show="!collapseHeaderTable" />
  166 + <ChevronUp v-show="collapseHeaderTable" />
  167 + </NIcon>
  168 + </template>
  169 + <span>{{ collapseHeaderTable ? '收起' : '展开' }}</span>
  170 + </NTooltip>
  171 + </section>
  172 + </NSpace>
  173 + </NCard>
  174 +</template>
  175 +
  176 +<style lang="scss" scoped>
  177 +.arrow {
  178 + display: flex;
  179 + justify-content: center;
  180 + align-items: center;
  181 + cursor: pointer;
  182 +
  183 + &:hover {
  184 + color: v-bind('themeColor');
  185 + }
  186 +}
  187 +</style>
  1 +<script setup lang="ts">
  2 +import { NInput, NInputNumber, NInputGroup, NSelect, SelectOption, NTabs, NTabPane } from 'naive-ui'
  3 +import { SettingItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
  4 +import { selectTimeOptions, selectTypeOptions } from '../../../index.d'
  5 +import {
  6 + RequestBodyEnum,
  7 + RequestContentTypeEnum,
  8 + RequestHttpEnum,
  9 + RequestHttpIntervalEnum,
  10 + RequestParams
  11 +} from '@/enums/httpEnum'
  12 +import { ref, unref } from 'vue'
  13 +import DefaultRequestContent from './DefaultRequestContent.vue'
  14 +import SqlConfiguration from './SqlConfiguration.vue'
  15 +import { useTargetData } from '../../../../hooks/useTargetData.hook'
  16 +
  17 +const { targetData } = useTargetData()
  18 +
  19 +const pondRequestContentTypeRef = ref(RequestContentTypeEnum.DEFAULT)
  20 +
  21 +const pondRequestHttpTypeRef = ref(RequestHttpEnum.GET)
  22 +
  23 +const pondRequestIntervalRef = ref<number | undefined>(20)
  24 +
  25 +const pondRequestIntervalUnitRef = ref(RequestHttpIntervalEnum.SECOND)
  26 +
  27 +const pondRequestSQLContentRef = ref('select * from where')
  28 +
  29 +const pondRequestParamsRef = ref({
  30 + Header: {},
  31 + Params: {},
  32 + Body: { 'form-data': {}, json: '', 'x-www-form-urlencoded': {}, xml: '' }
  33 +} as RequestParams)
  34 +
  35 +const pondRequestParamsBodyTypeRef = ref(RequestBodyEnum.NONE)
  36 +
  37 +const pondRequestUrlRef = ref<string>()
  38 +
  39 +const getConfigurationData = (): Recordable => {
  40 + return {
  41 + pondRequestInterval: unref(pondRequestIntervalRef),
  42 + pondRequestIntervalUnit: unref(pondRequestIntervalUnitRef),
  43 + pondRequestHttpType: unref(pondRequestHttpTypeRef),
  44 + pondRequestUrl: unref(pondRequestUrlRef),
  45 + pondRequestContentType: unref(pondRequestContentTypeRef),
  46 + pondRequestSQLContent: unref(pondRequestSQLContentRef),
  47 + pondRequestParamsBodyType: unref(pondRequestParamsBodyTypeRef),
  48 + pondRequestParams: unref(pondRequestParamsRef)
  49 + }
  50 +}
  51 +
  52 +const setConfigurationData = (request: Recordable) => {
  53 + const {
  54 + pondRequestInterval,
  55 + pondRequestIntervalUnit,
  56 + pondRequestHttpType,
  57 + pondRequestUrl,
  58 + pondRequestContentType,
  59 + pondRequestSQLContent,
  60 + pondRequestParamsBodyType,
  61 + pondRequestParams
  62 + } = request
  63 + pondRequestIntervalRef.value = pondRequestInterval
  64 + pondRequestIntervalUnitRef.value = pondRequestIntervalUnit
  65 + pondRequestHttpTypeRef.value = pondRequestHttpType
  66 + pondRequestUrlRef.value = pondRequestUrl
  67 + pondRequestContentTypeRef.value = pondRequestContentType
  68 + pondRequestSQLContentRef.value = pondRequestSQLContent
  69 + pondRequestParamsBodyTypeRef.value = pondRequestParamsBodyType
  70 + pondRequestParamsRef.value = pondRequestParams
  71 +}
  72 +
  73 +defineExpose({
  74 + getConfigurationData,
  75 + setConfigurationData
  76 +})
  77 +</script>
  78 +
  79 +<template>
  80 + <div v-if="targetData.request.pondRequestGlobalIsToken">
  81 + <NDivider />
  82 + <SettingItemBox
  83 + name="地址"
  84 + :itemRightStyle="{
  85 + gridTemplateColumns: '5fr 2fr 1fr'
  86 + }"
  87 + >
  88 + <SettingItem name="请求方式 & URL地址">
  89 + <NInputGroup>
  90 + <NSelect
  91 + v-model:value="pondRequestHttpTypeRef"
  92 + style="width: 150px"
  93 + size="small"
  94 + :options="(selectTypeOptions as SelectOption[])"
  95 + />
  96 + <NInput
  97 + v-model:value="pondRequestUrlRef"
  98 + class="select-time-number"
  99 + size="small"
  100 + min="0"
  101 + :show-button="false"
  102 + placeholder="请输入URL地址"
  103 + />
  104 + </NInputGroup>
  105 + </SettingItem>
  106 + <SettingItem name="更新间隔,为 0 只会初始化">
  107 + <NInputGroup>
  108 + <NInputNumber
  109 + v-model:value="pondRequestIntervalRef"
  110 + class="select-time-number"
  111 + size="small"
  112 + min="0"
  113 + :show-button="false"
  114 + placeholder="请输入数字"
  115 + />
  116 + <!-- 单位 -->
  117 + <NSelect
  118 + v-model:value="pondRequestIntervalUnitRef"
  119 + class="select-time-options"
  120 + size="small"
  121 + :options="(selectTimeOptions as SelectOption[])"
  122 + />
  123 + </NInputGroup>
  124 + </SettingItem>
  125 + </SettingItemBox>
  126 + <SettingItemBox name="选择方式">
  127 + <NTabs v-model:value="pondRequestContentTypeRef" type="segment" size="small">
  128 + <NTabPane :name="RequestContentTypeEnum.DEFAULT" tab="普通请求" />
  129 + <NTabPane :name="RequestContentTypeEnum.SQL" tab="SQL请求" />
  130 + </NTabs>
  131 + </SettingItemBox>
  132 + <SettingItemBox>
  133 + <DefaultRequestContent
  134 + v-if="pondRequestContentTypeRef === RequestContentTypeEnum.DEFAULT"
  135 + v-model:value="pondRequestParamsRef"
  136 + v-model:request-params-body-type="pondRequestParamsBodyTypeRef"
  137 + />
  138 + <SqlConfiguration
  139 + v-model:value="pondRequestSQLContentRef"
  140 + v-if="pondRequestContentTypeRef === RequestContentTypeEnum.SQL"
  141 + />
  142 + </SettingItemBox>
  143 +</div>
  144 +</template>
@@ -41,7 +41,7 @@ const handleSyncRequestParamsBodyType = (value: RequestBodyEnum) => { @@ -41,7 +41,7 @@ const handleSyncRequestParamsBodyType = (value: RequestBodyEnum) => {
41 v-model:value="value.Body[RequestBodyEnum.X_WWW_FORM_URLENCODED]" /> 41 v-model:value="value.Body[RequestBodyEnum.X_WWW_FORM_URLENCODED]" />
42 42
43 <MonacoEditor v-if="requestParamsBodyType === RequestBodyEnum.JSON" 43 <MonacoEditor v-if="requestParamsBodyType === RequestBodyEnum.JSON"
44 - v-model:modelValue="value.Body[RequestBodyEnum.JSON]" width="600px" height="200px" language="json" /> 44 + v-model:modelValue="value.Body[RequestBodyEnum.JSON]" width="600px" height="200px" language="json" :config="true" />
45 45
46 <MonacoEditor v-if="requestParamsBodyType === RequestBodyEnum.XML" 46 <MonacoEditor v-if="requestParamsBodyType === RequestBodyEnum.XML"
47 v-model:modelValue="value.Body[RequestBodyEnum.XML]" width="600px" height="200px" language="xml" /> 47 v-model:modelValue="value.Body[RequestBodyEnum.XML]" width="600px" height="200px" language="xml" />
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'
  17 +import { JSONParse } from '@/utils/external/utils'
  18 +import { isArray } from '@/utils/external/is'
18 19
19 const requestDataType = ref<RequestDataTypeEnum>(RequestDataTypeEnum.AJAX) 20 const requestDataType = ref<RequestDataTypeEnum>(RequestDataTypeEnum.AJAX)
20 21
@@ -36,7 +37,6 @@ const openModal = async (flag = true, type: RequestDataTypeEnum) => { @@ -36,7 +37,6 @@ const openModal = async (flag = true, type: RequestDataTypeEnum) => {
36 requestDataType.value = type 37 requestDataType.value = type
37 showModal.value = flag 38 showModal.value = flag
38 await nextTick() 39 await nextTick()
39 -  
40 unref(componentConfigurationEl as any)?.setConfigurationData(unref(selectTarget)!.request || {}) 40 unref(componentConfigurationEl as any)?.setConfigurationData(unref(selectTarget)!.request || {})
41 unref(publicInterfaceFormEl as any)?.setConfigurationData(unref(selectTarget)!.request || {}) 41 unref(publicInterfaceFormEl as any)?.setConfigurationData(unref(selectTarget)!.request || {})
42 } 42 }
@@ -81,15 +81,40 @@ const sendHandle = async () => { @@ -81,15 +81,40 @@ const sendHandle = async () => {
81 const res = await fetchTargetData() 81 const res = await fetchTargetData()
82 if (res) { 82 if (res) {
83 const { value } = useFilterFn(targetData.value.filter, res) 83 const { value } = useFilterFn(targetData.value.filter, res)
  84 + //分组更新下面子组件
  85 + if(targetData.value.isGroup) {
  86 + if (isArray(targetData.value.saveHistoryInput!)) {
  87 + const parseHistoryInput = JSONParse(targetData.value.saveHistoryInput!)
  88 + parseHistoryInput?.forEach((historyItem:Recordable) => {
  89 + const findCurrentItem = targetData.value.groupList?.find((groupItem:CreateComponentType | CreateComponentGroupType) => groupItem.id === historyItem.id)
  90 + if(findCurrentItem) {
  91 + findCurrentItem.option.dataset = value[historyItem.inputValue]
  92 + }
  93 + })
  94 + }
  95 + }
  96 + //
84 targetData.value.option.dataset = value 97 targetData.value.option.dataset = value
85 return 98 return
86 } 99 }
87 -  
88 } 100 }
89 101
90 const handleSaveAction = async () => { 102 const handleSaveAction = async () => {
91 if (!(await validate())) return 103 if (!(await validate())) return
92 - const value = getResult() 104 + let value = getResult()
  105 + value.pondRequestGlobalTokenKey = targetData.value.request.pondRequestGlobalTokenKey
  106 + value.pondRequestGlobalTokenSuffix = targetData.value.request.pondRequestGlobalTokenSuffix
  107 + value.pondRequestInterval = targetData.value.request.pondRequestInterval
  108 + value.pondRequestIntervalUnit= targetData.value.request.pondRequestIntervalUnit
  109 + value.pondRequestOriginUrl= targetData.value.request.pondRequestOriginUrl
  110 + value.requestVerificationToken = targetData.value.request.requestVerificationToken
  111 + value.requestDataPondId = targetData.value.request.requestDataPondId
  112 + value.thirdSelectCascaderLabel = targetData.value.request.thirdSelectCascaderLabel
  113 + value.requestDataType = targetData.value.request.requestDataType
  114 + value.publicInterfaceSelectId = targetData.value.request.publicInterfaceSelectId
  115 + value.pondRequestGlobalIsToken = targetData.value.request.pondRequestGlobalIsToken
  116 + value.pondRequestGlobalIntervalUnit = targetData.value.request.pondRequestGlobalIntervalUnit
  117 + value.pondRequestGlobalInterval = targetData.value.request.pondRequestGlobalInterval
93 if (unref(selectTarget)) { 118 if (unref(selectTarget)) {
94 chartEditStore.updateComponentList(chartEditStore.fetchTargetIndex(), { 119 chartEditStore.updateComponentList(chartEditStore.fetchTargetIndex(), {
95 ...unref(selectTarget)!, 120 ...unref(selectTarget)!,
@@ -105,26 +130,29 @@ createRequestModalContext({ @@ -105,26 +130,29 @@ createRequestModalContext({
105 }) 130 })
106 131
107 defineExpose({ 132 defineExpose({
108 - openModal, 133 + openModal
109 }) 134 })
110 -  
111 </script> 135 </script>
112 136
113 <template> 137 <template>
114 - <NModal :class="prefixCls" v-model:show="showModal" preset="card" style="width: 1000px;" title="请求配置"> 138 + <NModal :class="prefixCls" v-model:show="showModal" preset="card" style="width: 1000px" title="请求配置">
115 <GlobalPublicConfiguration v-if="requestDataType === RequestDataTypeEnum.AJAX" /> 139 <GlobalPublicConfiguration v-if="requestDataType === RequestDataTypeEnum.AJAX" />
116 <NDivider v-if="requestDataType === RequestDataTypeEnum.AJAX" /> 140 <NDivider v-if="requestDataType === RequestDataTypeEnum.AJAX" />
117 <ComponentConfiguration v-if="requestDataType === RequestDataTypeEnum.AJAX" ref="componentConfigurationEl" /> 141 <ComponentConfiguration v-if="requestDataType === RequestDataTypeEnum.AJAX" ref="componentConfigurationEl" />
118 <PublicInterfaceForm v-if="requestDataType === RequestDataTypeEnum.Pond" ref="publicInterfaceFormEl" /> 142 <PublicInterfaceForm v-if="requestDataType === RequestDataTypeEnum.Pond" ref="publicInterfaceFormEl" />
119 <template #action> 143 <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"> 144 + <NSpace justify="space-between">
  145 + <div style="display: flex; flex-direction: column">
  146 + <NTag type="info"
  147 + >当公共接口选择“实时轨迹或者获取设备经纬度历史数据”时,属性选择则选择经纬度即可(longitude,latitude)</NTag
  148 + >
  149 + <div style="height: 5px"></div>
  150 + <NTag type="info"
  151 + >如果是结构体属性的话,选择对应结构体属性即可,里面的经纬度,平台已经通过接口里面的过滤函数进行处理</NTag
  152 + >
  153 + <div style="display: flex; align-items: center; margin-top: 10px">
126 <span>「 更多 」</span> 154 <span>「 更多 」</span>
127 - <span style="margin-right: 5px;">——</span> 155 + <span style="margin-right: 5px">——</span>
128 <NTag type="info">{{ getRequestTypeName }}</NTag> 156 <NTag type="info">{{ getRequestTypeName }}</NTag>
129 </div> 157 </div>
130 </div> 158 </div>
@@ -134,10 +162,8 @@ defineExpose({ @@ -134,10 +162,8 @@ defineExpose({
134 </NModal> 162 </NModal>
135 </template> 163 </template>
136 164
137 -  
138 -<style lang="scss" > 165 +<style lang="scss">
139 @include thingsKit('chart-data-request') { 166 @include thingsKit('chart-data-request') {
140 -  
141 &.n-card.n-modal, 167 &.n-card.n-modal,
142 .n-card { 168 .n-card {
143 @extend .go-background-filter; 169 @extend .go-background-filter;
@@ -148,7 +174,7 @@ defineExpose({ @@ -148,7 +174,7 @@ defineExpose({
148 } 174 }
149 175
150 @include deep() { 176 @include deep() {
151 - &>.n-card__content { 177 + & > .n-card__content {
152 padding-right: 0; 178 padding-right: 0;
153 } 179 }
154 180
@@ -91,7 +91,7 @@ @@ -91,7 +91,7 @@
91 </setting-item-box> 91 </setting-item-box>
92 <!-- THINGS_KIT 修改多画布切换相关代码 用于切换画布 --> 92 <!-- THINGS_KIT 修改多画布切换相关代码 用于切换画布 -->
93 93
94 - <setting-item-box v-if="!interactActionsIsPageChange&&fnDimensionsAndSource(item.interactOn).length" name="查询结果" :alone="true"> 94 + <setting-item-box v-if="!interactActionsIsPageChange && fnDimensionsAndSource(item.interactOn, null, null)!.length" name="查询结果" :alone="true">
95 <n-table size="small" striped> 95 <n-table size="small" striped>
96 <thead> 96 <thead>
97 <tr> 97 <tr>
@@ -99,9 +99,9 @@ @@ -99,9 +99,9 @@
99 </tr> 99 </tr>
100 </thead> 100 </thead>
101 <tbody> 101 <tbody>
102 - <tr v-for="(cItem, index) in fnDimensionsAndSource(item.interactOn)" :key="index">  
103 - <td>{{ cItem.value }}</td>  
104 - <td>{{ cItem.label }}</td> 102 + <tr v-for="(cItem, index) in fnDimensionsAndSource(item.interactOn, null, null)" :key="index">
  103 + <td>{{ cItem?.value }}</td>
  104 + <td>{{ cItem?.label }}</td>
105 </tr> 105 </tr>
106 </tbody> 106 </tbody>
107 </n-table> 107 </n-table>
@@ -123,8 +123,10 @@ @@ -123,8 +123,10 @@
123 <n-select 123 <n-select
124 size="tiny" 124 size="tiny"
125 v-model:value="item.interactFn[ovlKey]" 125 v-model:value="item.interactFn[ovlKey]"
126 - :options="fnDimensionsAndSource(item.interactOn)" 126 + :options="fnDimensionsAndSource(item.interactOn, item.interactComponentId!, requestParamsItem)"
127 clearable 127 clearable
  128 + multiple
  129 + @update:value="(value: string, options: Recordable[])=>handleSelectInteract(value,options,item.interactOn,requestParamsItem)"
128 ></n-select> 130 ></n-select>
129 </setting-item> 131 </setting-item>
130 <n-text 132 <n-text
@@ -149,13 +151,13 @@ import { RequestParamsTypeEnum, RequestDataTypeEnum } from '@/enums/httpEnum' @@ -149,13 +151,13 @@ import { RequestParamsTypeEnum, RequestDataTypeEnum } from '@/enums/httpEnum'
149 import { InteractEventOn, COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum' 151 import { InteractEventOn, COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
150 import { icon } from '@/plugins' 152 import { icon } from '@/plugins'
151 import noData from '@/assets/images/canvas/noData.png' 153 import noData from '@/assets/images/canvas/noData.png'
152 -import { goDialog } from '@/utils' 154 +import { JSONParse, goDialog } from '@/utils'
153 import { useTargetData } from '../../../hooks/useTargetData.hook' 155 import { useTargetData } from '../../../hooks/useTargetData.hook'
154 import {PageChartEditStoreType} from '@/store/modules/chartEditStore/chartEditStore.d' 156 import {PageChartEditStoreType} from '@/store/modules/chartEditStore/chartEditStore.d'
155 157
156 const { CloseIcon, AddIcon, HelpOutlineIcon } = icon.ionicons5 158 const { CloseIcon, AddIcon, HelpOutlineIcon } = icon.ionicons5
157 const { targetData, chartEditStore } = useTargetData() 159 const { targetData, chartEditStore } = useTargetData()
158 -const requestParamsTypeList = [RequestParamsTypeEnum.PARAMS, RequestParamsTypeEnum.HEADER] 160 +const requestParamsTypeList = [RequestParamsTypeEnum.PARAMS, RequestParamsTypeEnum.BODY, RequestParamsTypeEnum.HEADER]
159 161
160 162
161 // THINGS_KIT 修改多画布切换相关代码 用于切换画布 163 // THINGS_KIT 修改多画布切换相关代码 用于切换画布
@@ -186,19 +188,40 @@ const fnGetRequest = (id: string | undefined, key: RequestParamsTypeEnum) => { @@ -186,19 +188,40 @@ const fnGetRequest = (id: string | undefined, key: RequestParamsTypeEnum) => {
186 const globalConfigPindApr = chartEditStore.getRequestGlobalConfig.requestDataPond.find(item => { 188 const globalConfigPindApr = chartEditStore.getRequestGlobalConfig.requestDataPond.find(item => {
187 return item.dataPondId === id 189 return item.dataPondId === id
188 })?.dataPondRequestConfig.requestParams 190 })?.dataPondRequestConfig.requestParams
189 -  
190 if (globalConfigPindApr) return globalConfigPindApr[key] 191 if (globalConfigPindApr) return globalConfigPindApr[key]
191 return chartEditStore.getComponentList[chartEditStore.fetchTargetIndex(id)]?.request.requestParams[key] 192 return chartEditStore.getComponentList[chartEditStore.fetchTargetIndex(id)]?.request.requestParams[key]
192 } 193 }
193 194
  195 +const handleSelectInteract = (value: string, options: SelectOption[], interactOn: InteractEventOn | undefined, requestParamsItem: RequestParamsTypeEnum | null) => {
  196 + console.log(value)
  197 + console.log(options)
  198 + console.log(interactOn)
  199 + console.log(requestParamsItem)
  200 + console.log(targetData.value)
  201 +}
  202 +
194 // 查询结果 203 // 查询结果
195 -const fnDimensionsAndSource = (interactOn: InteractEventOn | undefined) => { 204 +const fnDimensionsAndSource = (interactOn: InteractEventOn | undefined, id?: string | null, key?: RequestParamsTypeEnum | null) => {
196 if (!interactOn || !targetData.value.interactActions) return [] 205 if (!interactOn || !targetData.value.interactActions) return []
197 const tableData = targetData.value.interactActions.find(item => { 206 const tableData = targetData.value.interactActions.find(item => {
198 return item.interactType === interactOn 207 return item.interactType === interactOn
199 }) 208 })
200 -  
201 - return tableData?.componentEmitEvents[option.value[COMPONENT_INTERACT_EVENT_KET]] || [] 209 + // 新增支持Body
  210 + let bodyJsonList: SelectOption[]= []
  211 + if (id) {
  212 + const { request } = chartEditStore.getComponentList[chartEditStore.fetchTargetIndex(id)]
  213 + const { requestParams } = request
  214 + const { Body } = requestParams
  215 + const { json } = Body
  216 + if (!json) return
  217 + const jsonDict = JSONParse(json)
  218 + if (key === RequestParamsTypeEnum.BODY) {
  219 + bodyJsonList = Object.keys(jsonDict)?.map(bodyItem=>({label: bodyItem, value: bodyItem}))
  220 + }
  221 + }
  222 + //
  223 + const paramsTableData: SelectOption[] = tableData?.componentEmitEvents[option.value[COMPONENT_INTERACT_EVENT_KET]] || []
  224 + return [...paramsTableData, ...bodyJsonList] as unknown as SelectOption[]
202 } 225 }
203 226
204 // 绑定组件列表 227 // 绑定组件列表
@@ -263,7 +286,6 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => { @@ -263,7 +286,6 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => {
263 } 286 }
264 }) 287 })
265 }) 288 })
266 -console.log(tarArr)  
267 return tarArr 289 return tarArr
268 } 290 }
269 291
@@ -16,7 +16,32 @@ @@ -16,7 +16,32 @@
16 <script setup lang="ts"> 16 <script setup lang="ts">
17 import { NameSetting, PositionSetting, SizeSetting, StylesSetting } from '@/components/Pages/ChartItemSetting' 17 import { NameSetting, PositionSetting, SizeSetting, StylesSetting } from '@/components/Pages/ChartItemSetting'
18 import { useTargetData } from '../hooks/useTargetData.hook' 18 import { useTargetData } from '../hooks/useTargetData.hook'
  19 +import { watch } from 'vue'
  20 +import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
  21 +
19 const { targetData, chartEditStore } = useTargetData() 22 const { targetData, chartEditStore } = useTargetData()
  23 +
  24 +watch(
  25 + () => targetData.value,
  26 + (newValue: CreateComponentType | CreateComponentGroupType) => {
  27 + if (!newValue) return
  28 + if (!('yAxis' in newValue.option)) return
  29 + try {
  30 + if (!newValue?.option?.yAxis?.showRange) {
  31 + Reflect.deleteProperty((targetData.value as unknown as Recordable).option.yAxis, 'min')
  32 + Reflect.deleteProperty((targetData.value as unknown as Recordable).option.yAxis, 'max')
  33 + } else {
  34 + Reflect.set((targetData.value as unknown as Recordable).option.yAxis, 'min', newValue?.option?.yAxis.minData)
  35 + Reflect.set((targetData.value as unknown as Recordable).option.yAxis, 'max', newValue?.option?.yAxis.maxData)
  36 + }
  37 + } catch (e) {
  38 + console.log('🚀 ~ e:', e)
  39 + }
  40 + },
  41 + {
  42 + deep: true
  43 + }
  44 +)
20 </script> 45 </script>
21 46
22 <style lang="scss" scoped> 47 <style lang="scss" scoped>
@@ -44,6 +44,7 @@ import { CreateComponentType, CreateComponentGroupType } from '@/packages/index. @@ -44,6 +44,7 @@ import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.
44 import { datasetType, saveHistoryInputValueListType, historyInputValue } from './index.d' 44 import { datasetType, saveHistoryInputValueListType, historyInputValue } from './index.d'
45 import { uniqBy } from 'lodash' 45 import { uniqBy } from 'lodash'
46 import { SelectOption } from 'naive-ui' 46 import { SelectOption } from 'naive-ui'
  47 +import { isArray } from '@/utils/external/is'
47 48
48 const { targetData } = useTargetData() 49 const { targetData } = useTargetData()
49 50
@@ -107,8 +108,8 @@ watch( @@ -107,8 +108,8 @@ watch(
107 (newValue: CreateComponentType | CreateComponentGroupType) => { 108 (newValue: CreateComponentType | CreateComponentGroupType) => {
108 try { 109 try {
109 const uniqHistoryInputValueList = uniqBy(saveHistoryInputValueList.value, 'id') 110 const uniqHistoryInputValueList = uniqBy(saveHistoryInputValueList.value, 'id')
110 - if (uniqHistoryInputValueList) {  
111 - newValue.saveHistoryInput = JSON.stringify(uniqHistoryInputValueList) 111 + if (isArray(uniqHistoryInputValueList)) {
  112 + targetData.value.saveHistoryInput = JSON.stringify(uniqHistoryInputValueList)
112 window.localStorage.setItem('CACHE_HISTORY_INPUT_VALUE', JSON.stringify(uniqHistoryInputValueList)) 113 window.localStorage.setItem('CACHE_HISTORY_INPUT_VALUE', JSON.stringify(uniqHistoryInputValueList))
113 } 114 }
114 newValue?.groupList?.forEach((item: CreateComponentType) => { 115 newValue?.groupList?.forEach((item: CreateComponentType) => {
@@ -37,11 +37,12 @@ @@ -37,11 +37,12 @@
37 </template> 37 </template>
38 38
39 <script setup lang="ts"> 39 <script setup lang="ts">
40 -import { PropType } from 'vue' 40 +import { PropType, onMounted } from 'vue'
41 import { CreateComponentGroupType } from '@/packages/index.d' 41 import { CreateComponentGroupType } from '@/packages/index.d'
42 import { animationsClass, getFilterStyle, getTransformStyle, getBlendModeStyle } from '@/utils' 42 import { animationsClass, getFilterStyle, getTransformStyle, getBlendModeStyle } from '@/utils'
43 import { getSizeStyle, getComponentAttrStyle, getStatusStyle, getPreviewConfigStyle } from '../../utils' 43 import { getSizeStyle, getComponentAttrStyle, getStatusStyle, getPreviewConfigStyle } from '../../utils'
44 -import { useLifeHandler } from '@/hooks' 44 +import { useChartDataFetch, useLifeHandler } from '@/hooks'
  45 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
45 46
46 const props = defineProps({ 47 const props = defineProps({
47 groupData: { 48 groupData: {
@@ -61,6 +62,10 @@ const props = defineProps({ @@ -61,6 +62,10 @@ const props = defineProps({
61 required: true 62 required: true
62 } 63 }
63 }) 64 })
  65 +
  66 +onMounted(()=>{
  67 + useChartDataFetch(props.groupData, useChartEditStore)
  68 +})
64 </script> 69 </script>
65 70
66 <style lang="scss" scoped> 71 <style lang="scss" scoped>
@@ -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> {
@@ -11,6 +11,10 @@ interface ImportMetaEnv { @@ -11,6 +11,10 @@ interface ImportMetaEnv {
11 VITE_GLOB_CONTENT_SECURITY_POLICY: boolean 11 VITE_GLOB_CONTENT_SECURITY_POLICY: boolean
12 12
13 VITE_GLOB_APP_SHORT_NAME: string 13 VITE_GLOB_APP_SHORT_NAME: string
  14 +
  15 + // 流媒体播放协议
  16 + VITE_GLOB_STREAM_MEDIA_CONTENT_SECURITY_PROTOCOL: boolean
  17 +
14 } 18 }
15 19
16 20