@fe-free/core 2.1.3 → 2.1.5

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @fe-free/core
2
2
 
3
+ ## 2.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: json modal
8
+ - @fe-free/tool@2.1.5
9
+
10
+ ## 2.1.4
11
+
12
+ ### Patch Changes
13
+
14
+ - feat: chat
15
+ - @fe-free/tool@2.1.4
16
+
3
17
  ## 2.1.3
4
18
 
5
19
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/core",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "",
5
5
  "main": "./src/index.ts",
6
6
  "author": "",
@@ -39,7 +39,7 @@
39
39
  "remark-gfm": "^4.0.1",
40
40
  "vanilla-jsoneditor": "^0.23.1",
41
41
  "zustand": "^4.5.4",
42
- "@fe-free/tool": "2.1.3"
42
+ "@fe-free/tool": "2.1.5"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@ant-design/pro-components": "^2.8.7",
@@ -7,8 +7,8 @@ interface ChartData {
7
7
  rows: (string | number)[][];
8
8
  }
9
9
 
10
- interface ChartConfig {
11
- chart_type: 'line' | 'bar' | 'pie' | 'table' | 'scatter';
10
+ interface ChartConfigBase {
11
+ chart_type: 'bar' | 'pie' | 'table' | 'scatter';
12
12
  x_field?: string;
13
13
  y_field?: string;
14
14
  angle_field?: string;
@@ -16,6 +16,18 @@ interface ChartConfig {
16
16
  title: string;
17
17
  }
18
18
 
19
+ interface LineChartConfig {
20
+ chart_type: 'line';
21
+ x_field?: string;
22
+ y_field: string | string[];
23
+ angle_field?: string;
24
+ color_field?: string;
25
+ title: string;
26
+ }
27
+
28
+ // @ts-ignore
29
+ interface ChartConfig extends ChartConfigBase, ChartConfigLine {}
30
+
19
31
  // 错误处理组件
20
32
  function ChartError(props: { children?: React.ReactNode }) {
21
33
  const { children } = props;
@@ -29,7 +41,8 @@ function ChartError(props: { children?: React.ReactNode }) {
29
41
  class ErrorBoundary extends React.Component {
30
42
  state = { hasError: false };
31
43
 
32
- static getDerivedStateFromError() {
44
+ static getDerivedStateFromError(error) {
45
+ console.error('ErrorBoundary:', error);
33
46
  return { hasError: true };
34
47
  }
35
48
 
@@ -102,7 +115,7 @@ function PieChart(props: { data: ChartData; chart: ChartConfig }) {
102
115
  }
103
116
 
104
117
  // 折线图组件
105
- function LineChart(props: { data: ChartData; chart: ChartConfig }) {
118
+ function LineChart(props: { data: ChartData; chart: LineChartConfig }) {
106
119
  const { data, chart } = props;
107
120
  const { columns, rows } = data;
108
121
  const { x_field, y_field } = chart;
@@ -112,25 +125,64 @@ function LineChart(props: { data: ChartData; chart: ChartConfig }) {
112
125
  }
113
126
 
114
127
  const xIndex = columns.indexOf(x_field);
115
- const yIndex = columns.indexOf(y_field);
116
-
117
- if (xIndex === -1 || yIndex === -1) {
128
+ if (xIndex === -1) {
118
129
  return <ChartError />;
119
130
  }
120
131
 
121
- // 转换数据格式为 Ant Design Charts 需要的格式
122
- const chartData = rows.map((row) => ({
123
- [x_field]: row[xIndex],
124
- [y_field]: Number(row[yIndex]),
125
- }));
132
+ // 处理 y_field 为数组的情况
133
+ if (Array.isArray(y_field)) {
134
+ // 验证所有 y_field 是否存在于 columns 中
135
+ const yIndices = y_field.map((field) => columns.indexOf(field));
136
+ if (yIndices.some((index) => index === -1)) {
137
+ return <ChartError />;
138
+ }
126
139
 
127
- const config = {
128
- data: chartData,
129
- xField: x_field,
130
- yField: y_field,
131
- };
140
+ // 转换数据格式为 Ant Design Charts 需要的格式(长数据格式)
141
+ const chartData: any[] = [];
142
+ rows.forEach((row) => {
143
+ y_field.forEach((field, index) => {
144
+ const value = row[yIndices[index]];
145
+ if (value !== null && value !== undefined) {
146
+ chartData.push({
147
+ [x_field]: row[xIndex],
148
+ type: field,
149
+ value: Number(value),
150
+ });
151
+ }
152
+ });
153
+ });
154
+
155
+ const config = {
156
+ data: chartData,
157
+ xField: x_field,
158
+ yField: 'value',
159
+ seriesField: 'type',
160
+ };
161
+
162
+ console.log('config', config);
163
+
164
+ return <Line {...config} />;
165
+ } else {
166
+ // 处理单个 y_field 的情况(保持向后兼容)
167
+ const yIndex = columns.indexOf(y_field);
168
+ if (yIndex === -1) {
169
+ return <ChartError />;
170
+ }
132
171
 
133
- return <Line {...config} />;
172
+ // 转换数据格式为 Ant Design Charts 需要的格式
173
+ const chartData = rows.map((row) => ({
174
+ [x_field]: row[xIndex],
175
+ [y_field]: Number(row[yIndex]),
176
+ }));
177
+
178
+ const config = {
179
+ data: chartData,
180
+ xField: x_field,
181
+ yField: y_field,
182
+ };
183
+
184
+ return <Line {...config} />;
185
+ }
134
186
  }
135
187
 
136
188
  // 柱状图组件
@@ -253,7 +305,8 @@ function ChartBlock(props: any) {
253
305
 
254
306
  // 大模型会返回一些奇怪字符,需要去掉
255
307
  // 不间断空格
256
- const content = children.replace(/ /g, '');
308
+ // eslint-disable-next-line no-irregular-whitespace
309
+ const content = children?.replace(/ /g, '');
257
310
 
258
311
  return (
259
312
  <ErrorBoundary>
@@ -166,6 +166,30 @@ export const Chart: Story = {
166
166
  }
167
167
  \`\`\`
168
168
 
169
+ 多条折线
170
+
171
+ \`\`\`chart
172
+ {
173
+ "data": {
174
+ "columns": ["quarter", "L'Oreal", "P&G", "Proya"],
175
+ "rows": [
176
+ ["FY23-Q4/23-Q2", 8, 7, null],
177
+ ["FY24-Q1/23-Q3", 7, 6, null],
178
+ ["FY24-Q2/23-Q4", 4, 3, null],
179
+ ["FY24-Q3/24-Q1", 3, null, null],
180
+ ["FY24-Q4/24-Q2", null, null, null],
181
+ ["FY25-Q1/24-Q34",null,null,null]
182
+ ]
183
+ },
184
+ "chart": {
185
+ "chart_type": "line",
186
+ "x_field": "quarter",
187
+ "y_field": ["L'Oreal", "P&G","Proya"],
188
+ "title": "欧莱雅、宝洁及珀莱雅增长率变化趋势"
189
+ }
190
+ }
191
+ \`\`\`
192
+
169
193
  ## 柱状图示例
170
194
 
171
195
  \`\`\`chart
@@ -189,6 +213,7 @@ export const Chart: Story = {
189
213
  }
190
214
  \`\`\`
191
215
 
216
+
192
217
  ## 饼图示例
193
218
 
194
219
  \`\`\`chart
@@ -52,8 +52,6 @@ function Table<
52
52
  };
53
53
  }
54
54
 
55
- console.log('newSearch', newSearch);
56
-
57
55
  return (
58
56
  <ProTable<DataSource, Params>
59
57
  cardBordered
@@ -1,6 +1,7 @@
1
1
  import type { ProRenderFieldPropsType } from '@ant-design/pro-components';
2
2
  import { dateRender } from './date';
3
3
  import { jsonRender } from './json';
4
+ import { jsonModalRender } from './json_modal';
4
5
 
5
6
  enum CustomValueTypeEnum {
6
7
  /** 渲染时间 + 搜索日期范围 */
@@ -9,6 +10,8 @@ enum CustomValueTypeEnum {
9
10
  CustomDateAndDateRange = 'CustomDateAndDateRange',
10
11
  /** JSON */
11
12
  CustomJSON = 'CustomJSON',
13
+ /** JSON Modal */
14
+ CustomJSONModal = 'CustomJSONModal',
12
15
  }
13
16
 
14
17
  const customValueTypeMap: Record<string, ProRenderFieldPropsType> = {
@@ -24,6 +27,10 @@ const customValueTypeMap: Record<string, ProRenderFieldPropsType> = {
24
27
  render: jsonRender.render,
25
28
  renderFormItem: jsonRender.renderFormItem,
26
29
  },
30
+ [CustomValueTypeEnum.CustomJSONModal]: {
31
+ render: jsonModalRender.render,
32
+ renderFormItem: jsonModalRender.renderFormItem,
33
+ },
27
34
  };
28
35
 
29
- export { customValueTypeMap, CustomValueTypeEnum };
36
+ export { CustomValueTypeEnum, customValueTypeMap };
@@ -0,0 +1,56 @@
1
+ import type { ProFormItemProps } from '@ant-design/pro-components';
2
+ import { Modal } from 'antd';
3
+ import { useState } from 'react';
4
+ import type { EditorJSONProps } from '../editor_json';
5
+ import { EditorJSON } from '../editor_json';
6
+
7
+ interface JSONModalProps extends EditorJSONProps {
8
+ /** 默认 查看 */
9
+ title?: string;
10
+ }
11
+
12
+ function Render(text, props: ProFormItemProps<JSONModalProps>) {
13
+ const { title = '查看' } = props.fieldProps || {};
14
+
15
+ const [show, setShow] = useState(false);
16
+
17
+ let jsonText = text;
18
+
19
+ if (!text) {
20
+ return <div>-</div>;
21
+ }
22
+
23
+ try {
24
+ jsonText = JSON.stringify(JSON.parse(text), null, 2);
25
+ } catch (e) {
26
+ console.error(e, text);
27
+ }
28
+
29
+ return (
30
+ <>
31
+ <a onClick={() => setShow(true)}>{title}</a>
32
+ <Modal
33
+ title={title}
34
+ open={show}
35
+ onCancel={() => setShow(false)}
36
+ onOk={() => setShow(false)}
37
+ cancelButtonProps={{
38
+ style: {
39
+ display: 'none',
40
+ },
41
+ }}
42
+ >
43
+ <div className="h-[500px]">
44
+ <EditorJSON value={jsonText} readonly />
45
+ </div>
46
+ </Modal>
47
+ </>
48
+ );
49
+ }
50
+
51
+ const jsonModalRender = {
52
+ render: Render,
53
+ renderFormItem: () => <></>,
54
+ };
55
+
56
+ export { jsonModalRender };
@@ -76,6 +76,12 @@ const Table = () => {
76
76
  ellipsis: true,
77
77
  valueType: CustomValueTypeEnum.CustomJSON,
78
78
  },
79
+ {
80
+ title: 'jsonModal',
81
+ dataIndex: 'jsonText',
82
+ ellipsis: true,
83
+ valueType: CustomValueTypeEnum.CustomJSONModal,
84
+ },
79
85
  ];
80
86
 
81
87
  return (