neo-cmp-cli 1.13.17 → 1.13.18

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/dist/index2.js +1 -1
  2. package/dist/neo/env.js +1 -1
  3. package/dist/neo/pushCmp.js +1 -1
  4. package/dist/package.json.js +1 -1
  5. package/package.json +3 -2
  6. package/template/asset-manage-template/docs/README.md +1 -232
  7. package/template/echarts-custom-cmp-template/package.json +1 -1
  8. package/template/neo-bi-cmps/package.json +1 -1
  9. package/template/neo-bi-cmps/src/components/targetNumber__c/model.ts +1 -1
  10. package/template/neo-custom-cmp-template/docs/README.md +0 -231
  11. package/template/neo-custom-cmp-template/package.json +1 -1
  12. package/template/neo-h5-cmps/src/components/entityList__c/index.tsx +1 -2
  13. package/template/neo-h5-cmps/src/components/entityTabs__c/index.tsx +1 -1
  14. package/template/neo-h5-cmps/src/components/globalSearchInput__c/index.tsx +1 -1
  15. package/template/neo-h5-cmps/src/components/openChatPageBtn__c/index.tsx +1 -2
  16. package/template/neo-pipeline-cmps/neo.config.js +11 -0
  17. package/template/neo-pipeline-cmps/src/assets/css/common.scss +16 -16
  18. package/template/neo-pipeline-cmps/src/assets/css/mixin.scss +5 -5
  19. package/template/neo-pipeline-cmps/src/components/filterBar__c/README.md +9 -9
  20. package/template/neo-pipeline-cmps/src/components/filterBar__c/common.scss +5 -5
  21. package/template/neo-pipeline-cmps/src/components/filterBar__c/index.tsx +47 -46
  22. package/template/neo-pipeline-cmps/src/components/filterBar__c/model.ts +13 -11
  23. package/template/neo-pipeline-cmps/src/components/filterBar__c/style.scss +1 -1
  24. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/README.md +17 -17
  25. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/index.tsx +23 -22
  26. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/model.ts +18 -17
  27. package/template/neo-pipeline-cmps/src/components/showHealthResult__c/index.tsx +33 -26
  28. package/template/neo-pipeline-cmps/src/components/showHealthResult__c/model.ts +9 -9
  29. package/template/neo-pipeline-cmps/src/components/simpleTable__c/README.md +53 -54
  30. package/template/neo-pipeline-cmps/src/components/simpleTable__c/common.scss +5 -5
  31. package/template/neo-pipeline-cmps/src/components/simpleTable__c/index.tsx +70 -68
  32. package/template/neo-pipeline-cmps/src/components/simpleTable__c/model.ts +41 -41
  33. package/template/neo-pipeline-cmps/src/components/simpleTable__c/style.scss +2 -3
  34. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/README.md +15 -15
  35. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/index.tsx +35 -33
  36. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/model.ts +16 -15
  37. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/README.md +18 -18
  38. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/index.tsx +20 -20
  39. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/model.ts +21 -18
  40. package/template/neo-pipeline-cmps/src/utils/common.ts +14 -14
  41. package/template/neo-pipeline-cmps/src/utils/filter2chartFilter.ts +21 -23
  42. package/template/neo-pipeline-cmps/src/utils/filterBar.ts +14 -14
  43. package/template/neo-pipeline-cmps/src/utils/pipelineFunnel.ts +5 -5
  44. package/template/neo-pipeline-cmps/src/utils/queryByCustomSQL.ts +26 -22
  45. package/template/neo-pipeline-cmps/src/utils/requestDebounce.ts +3 -3
  46. package/template/neo-pipeline-cmps/src/utils/simpleTable.tsx +31 -26
  47. package/template/neo-pipeline-cmps/src/utils/stageSwitch.ts +1 -1
  48. package/template/neo-pipeline-cmps/src/utils/stageTimeChart.ts +5 -5
  49. package/template/neo-pipeline-cmps/src/utils/targetNumber.ts +2 -2
  50. package/template/neo-web-form/package.json +1 -1
  51. package/template/neo-web-form/src/components/batchAddTable__c/index.tsx +161 -41
  52. package/template/neo-web-form/src/components/batchAddTable__c/model.ts +4 -2
  53. package/template/react-custom-cmp-template/package.json +1 -1
  54. package/template/asset-manage-template/src/utils/axiosFetcher.ts +0 -37
  55. package/template/asset-manage-template/src/utils/queryObjectData.ts +0 -112
  56. package/template/asset-manage-template/src/utils/xobjects.ts +0 -162
  57. package/template/neo-custom-cmp-template/src/utils/axiosFetcher.ts +0 -37
  58. package/template/neo-custom-cmp-template/src/utils/queryObjectData.ts +0 -112
  59. package/template/neo-custom-cmp-template/src/utils/xobjects.ts +0 -162
  60. package/template/neo-h5-cmps/src/utils/axiosFetcher.ts +0 -37
  61. package/template/neo-h5-cmps/src/utils/queryObjectData.ts +0 -112
  62. package/template/neo-h5-cmps/src/utils/xobjects.ts +0 -167
  63. package/template/neo-order-cmps/src/utils/axiosFetcher.ts +0 -37
  64. package/template/neo-order-cmps/src/utils/queryObjectData.ts +0 -112
  65. package/template/neo-order-cmps/src/utils/xobjects.ts +0 -162
  66. package/template/neo-web-entity-grid/src/utils/axiosFetcher.ts +0 -37
  67. package/template/neo-web-entity-grid/src/utils/queryObjectData.ts +0 -112
  68. package/template/neo-web-entity-grid/src/utils/xobjects.ts +0 -167
  69. package/template/neo-web-form/src/utils/axiosFetcher.ts +0 -37
  70. package/template/neo-web-form/src/utils/queryObjectData.ts +0 -112
  71. package/template/neo-web-form/src/utils/xobjects.ts +0 -167
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @file 阶段停留时间组件
3
- * @description 展示各销售阶段的平均停留时间;图表数据来自 NeoBI queryDataTask,目标/上限来自 XObject customItem3/4(天)
2
+ * @file Stage Time Component
3
+ * @description Displays the average time spent in each sales stage; chart data from NeoBI queryDataTask, target/limit from XObject customItem3/4 (days)
4
4
  */
5
5
  import * as React from 'react';
6
6
  import { Spin } from 'antd';
@@ -52,7 +52,7 @@ interface StageTimeChartProps {
52
52
  style?: React.CSSProperties;
53
53
  }
54
54
 
55
- /** 阈值行:仅将 customItem3/4 规范为 number,其余字段保持原样 */
55
+ /** Threshold row: only normalize customItem3/4 to number, keep other fields as-is */
56
56
  interface ThresholdRecordRow extends Record<string, unknown> {
57
57
  customItem3__c: number;
58
58
  customItem4__c: number;
@@ -63,14 +63,14 @@ interface StageTimeChartState {
63
63
  error: string | null;
64
64
  items: StageTimeItem[];
65
65
  filter: any;
66
- /** 与阈值行 customItem2__c 一致,默认 New Business(可由 setFilter 更新) */
66
+ /** Matches threshold row customItem2__c, default New Business (can be updated by setFilter) */
67
67
  oppType: string;
68
- /** fetchThresholdRecords 拉取的完整列表(已转换 customItem3/4 number */
68
+ /** Full list fetched by fetchThresholdRecords (customItem3/4 converted to number) */
69
69
  thresholdRecords: ThresholdRecordRow[];
70
70
  }
71
71
 
72
72
  class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
73
- /** 初始化 state */
73
+ /** Initialize state */
74
74
  constructor(props: StageTimeChartProps) {
75
75
  super(props);
76
76
  const initialOppType =
@@ -94,20 +94,20 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
94
94
  this.setFilter = this.setFilter.bind(this);
95
95
  }
96
96
 
97
- /** 挂载后拉取阈值与图表 */
97
+ /** Fetch thresholds and chart data after mount */
98
98
  componentDidMount() {
99
99
  this.fetchAllData();
100
100
 
101
101
  /*
102
- // 监听一个广播事件
102
+ // Listen to a broadcast event
103
103
  NeoEvent.listen('updateFilterData', (filterData: any) => {
104
- console.log('StageTimeChart 监听到了一个广播事件 updateFilterData: ', filterData);
104
+ console.log('StageTimeChart received broadcast event updateFilterData: ', filterData);
105
105
  this.setFilter(filterData);
106
106
  });
107
107
  */
108
108
  }
109
109
 
110
- /** 关键 props 变化时重新拉数 */
110
+ /** Re-fetch data when key props change */
111
111
  componentDidUpdate(
112
112
  prevProps: StageTimeChartProps,
113
113
  prevState: StageTimeChartState,
@@ -134,7 +134,7 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
134
134
  }
135
135
  }
136
136
 
137
- /** customItem1__c / customItem2__c 在列表中查找单行;customItem2 默认取 state.oppType */
137
+ /** Find a single row in the list by customItem1__c / customItem2__c; customItem2 defaults to state.oppType */
138
138
  getThresholdRecord(
139
139
  customItem1__c: string = String(this.state.oppType ?? 'New Business'),
140
140
  customItem2__c: string,
@@ -150,7 +150,7 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
150
150
  });
151
151
  }
152
152
 
153
- /** 请求阈值列表,仅把 customItem3/4 转为 number,并写入 state.thresholdRecords */
153
+ /** Fetch threshold list, only convert customItem3/4 to number, and write to state.thresholdRecords */
154
154
  async fetchThresholdRecords(): Promise<ThresholdRecordRow[]> {
155
155
  const { thresholdsXObjectApi } = this.props;
156
156
  const apiKey = thresholdsXObjectApi?.xObjectApiKey;
@@ -180,7 +180,7 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
180
180
 
181
181
  if (!result?.status) {
182
182
  console.warn(
183
- 'StageTimeChart xObject.query(thresholds) 非成功:',
183
+ 'StageTimeChart xObject.query(thresholds) not successful:',
184
184
  result?.msg ?? result,
185
185
  );
186
186
  this.setState({ thresholdRecords: [] });
@@ -199,13 +199,13 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
199
199
  this.setState({ thresholdRecords });
200
200
  return thresholdRecords;
201
201
  } catch (e) {
202
- console.error('StageTimeChart 加载阈值数据失败:', e);
202
+ console.error('StageTimeChart failed to load threshold data:', e);
203
203
  this.setState({ thresholdRecords: [] });
204
204
  return [];
205
205
  }
206
206
  }
207
207
 
208
- /** 请求 queryDataTask,解析表格行并挂上每行对应的 target/limit(来自阈值行 customItem3/4 */
208
+ /** Request queryDataTask, parse table rows and attach target/limit for each row (from threshold row customItem3/4) */
209
209
  async fetchChartRows(
210
210
  thresholdRecords: ThresholdRecordRow[],
211
211
  ): Promise<{ rows: StageTimeRow[]; error: string | null }> {
@@ -216,7 +216,7 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
216
216
  if (viewId == null || viewId === '' || userId == null || userId === '') {
217
217
  return {
218
218
  rows: [],
219
- error: '缺少 viewId 或当前用户 iddata.__NeoCurrentUser.id',
219
+ error: 'Missing viewId or current user id (data.__NeoCurrentUser.id)',
220
220
  };
221
221
  }
222
222
 
@@ -248,7 +248,7 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
248
248
  if (status !== 0 || !Array.isArray(table)) {
249
249
  return {
250
250
  rows: [],
251
- error: res?.message || res?.msg || '查询图表数据失败',
251
+ error: res?.message || res?.msg || 'Failed to query chart data',
252
252
  };
253
253
  }
254
254
 
@@ -286,10 +286,10 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
286
286
 
287
287
  return { rows, error: null };
288
288
  } catch (e: any) {
289
- console.error('StageTimeChart queryDataTask 失败:', e);
289
+ console.error('StageTimeChart queryDataTask failed:', e);
290
290
  return {
291
291
  rows: [],
292
- error: e?.message || '网络请求失败',
292
+ error: e?.message || 'Network request failed',
293
293
  };
294
294
  }
295
295
  }
@@ -370,7 +370,7 @@ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
370
370
  <div
371
371
  className={`stageTimeChart__c ${className || ''}`}
372
372
  style={style}
373
- data-time="2026.4.15 01"
373
+ data-time="2026.4.17 01"
374
374
  >
375
375
  <Spin spinning={loading}>
376
376
  <div className="chart-header">
@@ -1,7 +1,7 @@
1
1
  export class StageTimeChartModel {
2
- label: string = '阶段停留时间';
2
+ label: string = 'Stage Time';
3
3
  description: string =
4
- '展示各销售阶段的平均停留时间;图表来自 NeoBI queryDataTask,目标/上限来自 XObject customItem3/4(天)';
4
+ 'Displays the average time spent in each sales stage; chart data from NeoBI queryDataTask, target/limit from XObject customItem3/4 (days)';
5
5
  iconUrl: string = 'https://custom-widgets.bj.bcebos.com/barChart.svg';
6
6
  targetPage: string[] = ['all'];
7
7
  targetDevice: string = 'all';
@@ -11,9 +11,9 @@ export class StageTimeChartModel {
11
11
  viewId: '4264466340118875',
12
12
  viewType: 'sync',
13
13
  showAiButton: true,
14
- /** 与阈值记录 customItem2__c 匹配的商机类型,默认 New Business */
14
+ /** Opportunity type matching threshold record customItem2__c, default New Business */
15
15
  oppType: 'New Business',
16
- /** 阈值:customItem1__c 阶段键、customItem2__c 商机类型、customItem3__c/4 目标与上限(天) */
16
+ /** Thresholds: customItem1__c stage key, customItem2__c opportunity type, customItem3__c/4 target and limit (days) */
17
17
  thresholdsXObjectApi: {
18
18
  xObjectApiKey: 'customEntity105__c',
19
19
  fields: [
@@ -30,28 +30,29 @@ export class StageTimeChartModel {
30
30
  events = [
31
31
  {
32
32
  apiKey: 'onActiveStageChange',
33
- label: '点击阶段条触发',
33
+ label: 'Triggered on stage bar click',
34
34
  helpText:
35
- '点击阶段条触发;事件参数含 activeStage(当前激活阶段)',
35
+ 'Triggered when clicking a stage bar; event params include activeStage (current active stage)',
36
36
  eventParams:
37
- '[{"apiKey":"eventParam","children":[{"apiKey":"activeStage","label":"当前激活阶段","type":"String"}],"label":"事件入参","type":"Object"}]',
37
+ '[{"apiKey":"eventParam","children":[{"apiKey":"activeStage","label":"Current active stage","type":"String"}],"label":"Event parameters","type":"Object"}]',
38
38
  },
39
39
  ];
40
40
 
41
41
  functions = [
42
42
  {
43
43
  apiKey: 'refreshData',
44
- label: '刷新数据',
45
- helpTextKey: '重新请求 queryDataTask 与阈值配置,刷新停留时间',
44
+ label: 'Refresh data',
45
+ helpTextKey:
46
+ 'Re-request queryDataTask and threshold config to refresh stage time',
46
47
  },
47
48
  {
48
49
  apiKey: 'setFilter',
49
- label: '设置过滤条件',
50
- helpTextKey: '设置 queryDataTask filter 并重新拉取图表数据',
50
+ label: 'Set filter conditions',
51
+ helpTextKey: 'Set the queryDataTask filter and re-fetch chart data',
51
52
  funcInParams: [
52
53
  {
53
54
  apiKey: 'filter',
54
- label: '过滤条件',
55
+ label: 'Filter conditions',
55
56
  type: 'Object',
56
57
  required: false,
57
58
  },
@@ -63,27 +64,28 @@ export class StageTimeChartModel {
63
64
  {
64
65
  type: 'panelInput',
65
66
  name: 'title',
66
- label: '标题',
67
+ label: 'Title',
67
68
  },
68
69
  {
69
70
  type: 'panelInput',
70
71
  name: 'viewId',
71
- label: '视图 ID',
72
+ label: 'View ID',
72
73
  },
73
74
  {
74
75
  type: 'panelInput',
75
76
  name: 'viewType',
76
- label: '视图类型(请求 type',
77
+ label: 'View type (request type)',
77
78
  },
78
79
  {
79
80
  type: 'panelInput',
80
81
  name: 'oppType',
81
- label: '商机类型(匹配 customItem2__c',
82
+ label: 'Opportunity type (matching customItem2__c)',
82
83
  },
84
+ /*
83
85
  {
84
86
  type: 'xObjectDataApi',
85
87
  name: 'thresholdsXObjectApi',
86
- label: '阶段目标/上限数据源',
88
+ label: 'Stage target/limit data source',
87
89
  value: {
88
90
  xObjectApiKey: '',
89
91
  fields: [
@@ -94,9 +96,10 @@ export class StageTimeChartModel {
94
96
  ],
95
97
  },
96
98
  placeholder:
97
- '实体需含 customItem1__c(阶段)、customItem2__c(商机类型)、customItem3/4(目标/上限天)',
99
+ 'Entity must contain customItem1__c (stage), customItem2__c (opportunity type), customItem3/4 (target/limit days)',
98
100
  custom: true,
99
101
  },
102
+ */
100
103
  ];
101
104
  }
102
105
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 多组件共用的纯工具方法(筛选 where、阶段名、金额展示、NeoBI 请求体等)
2
+ * Shared pure utility methods across multiple components (filter where, stage name, amount display, NeoBI request body, etc.)
3
3
  */
4
4
 
5
5
  export interface PropsContext {
@@ -10,7 +10,7 @@ export interface PropsContext {
10
10
  };
11
11
  };
12
12
  }
13
- /** 筛选项转有限数字,无效返回 null(与 filter2chartFilter 等一致) */
13
+ /** Convert filter option to finite number, returns null if invalid (consistent with filter2chartFilter, etc.) */
14
14
  export function toFiniteNumber(v: unknown): number | null {
15
15
  if (v == null || v === '') return null;
16
16
  if (typeof v === 'number' && Number.isFinite(v)) return v;
@@ -18,7 +18,7 @@ export function toFiniteNumber(v: unknown): number | null {
18
18
  return Number.isFinite(n) ? n : null;
19
19
  }
20
20
 
21
- /** 时间区间起止:均为有效数字时返回闭区间 [start, end](毫秒时间戳,与 FilterBar 一致) */
21
+ /** Time range start/end: returns closed interval [start, end] when both are valid numbers (millisecond timestamps, consistent with FilterBar) */
22
22
  export function closeRangeFromFilter(
23
23
  range: unknown,
24
24
  ): { start: number; end: number } | null {
@@ -30,7 +30,7 @@ export function closeRangeFromFilter(
30
30
  return { start, end };
31
31
  }
32
32
 
33
- /** opportunityOwner 用于 where 的用户 id 列表(字符串避免大整数精度丢失) */
33
+ /** opportunityOwner -> user id list for where clause (string to avoid big integer precision loss) */
34
34
  export function normalizeOwnerIdsForWhere(owner: unknown): string[] {
35
35
  if (owner == null || owner === '') return [];
36
36
  const raw = Array.isArray(owner) ? owner : [owner];
@@ -51,7 +51,7 @@ export function entityTypeIdForWhere(businessType: unknown): string | null {
51
51
  return s.replace(/,/g, '');
52
52
  }
53
53
 
54
- /** 从阶段展示名取「第一个 . 之后」的片段,用于匹配 customItem1__c */
54
+ /** Extract the segment after the first '.' from stage display name, used for matching customItem1__c, etc. */
55
55
  export function extractStageKeyFromStageName(stageName: string): string {
56
56
  const s = String(stageName ?? '').trim();
57
57
  const i = s.indexOf('.');
@@ -59,7 +59,7 @@ export function extractStageKeyFromStageName(stageName: string): string {
59
59
  return s.slice(i + 1).trim();
60
60
  }
61
61
 
62
- /** 商机行等:空或无法解析时为 0 */
62
+ /** Opportunity rows, etc.: returns 0 when empty or unparseable */
63
63
  export function parseNumberOrZero(raw: unknown): number {
64
64
  if (raw === null || raw === undefined || raw === '') return 0;
65
65
  const n =
@@ -69,7 +69,7 @@ export function parseNumberOrZero(raw: unknown): number {
69
69
  return Number.isFinite(n) ? n : 0;
70
70
  }
71
71
 
72
- /** 阈值配置等:空或无法解析时为 NaN */
72
+ /** Threshold config, etc.: returns NaN when empty or unparseable */
73
73
  export function parseNumberOrNaN(raw: unknown): number {
74
74
  if (raw === null || raw === undefined || raw === '') return NaN;
75
75
  const n =
@@ -79,7 +79,7 @@ export function parseNumberOrNaN(raw: unknown): number {
79
79
  return Number.isFinite(n) ? n : NaN;
80
80
  }
81
81
 
82
- /** 展示用金额:$ 前缀;≥1e3 时使用 K / M / B / T 缩写 */
82
+ /** Display amount: $ prefix; uses K / M / B / T abbreviation when >= 1e3 */
83
83
  export function formatAmountDisplay(n: number): string {
84
84
  if (!Number.isFinite(n)) return '-';
85
85
  const sign = n < 0 ? '-' : '';
@@ -110,7 +110,7 @@ export function formatAmountDisplay(n: number): string {
110
110
  return `${sign}$${body}${suffix}`;
111
111
  }
112
112
 
113
- /** queryDataTaskx-www-form-urlencoded 表单体(filter JSON 字符串传递) */
113
+ /** queryDataTask: x-www-form-urlencoded form body (filter passed as JSON string) */
114
114
  export function buildQueryDataTaskFormBody(params: {
115
115
  viewId: string;
116
116
  userId: string | number;
@@ -125,11 +125,11 @@ export function buildQueryDataTaskFormBody(params: {
125
125
  return form.toString();
126
126
  }
127
127
 
128
- /** 负责人多选默认值:当前登录用户 id(与 __NeoCurrentUser 一致) */
128
+ /** Owner multi-select default: current logged-in user id (consistent with __NeoCurrentUser) */
129
129
  export function getDefaultOpportunityOwnerIds(
130
130
  props: PropsContext,
131
131
  ): (number | string)[] {
132
- // return [1246045]; // 默认用户改成 Alice
132
+ // return [1246045]; // Default user changed to (Alice)
133
133
  const curUser = props.data?.__NeoCurrentUser;
134
134
  if (
135
135
  curUser?.id == null ||
@@ -141,9 +141,9 @@ export function getDefaultOpportunityOwnerIds(
141
141
  return [curUser.id];
142
142
  }
143
143
 
144
- /** 负责人多选默认值:当前登录用户 id(与 __NeoCurrentUser 一致) */
144
+ /** Owner multi-select default: current logged-in user id (consistent with __NeoCurrentUser) */
145
145
  export function getDefaultFilterWhereByProps(props: any = {}): any {
146
- let userId = 1246045; // 默认用户(Alice
146
+ let userId = 1246045; // Default user (Alice)
147
147
  const curUser = props.data?.__NeoCurrentUser;
148
148
  if (curUser?.id) {
149
149
  userId = curUser.id;
@@ -207,7 +207,7 @@ export function getDefaultFilterWhereByProps(props: any = {}): any {
207
207
  }
208
208
 
209
209
  export function getDefaultFilterByProps(props: any = {}): any {
210
- let userId = 1246045; // 默认用户(Alice
210
+ let userId = 1246045; // Default user (Alice)
211
211
  const curUser = props.data?.__NeoCurrentUser;
212
212
  if (curUser?.id) {
213
213
  userId = curUser.id;
@@ -1,26 +1,26 @@
1
1
  /**
2
- * 过滤条件格式化
3
- * 将筛选栏组件得到的过滤条件格式化为接口需要的格式。
2
+ * Filter condition formatting
3
+ * Formats the filter conditions from the filter bar component into the format required by the API.
4
4
  *
5
- * 数据转换规则:
5
+ * Data conversion rules:
6
6
  1. closeDate
7
7
 
8
- custom:用 toFiniteNumber 把选项值(如 201 / "201")转成数字,timeType: 'relative'value: [{ val, baseType: 'system' }]
9
- custom:读取 closeDateCustomRange.start / end,二者均为有效数字时,timeType: 'absolute'value 为两条 { val, close: 1 };缺区间则不生成该项。
8
+ Non-custom: Use toFiniteNumber to convert the option value (e.g. 201 / "201") to a number, timeType: 'relative', value: [{ val, baseType: 'system' }].
9
+ custom: Read closeDateCustomRange.start / end; when both are valid numbers, timeType: 'absolute', value is two { val, close: 1 } entries; if range is missing, this item is not generated.
10
10
 
11
- 2. opportunityOwner ownerId
12
- 支持单值(字符串/数字)或多选数组;逐项 toFiniteNumber,无效项丢弃。至少一个有效 id 时生成 refer 条件(referKey: 'user'optionType: 'user'operate: 'in'includeNullValue: 0)。
13
- value 为数组,每个用户为 { val, sub: false, source: 'internal', specialType: 0 }
11
+ 2. opportunityOwner -> ownerId
12
+ Supports single value (string/number) or multi-select array; toFiniteNumber each item, invalid items are discarded. When at least one valid id exists, generates a refer condition (referKey: 'user', optionType: 'user', operate: 'in', includeNullValue: 0).
13
+ value is an array, each user is { val, sub: false, source: 'internal', specialType: 0 }.
14
14
 
15
- 3. businessType entityType
16
- 有值且能转成数字时,生成 refer + value: [{ val }];空字符串不传 entityType
15
+ 3. businessType -> entityType
16
+ When a value exists and can be converted to a number, generates refer + value: [{ val }]; empty string does not pass entityType.
17
17
 
18
18
  4. relation
19
- 按最终条目的 seq 拼成 "1 and 2 and 3";没有任何条件时为 ''filter []
19
+ Concatenated as "1 and 2 and 3" based on the seq of final items; when there are no conditions, it is '', filter is [].
20
20
 
21
21
  *
22
- * 例如:
23
- * 筛选栏组件得到的过滤条件:
22
+ * Example:
23
+ * Filter conditions from the filter bar component:
24
24
  {
25
25
  "closeDate": "custom",
26
26
  "closeDateCustomRange": {
@@ -33,7 +33,7 @@ value 为数组,每个用户为 { val, sub: false, source: 'internal', special
33
33
  "changesSinceCustomTime": 1776268800000
34
34
  }
35
35
 
36
- 接口需要的格式:
36
+ Format required by the API:
37
37
  {
38
38
  "relation": "1 and 2 and 3",
39
39
  "filter": [
@@ -96,7 +96,7 @@ value 为数组,每个用户为 { val, sub: false, source: 'internal', special
96
96
  ]
97
97
  }
98
98
 
99
- 如果是 closeDate custom,则需要将 closeDateCustomRange 格式化为接口需要的格式
99
+ If closeDate is custom, the closeDateCustomRange needs to be formatted into the API-required format
100
100
  {
101
101
  "seq": 3,
102
102
  "fieldKey": "closeDate",
@@ -193,7 +193,7 @@ const ownerUserValueItem = (val: number) => ({
193
193
  specialType: 0,
194
194
  });
195
195
 
196
- /** opportunityOwner(单值或 id 数组)解析出有效的用户 id 列表 */
196
+ /** Parse valid user id list from opportunityOwner (single value or id array) */
197
197
  function normalizeOwnerIds(owner: unknown): number[] {
198
198
  if (owner == null || owner === '') return [];
199
199
  const raw = Array.isArray(owner) ? owner : [owner];
@@ -244,15 +244,13 @@ function entityTypeChunk(
244
244
  }
245
245
 
246
246
  /**
247
- * 将筛选栏 payload 转为图表/接口 filter 结构;仅映射 closeDateownerIdentityType
247
+ * Convert filter bar payload to chart/API filter structure; only maps closeDate, ownerId, entityType.
248
248
  */
249
249
  export const filter2chartFilter = (filter: any): ChartFilterPayload => {
250
250
  const f = filter && typeof filter === 'object' ? filter : {};
251
- const parts = [
252
- closeDateChunk(f),
253
- ownerChunk(f),
254
- entityTypeChunk(f),
255
- ].filter(Boolean) as Omit<ChartFilterItem, 'seq'>[];
251
+ const parts = [closeDateChunk(f), ownerChunk(f), entityTypeChunk(f)].filter(
252
+ Boolean,
253
+ ) as Omit<ChartFilterItem, 'seq'>[];
256
254
 
257
255
  const filterOut: ChartFilterItem[] = parts.map((p, i) => ({
258
256
  ...p,
@@ -265,4 +263,4 @@ export const filter2chartFilter = (filter: any): ChartFilterPayload => {
265
263
  : filterOut.map((x) => String(x.seq)).join(' and ');
266
264
 
267
265
  return { relation, filter: filterOut };
268
- };
266
+ };
@@ -1,22 +1,22 @@
1
1
  /**
2
- * 筛选栏 filterBar 专用工具方法
2
+ * Filter bar filterBar specific utility methods
3
3
  */
4
4
  import moment from 'moment';
5
5
 
6
6
  export interface FilterOption {
7
7
  value: string | number;
8
8
  label: string;
9
- /** 业务类型等接口项上的 apiKey,用于与 defaultBusiType 配置对齐 */
9
+ /** apiKey on API items like business type, used to align with defaultBusiType config */
10
10
  apiKey?: string;
11
11
  }
12
12
 
13
- /** 自定义日期区间:起止为 Unix 毫秒时间戳(日为本地 startOfDay / endOfDay */
13
+ /** Custom date range: start/end are Unix millisecond timestamps (day is local startOfDay / endOfDay) */
14
14
  export interface TimestampRange {
15
15
  start?: number;
16
16
  end?: number;
17
17
  }
18
18
 
19
- /** 规范化下拉项的 value / label */
19
+ /** Normalize dropdown item value / label */
20
20
  export function normalizeOptions(list?: FilterOption[]): FilterOption[] {
21
21
  if (!Array.isArray(list) || list.length === 0) return [];
22
22
  return list.map((o) => ({
@@ -25,7 +25,7 @@ export function normalizeOptions(list?: FilterOption[]): FilterOption[] {
25
25
  }));
26
26
  }
27
27
 
28
- /** Changes Since 下拉默认项 */
28
+ /** Changes Since dropdown default options */
29
29
  export function defaultChangesSinceOptions(): FilterOption[] {
30
30
  return [
31
31
  { value: 'Start of the Period', label: 'Start of the Period' },
@@ -33,7 +33,7 @@ export function defaultChangesSinceOptions(): FilterOption[] {
33
33
  ];
34
34
  }
35
35
 
36
- /** RangePicker 选中的两天转为起止时间戳(含当日) */
36
+ /** Convert two selected days from RangePicker to start/end timestamps (inclusive of the day) */
37
37
  export function momentRangeToTimestamps(dates: any): TimestampRange | null {
38
38
  const m0 = dates?.[0];
39
39
  const m1 = dates?.[1];
@@ -45,8 +45,8 @@ export function momentRangeToTimestamps(dates: any): TimestampRange | null {
45
45
  }
46
46
 
47
47
  /**
48
- * Close Date 相对周期编码转为本地自然日的起止时间戳(起点 0 点,终点 23:59:59.999)。
49
- * 约定:百位 2=本周(iso )3=本月、4=本季度(如 201/301/401 及同段其它编码)。
48
+ * Convert Close Date relative period code to local calendar day start/end timestamps (start at midnight, end at 23:59:59.999).
49
+ * Convention: hundreds digit 2=this week (ISO week), 3=this month, 4=this quarter (e.g. 201/301/401 and other codes in the same range).
50
50
  */
51
51
  export function relativeCloseDateRangeFromCode(
52
52
  encoded: number | string,
@@ -62,7 +62,7 @@ export function relativeCloseDateRangeFromCode(
62
62
  };
63
63
  }
64
64
  if (curEncoded === 301) {
65
- // This Month(起点为月初次日 0 点)
65
+ // This Month (start is the second day of the month at midnight)
66
66
  return {
67
67
  start: now
68
68
  .clone()
@@ -74,7 +74,7 @@ export function relativeCloseDateRangeFromCode(
74
74
  };
75
75
  }
76
76
  if (curEncoded === 401) {
77
- // This Quarter(起点为季首次日 0 点)
77
+ // This Quarter (start is the second day of the quarter at midnight)
78
78
  return {
79
79
  start: now
80
80
  .clone()
@@ -88,7 +88,7 @@ export function relativeCloseDateRangeFromCode(
88
88
  return null;
89
89
  }
90
90
 
91
- /** user 实体查询结果转为负责人下拉项(按 id 去重) */
91
+ /** Convert user entity query results to owner dropdown options (deduplicated by id) */
92
92
  export function parseUserRecordsToOwnerOptions(records: any): FilterOption[] {
93
93
  const arr = Array.isArray(records) ? records : [];
94
94
  const seen = new Set<string>();
@@ -104,7 +104,7 @@ export function parseUserRecordsToOwnerOptions(records: any): FilterOption[] {
104
104
  return out;
105
105
  }
106
106
 
107
- /** 从业务类型接口响应中取出列表数组 */
107
+ /** Extract list array from business type API response */
108
108
  export function getBusinessTypeRawList(res: any): any[] {
109
109
  const raw = res?.data !== undefined ? res.data : res;
110
110
  const arr = Array.isArray(raw)
@@ -113,7 +113,7 @@ export function getBusinessTypeRawList(res: any): any[] {
113
113
  return Array.isArray(arr) ? arr : [];
114
114
  }
115
115
 
116
- /** 解析业务类型接口结果为下拉选项(保留 apiKey 供默认项匹配) */
116
+ /** Parse business type API results to dropdown options (preserving apiKey for default item matching) */
117
117
  export function parseBusinessTypes(res: any): FilterOption[] {
118
118
  const arr = getBusinessTypeRawList(res);
119
119
  return arr
@@ -126,7 +126,7 @@ export function parseBusinessTypes(res: any): FilterOption[] {
126
126
  }
127
127
 
128
128
  /**
129
- * 在业务类型选项中按 apiKey === defaultBusiType 解析默认选中值(与下拉 value 一致,一般为 id
129
+ * Resolve default selected value in business type options by apiKey === defaultBusiType (consistent with dropdown value, usually id)
130
130
  */
131
131
  export function resolveDefaultBusinessTypeValue(
132
132
  options: FilterOption[],
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Pipeline 漏斗 pipelineFunnel 专用(解析表格行、ECharts 配置)
2
+ * Pipeline funnel pipelineFunnel specific (parse table rows, ECharts config)
3
3
  */
4
4
  import * as echarts from 'echarts';
5
5
 
@@ -41,7 +41,7 @@ export function isTruthyProp(v: unknown): boolean {
41
41
  return v === true || v === 'true' || v === 1 || v === '1';
42
42
  }
43
43
 
44
- /** 与后端阶段名比对时忽略大小写与连续空白 */
44
+ /** Ignore case and consecutive whitespace when comparing with backend stage names */
45
45
  export function isClosedLostStageName(raw: unknown): boolean {
46
46
  const n = String(raw ?? '')
47
47
  .trim()
@@ -50,7 +50,7 @@ export function isClosedLostStageName(raw: unknown): boolean {
50
50
  return n === 'closed lost';
51
51
  }
52
52
 
53
- /** 去掉 Closed Lost 阶段行,保留表头;须在 parseRowsToStages 之前调用,以免计入总额与占比 */
53
+ /** Remove Closed Lost stage rows, keep header; must be called before parseRowsToStages to avoid counting in total and percentage */
54
54
  export function filterOutClosedLostRows(table: unknown[][]): unknown[][] {
55
55
  if (!Array.isArray(table) || table.length < 2) return table;
56
56
  const header = table[0];
@@ -122,7 +122,7 @@ export function funnelValueForStage(
122
122
  return 0;
123
123
  }
124
124
 
125
- /** 经典漏斗:宽度仍由 value(顺序)控制;层高按金额占比分配(与 series.gap 一致,单位为 px */
125
+ /** Classic funnel: width still controlled by value (order); layer height allocated by amount proportion (consistent with series.gap, unit is px) */
126
126
  export function classicFunnelLayerHeightPercents(
127
127
  amountNums: number[],
128
128
  viewHeightPx: number,
@@ -144,7 +144,7 @@ export function classicFunnelLayerHeightPercents(
144
144
  }
145
145
 
146
146
  export interface BuildFunnelChartOptionParams {
147
- /** 容器高度(px),经典模式下用于计算各层 height 百分比;变化时应重新 setOption */
147
+ /** Container height (px), used in classic mode to calculate layer height percentages; should re-setOption when changed */
148
148
  chartViewHeightPx?: number;
149
149
  funnelGap?: number;
150
150
  }