aldehyde 0.2.526 → 0.2.528

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/lib/controls/entity-select/entity-select.d.ts.map +1 -1
  2. package/lib/controls/entity-select/entity-select.js +3 -3
  3. package/lib/controls/entity-select/entity-select.js.map +1 -1
  4. package/lib/controls/entity-select/index.css +6 -0
  5. package/lib/icon/local-aliIcon/iconfont.js +1 -1
  6. package/lib/icon/local-aliIcon/iconfont.js.map +1 -1
  7. package/lib/lowcode-components/heatmap-chart/index.d.ts +42 -0
  8. package/lib/lowcode-components/heatmap-chart/index.d.ts.map +1 -0
  9. package/lib/lowcode-components/heatmap-chart/index.js +326 -0
  10. package/lib/lowcode-components/heatmap-chart/index.js.map +1 -0
  11. package/lib/lowcode-components/index.d.ts +2 -0
  12. package/lib/lowcode-components/index.d.ts.map +1 -1
  13. package/lib/lowcode-components/index.js +2 -1
  14. package/lib/lowcode-components/index.js.map +1 -1
  15. package/lib/lowcode-components/line-chart/index.d.ts.map +1 -1
  16. package/lib/lowcode-components/line-chart/index.js +11 -5
  17. package/lib/lowcode-components/line-chart/index.js.map +1 -1
  18. package/lib/lowcode-components/lowcode-view/component/assets.d.ts.map +1 -1
  19. package/lib/lowcode-components/lowcode-view/component/assets.js +8 -0
  20. package/lib/lowcode-components/lowcode-view/component/assets.js.map +1 -1
  21. package/lib/module/dtmpl-edit-card.d.ts.map +1 -1
  22. package/lib/module/dtmpl-edit-card.js +2 -6
  23. package/lib/module/dtmpl-edit-card.js.map +1 -1
  24. package/lib/module/dtmpl-edit-page.d.ts.map +1 -1
  25. package/lib/module/dtmpl-edit-page.js +2 -6
  26. package/lib/module/dtmpl-edit-page.js.map +1 -1
  27. package/lib/module/ttmpl-table.d.ts +3 -0
  28. package/lib/module/ttmpl-table.d.ts.map +1 -1
  29. package/lib/module/ttmpl-table.js +15 -8
  30. package/lib/module/ttmpl-table.js.map +1 -1
  31. package/lib/routable/ttmpl-table-route.d.ts.map +1 -1
  32. package/lib/routable/ttmpl-table-route.js +32 -7
  33. package/lib/routable/ttmpl-table-route.js.map +1 -1
  34. package/lib/table/act-table.d.ts +1 -0
  35. package/lib/table/act-table.d.ts.map +1 -1
  36. package/lib/table/act-table.js +2 -2
  37. package/lib/table/act-table.js.map +1 -1
  38. package/lib/table/column/column-builder.d.ts.map +1 -1
  39. package/lib/table/column/column-builder.js +20 -4
  40. package/lib/table/column/column-builder.js.map +1 -1
  41. package/lib/table/relation-table.js +1 -1
  42. package/lib/table/relation-table.js.map +1 -1
  43. package/lib/tmpl/hc-data-source.d.ts +1 -0
  44. package/lib/tmpl/hc-data-source.d.ts.map +1 -1
  45. package/lib/tmpl/hc-data-source.js +11 -0
  46. package/lib/tmpl/hc-data-source.js.map +1 -1
  47. package/lib/tmpl/hcservice-v3.d.ts +1 -0
  48. package/lib/tmpl/hcservice-v3.d.ts.map +1 -1
  49. package/lib/tmpl/hcservice-v3.js +12 -0
  50. package/lib/tmpl/hcservice-v3.js.map +1 -1
  51. package/lib/tmpl/interface.d.ts +7 -0
  52. package/lib/tmpl/interface.d.ts.map +1 -1
  53. package/lib/tmpl/interface.js.map +1 -1
  54. package/package.json +1 -1
  55. package/src/aldehyde/controls/entity-select/entity-select.tsx +4 -5
  56. package/src/aldehyde/controls/entity-select/index.css +6 -0
  57. package/src/aldehyde/icon/local-aliIcon/iconfont.js +1 -1
  58. package/src/aldehyde/lowcode-components/heatmap-chart/index.tsx +362 -0
  59. package/src/aldehyde/lowcode-components/index.ts +4 -2
  60. package/src/aldehyde/lowcode-components/line-chart/index.tsx +11 -5
  61. package/src/aldehyde/lowcode-components/lowcode-view/component/assets.ts +8 -0
  62. package/src/aldehyde/module/dtmpl-edit-card.tsx +2 -6
  63. package/src/aldehyde/module/dtmpl-edit-page.tsx +2 -6
  64. package/src/aldehyde/module/ttmpl-table.tsx +25 -7
  65. package/src/aldehyde/routable/ttmpl-table-route.tsx +37 -7
  66. package/src/aldehyde/table/act-table.tsx +4 -2
  67. package/src/aldehyde/table/column/column-builder.tsx +30 -5
  68. package/src/aldehyde/table/relation-table.tsx +1 -1
  69. package/src/aldehyde/tmpl/hc-data-source.tsx +11 -0
  70. package/src/aldehyde/tmpl/hcservice-v3.tsx +11 -0
  71. package/src/aldehyde/tmpl/interface.tsx +3 -1
@@ -0,0 +1,362 @@
1
+ import * as echarts from 'echarts';
2
+ import React, { useEffect, useRef, useState, ForwardedRef, forwardRef, useImperativeHandle } from 'react';
3
+ import _ from 'lodash';
4
+ import { Spin } from "antd";
5
+ import { useLocale } from "../../locale/useLocale";
6
+ import HydrocarbonService from "../../tmpl/hcservice-v3";
7
+ import { DataConfigProps } from "../data";
8
+
9
+ /**
10
+ * 热力图组件
11
+ * x轴:维度1(d1)
12
+ * y轴:维度2(d2)
13
+ * 数值:事实1(v1)
14
+ * 状态-颜色:事实2(v2)
15
+ */
16
+
17
+ const defData = [
18
+ ['01', 'A', 0],
19
+ ['02', 'A', 0],
20
+ ['03', 'A', 0],
21
+ ['04', 'A', 2.3],
22
+ ['05', 'A', 3.5],
23
+ ['06', 'A', 0],
24
+ ['01', 'B', 2.820],
25
+ ['02', 'B', 2.950],
26
+ ['03', 'B', 0],
27
+ ['04', 'B', 3.620],
28
+ ['05', 'B', 3.710],
29
+ ['06', 'B', 4.650],
30
+ ['01', 'C', 3.210],
31
+ ['02', 'C', 3.350],
32
+ ['03', 'C', 3.660],
33
+ ['04', 'C', 0],
34
+ ['05', 'C', 3.920],
35
+ ['06', 'C', 4.100],
36
+ ['01', 'D', 4.600],
37
+ ['02', 'D', 4.750],
38
+ ['03', 'D', 3.910],
39
+ ['04', 'D', 3.820],
40
+ ['05', 'D', 0],
41
+ ['06', 'D', 3.640]
42
+ ];
43
+
44
+ const defVisualMap: any = {// 默认分段视觉映射
45
+ show: false,
46
+ type: 'piecewise',
47
+ left: 'left',
48
+ bottom: '5%',
49
+ textStyle: { color: '#fff' },
50
+ pieces: [
51
+ { min: 0, max: 0, color: '#666e7f', label: '停工无生产' },
52
+ { min: 0.001, lt: 3.5, color: '#00c878', label: '优(<3.5)' },
53
+ { min: 3.5, lt: 4.5, color: '#ffd040', label: '良(3.5~4.5)' },
54
+ { min: 4.5, color: '#ff3b30', label: '差(≥4.5)' }
55
+ ]
56
+ };
57
+
58
+ const defOption = {
59
+ title: {
60
+ text: '暂无数据',
61
+ left: 'center',
62
+ top: 'middle',
63
+ show: false, // 无数据时显示
64
+ },
65
+ tooltip: { trigger: "axis", formatter: undefined },
66
+ grid: { top: 30, left: 30, right: 20, bottom: 30 },
67
+ visualMap: { // 分段视觉映射
68
+ show: false
69
+ },
70
+ xAxis: {
71
+ type: 'category',
72
+ data: ['01', '02', '03', '04', '05', '06'],
73
+ },
74
+ yAxis: {
75
+ type: 'category',
76
+ data: ['A', 'B', 'C', 'D'],
77
+ },
78
+ series: [
79
+ {
80
+ type: 'heatmap',
81
+ data: defData,
82
+ itemStyle: {
83
+ borderColor: '#aaaaaa',
84
+ borderWidth: 1
85
+ },
86
+ label: {
87
+ show: true,
88
+ color: '#fff',
89
+ fontSize: 9,
90
+ },
91
+ }
92
+ ]
93
+ };
94
+
95
+ // 处理关系字段显示
96
+ const handleRelationVal = (val: string) => {
97
+ if (!val) {
98
+ return val;
99
+ }
100
+ if (typeof val === "string" && val?.includes("@R@")) {
101
+ return val.split("@R@")[1];
102
+ } else {
103
+ return val;
104
+ }
105
+ }
106
+
107
+ // 处理数据格式
108
+ const handleData = (data: { config: { [key: string]: string }, value: { [key: string]: any }[] }[]) => {
109
+ if (!data?.length) {
110
+ return { xAxisData: [], yAxisData: [], data: [] };
111
+ }
112
+ const temData = data.map((r) => {
113
+ const { config, value } = r;
114
+ // 维度字段 (d1、d2等)
115
+ const dNames = Object.keys(config).filter((r) => r.startsWith("d") && !r.includes("-")).sort((a, b) => parseInt(a.substring(1)) - parseInt(b.substring(1)));
116
+ // 事实字段 (v1、v2等) v1数值,v2颜色
117
+ const vNames = Object.keys(config).filter((r) => r.startsWith("v") && !r.includes("-")).sort((a, b) => parseInt(a.substring(1)) - parseInt(b.substring(1)));
118
+ return value.map((r) => ({ value: [handleRelationVal(r["d1"]), handleRelationVal(r["d2"]), r["v1"]], itemStyle: { color: r["v2-color"] }, otherData: [...dNames.map(v => ({ name: config[v], value: handleRelationVal(r[v]), key: v })), ...vNames.map(v => ({ name: config[v], value: r[v], key: v, color: r[v + "-color"] }))] }));
119
+ });
120
+ let xAxisData = [], yAxisData = [];
121
+ temData[0].forEach((r) => {
122
+ if (!xAxisData.includes(r.value[0])) xAxisData.push(r.value[0]);
123
+ if (!yAxisData.includes(r.value[1])) yAxisData.push(r.value[1]);
124
+ });
125
+ return { xAxisData, yAxisData, data: temData[0] };
126
+ };
127
+
128
+ export interface ComponentStyle {
129
+ tooltip?: { show: boolean };
130
+ grid?: { top: number, left: number, right: number, bottom: number };
131
+ xAxis?: { [key: string]: any };
132
+ yAxis?: { [key: string]: any };
133
+ renderer?: "canvas" | "svg";
134
+ }
135
+
136
+ export interface ComponentProps {
137
+ style?: ComponentStyle;
138
+ base?: { width: number, height: number };
139
+ data?: DataConfigProps;
140
+ isDesignMode?: boolean; // 是否编辑模式
141
+ initSearchParams?: { [key: string]: any }; // 全局初始化外部参数,例:传参包含设备id,则在查询时带上设备id
142
+ }
143
+
144
+ export interface ComponentRef {
145
+ updateConfig: (newConfig: ComponentProps) => void;
146
+ destroy: () => void;
147
+ updateSearchParams: (params: { [key: string]: any }) => void;
148
+ }
149
+
150
+ const Index = forwardRef((props: ComponentProps, ref: ForwardedRef<ComponentRef>) => {
151
+ const { style, data: propsData, isDesignMode } = props;
152
+ const [config, setConfig] = useState<ComponentStyle>(style || {});
153
+ const [renderType, setRenderType] = useState<"canvas" | "svg">(style?.renderer || "svg"); // 渲染模式
154
+ const [size, setSize] = useState<{ width: number, height: number }>();
155
+ const [dataConfig, setDataConfig] = useState<DataConfigProps>({ ...propsData }); // 数据源配置
156
+ const [data, setData] = useState<{ [key: string]: any }[]>([]);
157
+ const [xAxisData, setXAxisData] = useState<string[]>([]);
158
+ const [yAxisData, setYAxisData] = useState<string[]>([]);
159
+ const [searchParams, setSearchParams] = useState<{ [key: string]: any }>();
160
+ const [initSearchParams, setInitSearchParams] = useState<{ [key: string]: any }>();
161
+ const [loading, setLoading] = useState<boolean>(false);
162
+ const chartRef = useRef<HTMLDivElement>(null);
163
+ const chart = useRef<any>(null);
164
+ const pollingIntervalRef = useRef<number | NodeJS.Timeout>(null);
165
+ const resizeObserverRef = useRef<any>(null);
166
+ const { translate } = useLocale();
167
+
168
+ const handleDestroy = () => {
169
+ pollingIntervalRef.current && clearInterval(pollingIntervalRef.current);
170
+ resizeObserverRef.current && resizeObserverRef.current.disconnect();
171
+ chart.current && chart.current.dispose();
172
+ };
173
+
174
+ // 全局初始化请求数据处理
175
+ const handleInitData = (val: DataConfigProps) => {
176
+ if (val.sourceType === "sourceId" && val.isInit && val.initData) {
177
+ const { config: dataConfig, value } = val.initData;
178
+ const temData = handleData(value);
179
+ setData(temData.data || []);
180
+ setXAxisData(temData.xAxisData || []);
181
+ setYAxisData(temData.yAxisData || []);
182
+ if (dataConfig?.requestMode === "polling") {
183
+ pollingIntervalRef.current = setInterval(() => { getData() }, dataConfig?.pollingInterval || 60000);
184
+ }
185
+ }
186
+ }
187
+
188
+ // ws订阅数据更新
189
+ const handleWSData = (val: DataConfigProps) => {
190
+ if (val.sourceType === "sourceId" && val.wsData) {
191
+ const { value } = val.initData;
192
+ const temData = handleData(value);
193
+ setData(temData.data || []);
194
+ setXAxisData(temData.xAxisData || []);
195
+ setYAxisData(temData.yAxisData || []);
196
+ }
197
+ }
198
+
199
+ useImperativeHandle(ref, () => ({
200
+ updateConfig: (newConfig) => {
201
+ const { base, style: newStyle, data: newDataConfig, initSearchParams: newISParams } = newConfig;
202
+ setConfig({ ...(newStyle || {}) });
203
+ setSize({ width: base.width, height: base.height });
204
+ setDataConfig(newDataConfig);
205
+ setRenderType(newStyle?.renderer || "svg");
206
+ handleInitData(newDataConfig);
207
+ setSearchParams(newDataConfig.searchParams);
208
+ setInitSearchParams(newISParams);
209
+ handleWSData(newDataConfig);
210
+ },
211
+ updateSearchParams: (params) => {
212
+ setInitSearchParams(params);
213
+ },
214
+ destroy: handleDestroy,
215
+ }));
216
+
217
+ // 窗口大小变化时重新调整图表大小
218
+ const handleResize = () => {
219
+ const container = chartRef.current;
220
+ if (!container || container.offsetWidth === 0 || container.offsetHeight === 0) return;
221
+ if (chart.current) {
222
+ requestAnimationFrame(() => {
223
+ chart.current.resize({ animation: { duration: 500 } });
224
+ });
225
+ }
226
+ };
227
+
228
+ useEffect(() => {
229
+ return () => {
230
+ handleDestroy();
231
+ }
232
+ }, []);
233
+
234
+ useEffect(() => {
235
+ handleDestroy();
236
+ chart.current = echarts.init(chartRef.current, null, { renderer: renderType, useDirtyRect: true });
237
+ // 监听容器尺寸变化:页面从隐藏(如切到其他 tab)变为可见时,图表自动重新适应
238
+ resizeObserverRef.current = new ResizeObserver(() => handleResize());
239
+ resizeObserverRef.current.observe(chartRef.current);
240
+ }, [renderType]);
241
+
242
+ // 请求数据
243
+ const getData = async (params?: object) => {
244
+ setLoading(true);
245
+ const { data } = await HydrocarbonService.requestChartData(null, dataConfig?.sourceId, params) || {};
246
+ setLoading(false);
247
+ const temData = handleData(data?.value);
248
+ setData(temData.data || []);
249
+ setXAxisData(temData.xAxisData || []);
250
+ setYAxisData(temData.yAxisData || []);
251
+ return data?.config;
252
+ };
253
+
254
+ // 初始化请求数据
255
+ const getInitData = async (params?: object) => {
256
+ pollingIntervalRef.current && clearInterval(pollingIntervalRef.current);
257
+ const config = await getData(params);
258
+ if (config?.requestMode === "polling") {
259
+ pollingIntervalRef.current = setInterval(() => getData(params), config?.pollingInterval || 60000);
260
+ }
261
+ };
262
+
263
+ // 静态数据处理
264
+ useEffect(() => {
265
+ if (dataConfig?.sourceType === 'staticData') {
266
+ const temData = handleData(dataConfig.staticData);
267
+ setData(temData.data || []);
268
+ setXAxisData(temData.xAxisData || []);
269
+ setYAxisData(temData.yAxisData || []);
270
+ }
271
+ }, [dataConfig?.sourceType, dataConfig?.staticData]);
272
+
273
+ /**
274
+ * 数据源数据请求
275
+ * 1、编辑态不请求数据
276
+ */
277
+ useEffect(() => {
278
+ if (!isDesignMode && dataConfig?.sourceType === 'sourceId' && dataConfig?.sourceId && !dataConfig?.isInit && dataConfig?.isDefRequest !== false) {
279
+ if (dataConfig?.isInitParams) { // 组件数据源接收外部参数
280
+ initSearchParams && getInitData(initSearchParams);
281
+ } else {
282
+ getInitData();
283
+ }
284
+ } else if (dataConfig?.sourceType === 'sourceId') {
285
+ setData([]);
286
+ }
287
+ }, [dataConfig?.sourceType, dataConfig?.sourceId, initSearchParams]);
288
+
289
+ // 搜索参数变化时重新请求数据
290
+ useEffect(() => {
291
+ if (searchParams) {
292
+ const params = { ...(initSearchParams || {}), ...searchParams };
293
+ if (dataConfig?.isInitParams) { // 数据源接收外部参数,则参数存在再请求
294
+ initSearchParams && getInitData(params);
295
+ } else {
296
+ getInitData(params);
297
+ }
298
+ }
299
+ }, [searchParams, initSearchParams]);
300
+
301
+ const renderChart = (tData) => {
302
+ const { grid, tooltip, xAxis, yAxis } = config;
303
+ const option = _.cloneDeep(defOption);
304
+ const isDefaultData = isDesignMode && !tData?.length;
305
+ // 编辑态无数据显示默认数据
306
+ const temData = isDefaultData ? defData : tData;
307
+ option.grid = grid;
308
+ option.tooltip = {
309
+ trigger: "axis",
310
+ ...tooltip,
311
+ formatter: (params) => {
312
+ const temData = params[0]?.data?.otherData || [];
313
+ if (!temData?.length) {
314
+ return undefined;
315
+ }
316
+ return temData.map(item => `<div style="margin-bottom: 6px;"><span style="font-weight: bold;font-size: 15px;">${item.name}</span>:<span style=${item.color ? `color:${item.color}` : ""}>${item.value}</span></div>`).join('');
317
+ }
318
+ };
319
+ option.xAxis = { ...option.xAxis, ...xAxis, data: isDefaultData ? option.xAxis.data : xAxisData || [] };
320
+ option.yAxis = { ...option.yAxis, ...yAxis, data: isDefaultData ? option.yAxis.data : yAxisData || [] };
321
+ option.title.text = translate("${暂无数据}");
322
+ option.title.show = !temData?.length;
323
+ option.visualMap = isDefaultData ? defVisualMap : { show: false };
324
+ option.series = [{
325
+ type: "heatmap",
326
+ data: temData,
327
+ itemStyle: {
328
+ borderColor: "#000",
329
+ borderWidth: 1,
330
+ },
331
+ label: {
332
+ show: true,
333
+ color: "#fff",
334
+ fontSize: 12,
335
+ },
336
+ }];
337
+ chart.current.setOption(option, true);
338
+ };
339
+
340
+ useEffect(() => {
341
+ if (config) {
342
+ renderChart(data);
343
+ }
344
+ }, [config, data]);
345
+
346
+ useEffect(() => {
347
+ if (size) {
348
+ handleResize();
349
+ }
350
+ }, [size]);
351
+
352
+ const renderChartDom = () => <div ref={chartRef} style={{ width: '100%', height: '100%' }} />;
353
+
354
+ if (isDesignMode) {
355
+ return renderChartDom();
356
+ }
357
+
358
+ return <Spin spinning={loading}>{renderChartDom()}</Spin>;
359
+ });
360
+
361
+ export default Index;
362
+
@@ -54,6 +54,7 @@ import Carousel from "./carousel";
54
54
  import SearchForm from "./search-form";
55
55
  import BaseRadio from "./base-radio";
56
56
  import RadarChart from "./radar-chart";
57
+ import HeatmapChart from "./heatmap-chart";
57
58
 
58
59
 
59
60
  type CompoundedComponent = {
@@ -112,7 +113,8 @@ type CompoundedComponent = {
112
113
  Carousel?: typeof Carousel,
113
114
  SearchForm?: typeof SearchForm,
114
115
  BaseRadio?: typeof BaseRadio,
115
- RadarChart?: typeof RadarChart
116
+ RadarChart?: typeof RadarChart,
117
+ HeatmapChart?: typeof HeatmapChart,
116
118
  };
117
119
 
118
120
  const LowcodeComponents: CompoundedComponent = {
@@ -125,7 +127,7 @@ const LowcodeComponents: CompoundedComponent = {
125
127
  Decoration6, Decoration7, Decoration8, Decoration9, Decoration10, Decoration11,
126
128
  BaseTable, TextScroller, CapsuleBarChart, CircularProgressChart, ActTable, ProgressChart,
127
129
  LineBarChart, Column3dChart, StrokeAnimation, EffectScatterMap3D, BaseButton, BaseTabs,
128
- PlaceholderComponent, Carousel, SearchForm, BaseRadio, RadarChart
130
+ PlaceholderComponent, Carousel, SearchForm, BaseRadio, RadarChart, HeatmapChart
129
131
  };
130
132
 
131
133
  export default LowcodeComponents;
@@ -21,12 +21,14 @@ const defOption = {
21
21
  boundaryGap: true,
22
22
  axisTick: { show: true },
23
23
  axisLabel: {},
24
- min: undefined
24
+ min: undefined,
25
+ max: undefined
25
26
  },
26
27
  yAxis: {
27
28
  type: 'value',
28
29
  axisLabel: {},
29
- min: undefined
30
+ min: undefined,
31
+ max: undefined
30
32
  },
31
33
  legend: { show: false },
32
34
  dataZoom: [],
@@ -325,24 +327,28 @@ const Index = forwardRef((props: ComponentProps, ref: ForwardedRef<ComponentRef>
325
327
  const option = _.cloneDeep(defOption);
326
328
  const yAxisLabel = yAxis?.axisLabel;
327
329
  const xAxisLabel = xAxis?.axisLabel;
328
- let xAxisMin, yAxisMin;
330
+ let xAxisMin, yAxisMin, xAxisMax, yAxisMax;
329
331
  // 编辑态无数据显示默认数据
330
332
  const temData = isDesignMode && !tData?.length ? option.series : tData;
331
333
  if (temData?.length && xAxis?.type === "time" && xAxis?.timeCompleteZero) { // 时间轴配置-时间轴0点补全
332
334
  const dataTime = temData.map(r => r.data || []).flat().map(item => new Date(item[0]).getTime());
333
335
  const minTime = Math.min(...dataTime);
336
+ const maxTime = Math.max(...dataTime);
334
337
  xAxisMin = dayjs(minTime).startOf("day").valueOf() + 1; // 时间轴0点补全,+1毫秒,避免显示日期
338
+ xAxisMax = dayjs(maxTime).endOf("day").valueOf();
335
339
  }
336
340
  if (temData?.length && yAxis?.type === "time" && yAxis?.timeCompleteZero) {
337
341
  const dataTime = temData.map(r => r.data || []).flat().map(item => new Date(item[1]).getTime());
338
342
  const minTime = Math.min(...dataTime);
343
+ const maxTime = Math.max(...dataTime);
339
344
  yAxisMin = dayjs(minTime).startOf("day").valueOf() + 1;
345
+ yAxisMax = dayjs(maxTime).endOf("day").valueOf();
340
346
  }
341
347
  option.grid = grid;
342
348
  option.legend = { ...legend, ...legends[legend?.position], data: temData?.filter((item: any) => !item.isMarkLine && item.name).map((r: any) => r.name) };
343
349
  option.tooltip = { trigger: "axis", ...tooltip };
344
- option.xAxis = { ...option.xAxis, ...xAxis, min: xAxisMin, axisTick: { show: xAxis?.axisLine?.show }, axisLabel: xAxisLabel.numFormat && xAxis.type === "value" ? { ...xAxisLabel, formatter: formatNumberUnit } : { ...xAxisLabel, showMinLabel: xAxisMin ? false : null } };
345
- option.yAxis = { ...option.yAxis, ...yAxis, min: yAxisMin, axisLabel: yAxisLabel.numFormat && yAxis.type === "value" ? { ...yAxisLabel, formatter: formatNumberUnit } : { ...yAxisLabel, showMinLabel: yAxisMin ? false : null } };
350
+ option.xAxis = { ...option.xAxis, ...xAxis, min: xAxisMin, max: xAxisMax, axisTick: { show: xAxis?.axisLine?.show }, axisLabel: xAxisLabel.numFormat && xAxis.type === "value" ? { ...xAxisLabel, formatter: formatNumberUnit } : { ...xAxisLabel, showMinLabel: xAxisMin ? false : null } };
351
+ option.yAxis = { ...option.yAxis, ...yAxis, min: yAxisMin, max: yAxisMax, axisLabel: yAxisLabel.numFormat && yAxis.type === "value" ? { ...yAxisLabel, formatter: formatNumberUnit } : { ...yAxisLabel, showMinLabel: yAxisMin ? false : null } };
346
352
  option.dataZoom = dataZoom ? [slider ? { type: "slider" } : undefined, { type: "inside", disabled: false }].filter(Boolean) : [];
347
353
  option.title.text = translate("${暂无数据}");
348
354
  option.title.show = !temData?.length;
@@ -55,6 +55,7 @@ import Carousel from "../../carousel";
55
55
  import SearchForm from "../../search-form";
56
56
  import BaseRadio from "../../base-radio";
57
57
  import RadarChart from "../../radar-chart";
58
+ import HeatmapChart from "../../heatmap-chart";
58
59
 
59
60
  interface ComponentItemConfig {
60
61
  baseInfo: BaseInfoType, // 基础信息
@@ -475,5 +476,12 @@ export const compsConfig: { [key: string]: ComponentItemConfig } = {
475
476
  compName: "雷达图",
476
477
  compKey: "RadarChart"
477
478
  }
479
+ },
480
+ HeatmapChart: {
481
+ componentNode: HeatmapChart,
482
+ baseInfo: {
483
+ compName: "热力图",
484
+ compKey: "HeatmapChart"
485
+ }
478
486
  }
479
487
  };
@@ -79,7 +79,6 @@ export default class DtmplEditCard extends React.PureComponent<
79
79
  if (prevProps.sourceId != this.props.sourceId || dtmplConfig == null || (!this.props.code && prevProps.code)) {
80
80
  await this.loadConfigData();
81
81
  } else if (prevProps.sourceId != this.props.sourceId || queryingCode != code || !dtmplData) {
82
- await this.handleBuildInFuncFields(dtmplConfig);
83
82
  //防止反复请求 code
84
83
  if (code) {
85
84
  await this.loadCodeData(dtmplConfig, code);
@@ -115,7 +114,6 @@ export default class DtmplEditCard extends React.PureComponent<
115
114
  addTmplId
116
115
  );
117
116
  }
118
- await this.handleBuildInFuncFields(dtmplConfig);
119
117
  this.handleRelValueField(dtmplConfig);
120
118
  if (dtmplConfig.entity) {
121
119
  let dtmplData = dtmplConfig.entity;
@@ -125,12 +123,10 @@ export default class DtmplEditCard extends React.PureComponent<
125
123
  } else {
126
124
  this.setState({ queryingCode: code, dtmplData, dtmplConfig, loading: false });
127
125
  }
126
+ setTimeout(() => this.handleBuildInFuncFields(dtmplConfig), 300);
128
127
  } else {
129
128
  await this.loadData(dtmplConfig);
130
- this.setState({
131
- dtmplConfig,
132
- loading: false,
133
- });
129
+ this.setState({ dtmplConfig, loading: false });
134
130
  }
135
131
  };
136
132
 
@@ -121,7 +121,6 @@ export default class DtmplEditPage extends React.PureComponent<
121
121
  ) {
122
122
  await this.loadConfigData();
123
123
  } else {
124
- await this.handleBuildInFuncFields(dtmplConfig);
125
124
  await this.loadData(dtmplConfig);
126
125
  }
127
126
  }
@@ -153,7 +152,6 @@ export default class DtmplEditPage extends React.PureComponent<
153
152
  );
154
153
  }
155
154
  this.handleRelValueField(dtmplConfig);
156
- await this.handleBuildInFuncFields(dtmplConfig);
157
155
  // 直接复制
158
156
  if (dtmplConfig?.entity && dtmplConfig?.entity?.code == code) {
159
157
  let dtmplData = dtmplConfig.entity;
@@ -163,13 +161,11 @@ export default class DtmplEditPage extends React.PureComponent<
163
161
  } else {
164
162
  this.setState({ dtmplData, id: code, loading: false });
165
163
  }
164
+ setTimeout(() => this.handleBuildInFuncFields(), 300);
166
165
  } else {
167
166
  await this.loadData(dtmplConfig);
168
167
  }
169
- this.setState({
170
- dtmplConfig,
171
- loading: false,
172
- });
168
+ this.setState({ dtmplConfig, loading: false });
173
169
  };
174
170
 
175
171
  // 表单关联项secondCriterion处理start
@@ -48,6 +48,9 @@ export interface TtmplTableProps {
48
48
  bordered?: boolean; // 表格是否显示边框
49
49
  showHeader?: boolean; // 表格是否显示表头
50
50
  ettmplConfig?: EttmplConfig; // 展开树配置
51
+ ettmplRootSourceId?: string; // 展开树配置根 sourceId
52
+ isRecursion?: boolean; // 是否递归
53
+ recursionSourceId?: string; // 递归 sourceId
51
54
  }
52
55
 
53
56
  const TtmplTable = (props: TtmplTableProps) => {
@@ -80,7 +83,8 @@ const TtmplTable = (props: TtmplTableProps) => {
80
83
  hideOnSinglePage,
81
84
  bordered,
82
85
  showHeader,
83
- ettmplConfig: pEttmplConfig
86
+ ettmplConfig: pEttmplConfig,
87
+ ettmplRootSourceId, isRecursion = false, recursionSourceId
84
88
  } = props;
85
89
  const { translate } = useContext(LocaleContext);
86
90
  const [ltmplConfigRes, setLtmplConfigRes] = useState<LtmplConfigRes>();
@@ -99,6 +103,7 @@ const TtmplTable = (props: TtmplTableProps) => {
99
103
  const [drawerSize, setDrawerSize] = useState<number | string>("92vw"); // 抽屉组件
100
104
  const [isCopy, setIsCopy] = useState<boolean>(false); // 是否复制
101
105
  const [ettmplConfig, setEttmplConfig] = useState<EttmplConfig>(pEttmplConfig); // 展开树配置
106
+ const [treeAddData, setTreeAddData] = useState<{ [key: string]: any }>(); // 展开树添加递归及关联关系配置
102
107
  const { token } = useToken();
103
108
 
104
109
  const toCriteriaData = (values: object) => {
@@ -113,11 +118,11 @@ const TtmplTable = (props: TtmplTableProps) => {
113
118
  };
114
119
 
115
120
  const loadLtmplConfig = async () => {
116
- const res: LtmplConfigRes = await HCDataSource.requestLtmplConfig(serverKey, sourceId);
117
121
  if (!pEttmplConfig) {
118
122
  const ettmplConfig_: EttmplConfig = await HCDataSource.requestEttmplConfig(serverKey, sourceId);
119
123
  setEttmplConfig(ettmplConfig_);
120
124
  }
125
+ const res: LtmplConfigRes = await HCDataSource.requestEttmplLtmplConfig(serverKey, ettmplRootSourceId, isRecursion ? recursionSourceId : sourceId);
121
126
  let criteriaData_: object;
122
127
  let defCriteriaValue = {};
123
128
  //提取 过滤条件的默认值
@@ -191,6 +196,14 @@ const TtmplTable = (props: TtmplTableProps) => {
191
196
  }
192
197
  };
193
198
 
199
+
200
+ // 展开树行操作添加按钮
201
+ const doAddRaction = (ractionId: string, mainCode: string) => {
202
+ setSelectedCode(null);
203
+ setShowDtmplEdit(true);
204
+ setTreeAddData({ ractionId, mainCode });
205
+ }
206
+
194
207
  const doSearch = (params_?: object) => {
195
208
  let params = { ...(criteriaData || {}), ...params_ };
196
209
  //追加过滤条件,hiddenColIds,innerQueryKey
@@ -222,11 +235,14 @@ const TtmplTable = (props: TtmplTableProps) => {
222
235
 
223
236
  // 嵌套表格配置
224
237
  const expandedRowRender = (val: { [key: string]: any }) => {
225
- const { subNodes, recursiveRatmplId } = ettmplConfig;
238
+ const { subNodes, recursiveRatmplId, sourceId: ettmplSourceId } = ettmplConfig;
226
239
  return <div style={{ marginLeft: "24px", background: token.colorBgContainer }}>
227
240
  {recursiveRatmplId ?
228
241
  <TtmplTable
242
+ isRecursion={true}
243
+ recursionSourceId={ettmplSourceId}
229
244
  ettmplConfig={ettmplConfig}
245
+ ettmplRootSourceId={ettmplRootSourceId}
230
246
  hideOnSinglePage={true}
231
247
  funcMode="simple"
232
248
  serverKey={serverKey}
@@ -237,6 +253,7 @@ const TtmplTable = (props: TtmplTableProps) => {
237
253
  {subNodes.length > 1 ? <h4 style={{ padding: "12px 0 0 12px" }}>{item.title}</h4> : ""}
238
254
  <TtmplTable
239
255
  ettmplConfig={item}
256
+ ettmplRootSourceId={ettmplRootSourceId}
240
257
  hideOnSinglePage={true}
241
258
  funcMode="simple"
242
259
  serverKey={serverKey}
@@ -283,6 +300,7 @@ const TtmplTable = (props: TtmplTableProps) => {
283
300
  showHeader={showHeader}
284
301
  expandable={(subNodes?.length || recursiveRatmplId) ? { expandedRowRender } : undefined} // 嵌套表格
285
302
  showEmpty={false}
303
+ doAddRaction={doAddRaction}
286
304
  />
287
305
  {buttons.includes("detail") && showDtmplView ? (
288
306
  <ModalDtmplView
@@ -301,8 +319,8 @@ const TtmplTable = (props: TtmplTableProps) => {
301
319
  serverKey={serverKey}
302
320
  open={showDtmplEdit}
303
321
  onCancel={() => setShowDtmplEdit(false)}
304
- sourceId={dtmplSourceId ? dtmplSourceId : sourceId}
305
- mainCode={mainCode}
322
+ sourceId={treeAddData?.ractionId || (dtmplSourceId ? dtmplSourceId : sourceId)}
323
+ mainCode={treeAddData?.mainCode || mainCode}
306
324
  code={selectedCode}
307
325
  onOk={handleDtmplEdit}
308
326
  isCopy={isCopy}
@@ -317,8 +335,8 @@ const TtmplTable = (props: TtmplTableProps) => {
317
335
  setShowDtmplCustomEdit(false);
318
336
  }}
319
337
  customPath={customEditPagePath}
320
- sourceId={sourceId}
321
- mainCode={mainCode}
338
+ sourceId={treeAddData?.ractionId || sourceId}
339
+ mainCode={treeAddData?.mainCode || mainCode}
322
340
  code={selectedCode}
323
341
  isCopy={isCopy}
324
342
  />