neo-cmp-cli 1.13.18 → 1.13.19

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 (29) hide show
  1. package/README.md +23 -3
  2. package/dist/package.json.js +1 -1
  3. package/package.json +1 -1
  4. package/template/neo-bi-cmps/src/components/filterBar__c/common.scss +1 -1
  5. package/template/neo-bi-cmps/src/components/filterBar__c/index.tsx +18 -10
  6. package/template/neo-bi-cmps/src/components/filterBar__c/model.ts +8 -2
  7. package/template/neo-bi-cmps/src/utils/common.ts +18 -20
  8. package/template/neo-bi-cmps/src/utils/filter2chartFilter.ts +4 -6
  9. package/template/neo-bi-cmps/src/utils/pipelineFunnel.ts +4 -2
  10. package/template/neo-bi-cmps/src/utils/simpleTable.tsx +21 -16
  11. package/template/neo-pipeline-cmps/src/components/filterBar__c/model.ts +10 -2
  12. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/index.tsx +1 -0
  13. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/model.ts +14 -2
  14. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/reset.scss +4 -0
  15. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/model.ts +14 -2
  16. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/model.ts +14 -2
  17. package/template/neo-web-entity-grid/src/components/createForm__c/index.tsx +271 -259
  18. package/template/neo-web-entity-grid/src/components/createForm__c/model.ts +17 -3
  19. package/template/neo-web-entity-grid/src/components/createForm__c/resetAntd.scss +0 -1
  20. package/template/neo-web-entity-grid/src/components/createForm__c/style.scss +1 -1
  21. package/template/neo-web-entity-grid/src/components/entityGrid2__c/index.tsx +5 -1
  22. package/template/neo-web-entity-grid/src/components/entityGrid2__c/model.ts +4 -3
  23. package/template/neo-web-entity-grid/src/components/entityGrid3__c/index.tsx +1 -1
  24. package/template/neo-web-entity-grid/src/components/searchForm__c/index.tsx +4 -3
  25. package/template/neo-web-entity-grid/src/components/searchForm__c/model.ts +9 -4
  26. package/template/neo-web-entity-grid/src/components/searchForm__c/style.scss +2 -1
  27. package/template/neo-web-form/src/components/batchAddTable__c/index.tsx +19 -19
  28. package/template/neo-web-form/src/components/batchAddTable__c/model.ts +11 -15
  29. package/template/neo-web-form/src/components/listSummary__c/index.tsx +6 -5
package/README.md CHANGED
@@ -59,10 +59,11 @@ neo init -t vue2 -n myVue2Cmp
59
59
  ### 1. 安装工具
60
60
 
61
61
  ```bash
62
- yarn global add neo-cmp-cli
63
- #
64
- npm i -g neo-cmp-cli
62
+ yarn global add neo-cmp-cli --registry https://registry.npmmirror.com
63
+ # 或(备注:使用国内淘宝的NPM源安装)
64
+ npm i -g neo-cmp-cli --registry=https://registry.npmmirror.com
65
65
  ```
66
+ 说明: 默认使用 国内淘宝的NPM源 安装 neo-cmp-cli,提高安装速度。
66
67
 
67
68
  ### 2. 创建项目
68
69
 
@@ -145,6 +146,25 @@ A: 如果提示“在此系统上禁止运行脚本”,这个可能是 Windows
145
146
 
146
147
  说明:以上命令用于设置 允许当前用户在此 Windows 客户端执行所有脚本。[关于 PowerShell 执行策略](https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.5)
147
148
 
149
+ **Q2: 使用 neo-cmp-cli 时,提示 “无法将 xxx 项识别为 cmdlet、函数、脚本文件或可运行程序的名称**
150
+ A: 这个报错是 Windows 最典型的环境变量 PATH 问题,PowerShell 找不到你安装的 CLI 命令所在的文件夹。可按以下 三个步骤把 npm 全局路径加到 PATH:
151
+
152
+ 步骤1: 查看 npm 全局安装路径(自动获取)
153
+ ```bash
154
+ $npmPath = npm config get prefix
155
+ ```
156
+
157
+ 步骤2: 把路径加到当前终端 PATH(立刻生效)
158
+ ```bash
159
+ $env:PATH += ";$npmPath"
160
+ ```
161
+
162
+ 步骤3: 永久写入系统环境变量(以后重启也能用)
163
+ ```bash
164
+ [Environment]::SetEnvironmentVariable("PATH", $env:PATH + ";$npmPath", "User")
165
+ ```
166
+
167
+ 说明: 出现以上问题,通常是因为安装 Node 时没有勾选「Automatically install the necessary tools. Note that this will also install Chocolatey. The script will pop-up in a new window after the installation completes.」。
148
168
 
149
169
  ---
150
170
 
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var e="1.13.18";const o={version:e};exports.default=o,exports.version=e;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var e="1.13.19";const o={version:e};exports.default=o,exports.version=e;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo-cmp-cli",
3
- "version": "1.13.18",
3
+ "version": "1.13.19",
4
4
  "description": "Neo 自定义组件开发工具,支持react 和 vue2.0技术栈。",
5
5
  "keywords": [
6
6
  "neo-cli",
@@ -26,4 +26,4 @@ body {
26
26
 
27
27
  .single-slot-layout .content-section {
28
28
  background-color: $background-color !important;
29
- }
29
+ }
@@ -156,8 +156,7 @@ class FilterBar extends BaseCmp<FilterBarProps, FilterBarState> {
156
156
  this.handleCloseDateRangeChange.bind(this);
157
157
  this.handleChangesSinceTimeChange =
158
158
  this.handleChangesSinceTimeChange.bind(this);
159
- this.closeDateRangePickerValue =
160
- this.closeDateRangePickerValue.bind(this);
159
+ this.closeDateRangePickerValue = this.closeDateRangePickerValue.bind(this);
161
160
  this.changesSinceDatePickerValue =
162
161
  this.changesSinceDatePickerValue.bind(this);
163
162
  this.getFilters = this.getFilters.bind(this);
@@ -245,9 +244,10 @@ class FilterBar extends BaseCmp<FilterBarProps, FilterBarState> {
245
244
  closeDateCustomRange: isCustom
246
245
  ? prev.closeDateCustomRange
247
246
  : relativeRange,
248
- changesSinceCustomTime: prev.values.changesSince === 'Custom'
249
- ? prev.changesSinceCustomTime
250
- : relativeRange?.start ?? null,
247
+ changesSinceCustomTime:
248
+ prev.values.changesSince === 'Custom'
249
+ ? prev.changesSinceCustomTime
250
+ : relativeRange?.start ?? null,
251
251
  };
252
252
  });
253
253
  }
@@ -285,8 +285,8 @@ class FilterBar extends BaseCmp<FilterBarProps, FilterBarState> {
285
285
  changesSinceCustomTime: changesCustom
286
286
  ? changesSinceCustomTime ?? undefined
287
287
  : rangeResolved?.start != null
288
- ? rangeResolved.start
289
- : undefined,
288
+ ? rangeResolved.start
289
+ : undefined,
290
290
  };
291
291
  }
292
292
 
@@ -299,7 +299,7 @@ class FilterBar extends BaseCmp<FilterBarProps, FilterBarState> {
299
299
  onValuesChange(payload);
300
300
  }
301
301
  this.onFiltersChange({
302
- data: payload
302
+ data: payload,
303
303
  });
304
304
 
305
305
  /*
@@ -317,7 +317,11 @@ class FilterBar extends BaseCmp<FilterBarProps, FilterBarState> {
317
317
  this.setState({ ownerLoading: true });
318
318
  const currentUser = Object.assign({}, this.props.data?.__NeoCurrentUser);
319
319
  // 给当前用户增加标记
320
- if (currentUser && currentUser.name && currentUser.name.indexOf('(CurrentUser)') === -1) {
320
+ if (
321
+ currentUser &&
322
+ currentUser.name &&
323
+ currentUser.name.indexOf('(CurrentUser)') === -1
324
+ ) {
321
325
  currentUser.name = currentUser.name + '(CurrentUser)';
322
326
  }
323
327
  const currentUserRecords =
@@ -709,7 +713,11 @@ class FilterBar extends BaseCmp<FilterBarProps, FilterBarState> {
709
713
  console.log('[FilterBar__c] render', this.props);
710
714
 
711
715
  return (
712
- <div className={`filterBar__c ${className || ''}`} style={style} data-time='2026.4.15 01'>
716
+ <div
717
+ className={`filterBar__c ${className || ''}`}
718
+ style={style}
719
+ data-time="2026.4.15 01"
720
+ >
713
721
  {this.renderCloseDateBlock()}
714
722
  {this.renderOwnerBlock()}
715
723
  {this.renderBusinessTypeBlock()}
@@ -25,8 +25,14 @@ export class FilterBarModel {
25
25
  label: '筛选条件变化后',
26
26
  helpText:
27
27
  '任一筛选项或自定义时间区间变更时触发;事件参数含 closeDate、closeDateCustomRange(非 custom 时为当前相对周期起止 Unix 毫秒时间戳;custom 时为 RangePicker 起止)、opportunityOwner(负责人多选 id 数组)、businessType、businessTypeLabel(业务类型展示名)、changesSince、changesSinceCustomTime(Changes Since 为 Custom 时为所选日期当日 0 点;否则在 Close Date 非 custom 时为周期起点当日 0 点)',
28
- eventParams:
29
- '[{"apiKey":"eventParam","children":[{"apiKey":"data","label":"当前筛选数据","type":"Object"}],"label":"事件入参","type":"Object"}]',
28
+ eventParams: [
29
+ {
30
+ apiKey: 'eventParam',
31
+ children: [{ apiKey: 'data', label: '当前筛选数据', type: 'Object' }],
32
+ label: '事件入参',
33
+ type: 'Object',
34
+ },
35
+ ],
30
36
  },
31
37
  ];
32
38
 
@@ -131,16 +131,18 @@ export function getDefaultOpportunityOwnerIds(
131
131
  ): (number | string)[] {
132
132
  // return [1246045]; // 默认用户改成 (Alice)
133
133
  const curUser = props.data?.__NeoCurrentUser;
134
- if (curUser?.id == null || curUser.name == null || String(curUser.name).trim() === '') {
134
+ if (
135
+ curUser?.id == null ||
136
+ curUser.name == null ||
137
+ String(curUser.name).trim() === ''
138
+ ) {
135
139
  return [];
136
140
  }
137
141
  return [curUser.id];
138
142
  }
139
143
 
140
144
  /** 负责人多选默认值:当前登录用户 id(与 __NeoCurrentUser 一致) */
141
- export function getDefaultFilterWhereByProps(
142
- props: any = {},
143
- ): any {
145
+ export function getDefaultFilterWhereByProps(props: any = {}): any {
144
146
  let userId = 1246045; // 默认用户(Alice)
145
147
  const curUser = props.data?.__NeoCurrentUser;
146
148
  if (curUser?.id) {
@@ -204,28 +206,24 @@ export function getDefaultFilterWhereByProps(
204
206
  return defaultFilter;
205
207
  }
206
208
 
207
- export function getDefaultFilterByProps(
208
- props: any = {},
209
- ): any {
209
+ export function getDefaultFilterByProps(props: any = {}): any {
210
210
  let userId = 1246045; // 默认用户(Alice)
211
211
  const curUser = props.data?.__NeoCurrentUser;
212
212
  if (curUser?.id) {
213
213
  userId = curUser.id;
214
214
  }
215
215
  const defaultFilter = {
216
- "closeDate": 401,
217
- "closeDateCustomRange": {
218
- "start": 1775059200000,
219
- "end": 1782835199999
216
+ closeDate: 401,
217
+ closeDateCustomRange: {
218
+ start: 1775059200000,
219
+ end: 1782835199999,
220
220
  },
221
- "opportunityOwner": [
222
- userId
223
- ],
224
- "businessType": 8150459,
225
- "businessTypeLabel": "New Business",
226
- "businessTypeApiKey": "defaultBusiType_1",
227
- "changesSince": "Start of the Period",
228
- "changesSinceCustomTime": 1775059200000
221
+ opportunityOwner: [userId],
222
+ businessType: 8150459,
223
+ businessTypeLabel: 'New Business',
224
+ businessTypeApiKey: 'defaultBusiType_1',
225
+ changesSince: 'Start of the Period',
226
+ changesSinceCustomTime: 1775059200000,
229
227
  };
230
228
  return defaultFilter;
231
- }
229
+ }
@@ -248,11 +248,9 @@ function entityTypeChunk(
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
+ };
@@ -132,13 +132,15 @@ export function classicFunnelLayerHeightPercents(
132
132
  if (n === 0) return [];
133
133
  const h = Math.max(viewHeightPx, 1);
134
134
  const factor = (h - gapPx * Math.max(n - 1, 0)) / h;
135
- const positives = amountNums.map((v) => (Number.isFinite(v) && v > 0 ? v : 0));
135
+ const positives = amountNums.map((v) =>
136
+ Number.isFinite(v) && v > 0 ? v : 0,
137
+ );
136
138
  const sum = positives.reduce((a, v) => a + v, 0);
137
139
  if (sum <= 0) {
138
140
  const even = (100 / n) * factor;
139
141
  return Array(n).fill(`${even}%`);
140
142
  }
141
- return positives.map((v) => `${(100 * (v / sum)) * factor}%`);
143
+ return positives.map((v) => `${100 * (v / sum) * factor}%`);
142
144
  }
143
145
 
144
146
  export interface BuildFunnelChartOptionParams {
@@ -91,9 +91,7 @@ export function historyRowToSnap(row: unknown): HistoryOppSnap | null {
91
91
  opportunityName: String(
92
92
  o.opportunity_1_opportunityName ?? o.opportunityName ?? '',
93
93
  ),
94
- saleStageId: String(
95
- o.opportunity_1_saleStageId ?? o.saleStageId ?? '',
96
- ),
94
+ saleStageId: String(o.opportunity_1_saleStageId ?? o.saleStageId ?? ''),
97
95
  money: o.opportunity_1_money ?? o.money,
98
96
  };
99
97
  }
@@ -151,7 +149,9 @@ export function formatMoneyCell(value: unknown): string {
151
149
  }
152
150
 
153
151
  /** oppHealthAssessmentLevel:数值 → 健康度标签(带颜色背景) */
154
- export function renderOppHealthAssessmentLevel(value: unknown): React.ReactNode {
152
+ export function renderOppHealthAssessmentLevel(
153
+ value: unknown,
154
+ ): React.ReactNode {
155
155
  if (value == null || value === '') return '—';
156
156
  const n = toFiniteNumber(value);
157
157
  if (n === 5) {
@@ -160,7 +160,9 @@ export function renderOppHealthAssessmentLevel(value: unknown): React.ReactNode
160
160
  );
161
161
  }
162
162
  if (n === 6) {
163
- return <span className="opp-health-tag opp-health-tag--yellow">Health</span>;
163
+ return (
164
+ <span className="opp-health-tag opp-health-tag--yellow">Health</span>
165
+ );
164
166
  }
165
167
  if (n === 7) {
166
168
  return <span className="opp-health-tag opp-health-tag--red">Risk</span>;
@@ -205,7 +207,9 @@ export function moneyChangeTooltipTitle(
205
207
  <div className="simpleTable-change-tip__detail">
206
208
  {formatMoneyCell(h.money)}
207
209
  {' → '}
208
- <span className="simpleTable-change-tip__to">{formatMoneyCell(current)}</span>
210
+ <span className="simpleTable-change-tip__to">
211
+ {formatMoneyCell(current)}
212
+ </span>
209
213
  </div>
210
214
  <div className="simpleTable-change-tip__meta">
211
215
  Changed on {formatChangeRecordedAt(preset)}
@@ -227,7 +231,9 @@ export function closeDateChangeTooltipTitle(
227
231
  <div className="simpleTable-change-tip__detail">
228
232
  {formatCloseDate(h.closeDate)}
229
233
  {' → '}
230
- <span className="simpleTable-change-tip__to">{formatCloseDate(current)}</span>
234
+ <span className="simpleTable-change-tip__to">
235
+ {formatCloseDate(current)}
236
+ </span>
231
237
  </div>
232
238
  <div className="simpleTable-change-tip__meta">
233
239
  Changed on {formatChangeRecordedAt(preset)}
@@ -275,15 +281,10 @@ export function renderWinRateHoverCard(record: any): React.ReactNode {
275
281
  const negatives = record?.customItem242__c;
276
282
  const winRate = record?.customItem239__c;
277
283
 
278
- const fmtLine = (v: unknown) =>
279
- v == null || v === '' ? '—' : String(v);
284
+ const fmtLine = (v: unknown) => (v == null || v === '' ? '—' : String(v));
280
285
 
281
286
  return (
282
- <Card
283
- size="small"
284
- bordered={false}
285
- className="simpleTable-winrate-card"
286
- >
287
+ <Card size="small" bordered={false} className="simpleTable-winrate-card">
287
288
  <div className="simpleTable-winrate-card__baseline">
288
289
  Baseline Probability{' '}
289
290
  <span className="simpleTable-winrate-card__baseline-val">
@@ -291,12 +292,16 @@ export function renderWinRateHoverCard(record: any): React.ReactNode {
291
292
  </span>
292
293
  </div>
293
294
  <hr className="simpleTable-winrate-card__hr" />
294
- <div className="simpleTable-winrate-card__section-title">Positive Factors</div>
295
+ <div className="simpleTable-winrate-card__section-title">
296
+ Positive Factors
297
+ </div>
295
298
  <div className="simpleTable-winrate-card__positives">
296
299
  {fmtLine(positives)}
297
300
  </div>
298
301
  <hr className="simpleTable-winrate-card__hr" />
299
- <div className="simpleTable-winrate-card__section-title">Negative Factors</div>
302
+ <div className="simpleTable-winrate-card__section-title">
303
+ Negative Factors
304
+ </div>
300
305
  <div className="simpleTable-winrate-card__negatives">
301
306
  {fmtLine(negatives)}
302
307
  </div>
@@ -26,8 +26,16 @@ export class FilterBarModel {
26
26
  label: 'After filter conditions change',
27
27
  helpText:
28
28
  'Triggered when any filter option or custom time range changes; event params include closeDate, closeDateCustomRange (for non-custom: current relative period start/end Unix ms timestamps; for custom: RangePicker start/end), opportunityOwner (owner multi-select id array), businessType, businessTypeLabel (business type display name), changesSince, changesSinceCustomTime (for Custom Changes Since: selected date midnight; otherwise for non-custom Close Date: period start midnight)',
29
- eventParams:
30
- '[{"apiKey":"eventParam","children":[{"apiKey":"data","label":"Current filter data","type":"Object"}],"label":"Event parameters","type":"Object"}]',
29
+ eventParams: [
30
+ {
31
+ apiKey: 'eventParam',
32
+ children: [
33
+ { apiKey: 'data', label: 'Current filter data', type: 'Object' },
34
+ ],
35
+ label: 'Event parameters',
36
+ type: 'Object',
37
+ },
38
+ ],
31
39
  },
32
40
  ];
33
41
 
@@ -25,6 +25,7 @@ import {
25
25
  type FunnelStage,
26
26
  } from '../../utils/pipelineFunnel';
27
27
 
28
+ import './reset.scss';
28
29
  import './style.scss';
29
30
 
30
31
  const QUERY_DATA_TASK_URL = '/rest/neobi/v2.0/bestpractices/queryDataTask';
@@ -21,8 +21,20 @@ export class PipelineFunnelModel {
21
21
  label: 'Triggered on stage click',
22
22
  helpText:
23
23
  'Triggered when clicking a funnel stage; event params include activeStage (current active stage)',
24
- eventParams:
25
- '[{"apiKey":"eventParam","children":[{"apiKey":"activeStage","label":"Current active stage","type":"String"}],"label":"Event parameters","type":"Object"}]',
24
+ eventParams: [
25
+ {
26
+ apiKey: 'eventParam',
27
+ children: [
28
+ {
29
+ apiKey: 'activeStage',
30
+ label: 'Current active stage',
31
+ type: 'String',
32
+ },
33
+ ],
34
+ label: 'Event parameters',
35
+ type: 'Object',
36
+ },
37
+ ],
26
38
  },
27
39
  ];
28
40
 
@@ -0,0 +1,4 @@
1
+ // 隐藏 AI icon
2
+ .nav-ai-container {
3
+ display: none;
4
+ }
@@ -19,8 +19,20 @@ export class StageSwitchModel {
19
19
  label: 'After active stage changes',
20
20
  helpText:
21
21
  'Triggered after the active stage changes; event params include activeStage (current active stage)',
22
- eventParams:
23
- '[{"apiKey":"eventParam","children":[{"apiKey":"activeStage","label":"Current active stage","type":"String"}],"label":"Event parameters","type":"Object"}]',
22
+ eventParams: [
23
+ {
24
+ apiKey: 'eventParam',
25
+ children: [
26
+ {
27
+ apiKey: 'activeStage',
28
+ label: 'Current active stage',
29
+ type: 'String',
30
+ },
31
+ ],
32
+ label: 'Event parameters',
33
+ type: 'Object',
34
+ },
35
+ ],
24
36
  },
25
37
  ];
26
38
 
@@ -33,8 +33,20 @@ export class StageTimeChartModel {
33
33
  label: 'Triggered on stage bar click',
34
34
  helpText:
35
35
  'Triggered when clicking a stage bar; event params include activeStage (current active stage)',
36
- eventParams:
37
- '[{"apiKey":"eventParam","children":[{"apiKey":"activeStage","label":"Current active stage","type":"String"}],"label":"Event parameters","type":"Object"}]',
36
+ eventParams: [
37
+ {
38
+ apiKey: 'eventParam',
39
+ children: [
40
+ {
41
+ apiKey: 'activeStage',
42
+ label: 'Current active stage',
43
+ type: 'String',
44
+ },
45
+ ],
46
+ label: 'Event parameters',
47
+ type: 'Object',
48
+ },
49
+ ],
38
50
  },
39
51
  ];
40
52
 
@@ -345,7 +345,7 @@ export default class CreateEntityForm extends React.PureComponent<
345
345
  // 触发表单提交事件
346
346
  this.onSubmit({
347
347
  xObjectApiKey,
348
- data: values
348
+ data: values,
349
349
  });
350
350
  });
351
351
  }
@@ -438,275 +438,287 @@ export default class CreateEntityForm extends React.PureComponent<
438
438
 
439
439
  return (
440
440
  <>
441
- <Form
442
- ref={(form) => this.setState({ form })}
443
- layout="horizontal"
444
- {...formItemLayout}
445
- >
446
- <Row gutter={16}>
447
- {curFieldList.map((field) => {
448
- // 跳过 ID 字段,不需要在表单中显示
449
- if (field.apiKey === 'id') return null;
450
-
451
- let inputComponent;
452
- const selectitem = field.selectitem || [];
453
- const checkitem = field.checkitem || [];
454
-
455
- // 关联字段:存在 referTo 时,渲染为点击选择弹窗的输入框
456
- if (field.referTo && (field.type !== 'entityType' && field.type !== 'entitytype')) {
457
- // 非业务类型字段
458
- const selectedLabel = referSelectedLabels[field.apiKey] || '';
441
+ <Form
442
+ ref={(form) => this.setState({ form })}
443
+ layout="horizontal"
444
+ {...formItemLayout}
445
+ >
446
+ <Row gutter={16}>
447
+ {curFieldList.map((field) => {
448
+ // 跳过 ID 字段,不需要在表单中显示
449
+ if (field.apiKey === 'id') return null;
450
+
451
+ let inputComponent;
452
+ const selectitem = field.selectitem || [];
453
+ const checkitem = field.checkitem || [];
454
+
455
+ // 关联字段:存在 referTo 时,渲染为点击选择弹窗的输入框
456
+ if (
457
+ field.referTo &&
458
+ field.type !== 'entityType' &&
459
+ field.type !== 'entitytype'
460
+ ) {
461
+ // 非业务类型字段
462
+ const selectedLabel = referSelectedLabels[field.apiKey] || '';
463
+ const colSpan = columnCount === 2 ? 12 : 24;
464
+ return (
465
+ <Col span={colSpan} key={field.apiKey}>
466
+ <Form.Item
467
+ label={field.label}
468
+ required={field.required ?? false}
469
+ >
470
+ <Input.Group compact style={{ display: 'flex' }}>
471
+ <Form.Item
472
+ name={field.apiKey}
473
+ noStyle
474
+ rules={[
475
+ {
476
+ required: field.required,
477
+ message: `请选择${field.label}`,
478
+ },
479
+ ]}
480
+ >
481
+ <Input type="hidden" />
482
+ </Form.Item>
483
+ <Input
484
+ readOnly
485
+ value={selectedLabel}
486
+ placeholder={`请点击选择${field.label}`}
487
+ style={{ flex: 1, cursor: 'pointer' }}
488
+ onClick={() => this.openReferModal(field)}
489
+ />
490
+ <Button
491
+ type="primary"
492
+ onClick={() => this.openReferModal(field)}
493
+ >
494
+ 选择
495
+ </Button>
496
+ </Input.Group>
497
+ </Form.Item>
498
+ </Col>
499
+ );
500
+ }
501
+
502
+ // 根据字段类型生成对应的输入组件
503
+ switch (field.type) {
504
+ case 'entityType':
505
+ case 'entitytype':
506
+ // 业务类型选择器
507
+ inputComponent = (
508
+ <Select placeholder="请选择业务类型" allowClear>
509
+ {entityTypeList.map((item) => (
510
+ <Option
511
+ key={item.apiKey}
512
+ value={item.id}
513
+ disabled={!item.active}
514
+ >
515
+ {item.label}
516
+ </Option>
517
+ ))}
518
+ </Select>
519
+ );
520
+ break;
521
+ case 'picklist':
522
+ // 单选下拉框
523
+ inputComponent = (
524
+ <Select placeholder={`请选择${field.label}`} allowClear>
525
+ {selectitem.map((item) => (
526
+ <Option key={item.apiKey} value={item.id}>
527
+ {item.label}
528
+ </Option>
529
+ ))}
530
+ </Select>
531
+ );
532
+ break;
533
+ case 'textarea':
534
+ // 多行文本输入框
535
+ inputComponent = (
536
+ <Input.TextArea
537
+ placeholder={`请输入${field.label}`}
538
+ rows={3}
539
+ showCount
540
+ maxLength={500}
541
+ />
542
+ );
543
+ break;
544
+ case 'multipicklist':
545
+ // 多选下拉框
546
+ inputComponent = (
547
+ <Select
548
+ placeholder={`请选择${field.label}`}
549
+ mode="multiple"
550
+ allowClear
551
+ >
552
+ {checkitem.map((item) => (
553
+ <Option key={item.apiKey} value={item.id}>
554
+ {item.label}
555
+ </Option>
556
+ ))}
557
+ </Select>
558
+ );
559
+ break;
560
+ case 'datetime':
561
+ // 日期时间选择器
562
+ inputComponent = (
563
+ <DatePicker
564
+ placeholder={`请选择${field.label}`}
565
+ format={'YYYY/MM/DD HH:mm:ss'}
566
+ showTime={true}
567
+ style={{ width: '100%' }}
568
+ />
569
+ );
570
+ break;
571
+ case 'date':
572
+ // 日期选择器
573
+ inputComponent = (
574
+ <DatePicker
575
+ placeholder={`请选择${field.label}`}
576
+ format={'YYYY/MM/DD'}
577
+ style={{ width: '100%' }}
578
+ />
579
+ );
580
+ break;
581
+ case 'time':
582
+ // 时间选择器
583
+ inputComponent = (
584
+ <DatePicker
585
+ placeholder={`请选择${field.label}`}
586
+ format={'HH:mm:ss'}
587
+ showTime={true}
588
+ style={{ width: '100%' }}
589
+ />
590
+ );
591
+ break;
592
+ case 'int':
593
+ case 'float':
594
+ // 数字输入框
595
+ inputComponent = (
596
+ <InputNumber
597
+ placeholder={`请输入${field.label}`}
598
+ style={{ width: '100%' }}
599
+ />
600
+ );
601
+ break;
602
+ case 'email':
603
+ // 邮箱输入框
604
+ inputComponent = (
605
+ <Input placeholder={`请输入${field.label}`} type="email" />
606
+ );
607
+ break;
608
+ case 'url':
609
+ // URL 输入框
610
+ inputComponent = (
611
+ <Input placeholder={`请输入${field.label}`} type="url" />
612
+ );
613
+ break;
614
+ case 'phone':
615
+ // 电话号码输入框
616
+ inputComponent = (
617
+ <Input placeholder={`请输入${field.label}`} type="tel" />
618
+ );
619
+ break;
620
+ default:
621
+ // 默认文本输入框
622
+ inputComponent = (
623
+ <Input
624
+ placeholder={`请输入${field.label}`}
625
+ maxLength={200}
626
+ />
627
+ );
628
+ }
629
+
459
630
  const colSpan = columnCount === 2 ? 12 : 24;
631
+
460
632
  return (
461
633
  <Col span={colSpan} key={field.apiKey}>
462
634
  <Form.Item
635
+ name={field.apiKey}
463
636
  label={field.label}
464
637
  required={field.required ?? false}
638
+ rules={[
639
+ {
640
+ required: field.required,
641
+ message: `请${
642
+ field.type === 'picklist' ||
643
+ field.type === 'multipicklist' ||
644
+ field.type === 'entityType' ||
645
+ field.type === 'entitytype' ||
646
+ field.type === 'date' ||
647
+ field.type === 'datetime' ||
648
+ field.type === 'time'
649
+ ? '选择'
650
+ : '输入'
651
+ }${field.label}`,
652
+ },
653
+ ]}
465
654
  >
466
- <Input.Group compact style={{ display: 'flex' }}>
467
- <Form.Item
468
- name={field.apiKey}
469
- noStyle
470
- rules={[
471
- {
472
- required: field.required,
473
- message: `请选择${field.label}`,
474
- },
475
- ]}
476
- >
477
- <Input type="hidden" />
478
- </Form.Item>
479
- <Input
480
- readOnly
481
- value={selectedLabel}
482
- placeholder={`请点击选择${field.label}`}
483
- style={{ flex: 1, cursor: 'pointer' }}
484
- onClick={() => this.openReferModal(field)}
485
- />
486
- <Button
487
- type="primary"
488
- onClick={() => this.openReferModal(field)}
489
- >
490
- 选择
491
- </Button>
492
- </Input.Group>
655
+ {inputComponent}
493
656
  </Form.Item>
494
657
  </Col>
495
658
  );
496
- }
497
-
498
- // 根据字段类型生成对应的输入组件
499
- switch (field.type) {
500
- case 'entityType':
501
- case 'entitytype':
502
- // 业务类型选择器
503
- inputComponent = (
504
- <Select placeholder="请选择业务类型" allowClear>
505
- {entityTypeList.map((item) => (
506
- <Option
507
- key={item.apiKey}
508
- value={item.id}
509
- disabled={!item.active}
510
- >
511
- {item.label}
512
- </Option>
513
- ))}
514
- </Select>
515
- );
516
- break;
517
- case 'picklist':
518
- // 单选下拉框
519
- inputComponent = (
520
- <Select placeholder={`请选择${field.label}`} allowClear>
521
- {selectitem.map((item) => (
522
- <Option key={item.apiKey} value={item.id}>
523
- {item.label}
524
- </Option>
525
- ))}
526
- </Select>
527
- );
528
- break;
529
- case 'textarea':
530
- // 多行文本输入框
531
- inputComponent = (
532
- <Input.TextArea
533
- placeholder={`请输入${field.label}`}
534
- rows={3}
535
- showCount
536
- maxLength={500}
537
- />
538
- );
539
- break;
540
- case 'multipicklist':
541
- // 多选下拉框
542
- inputComponent = (
543
- <Select
544
- placeholder={`请选择${field.label}`}
545
- mode="multiple"
546
- allowClear
547
- >
548
- {checkitem.map((item) => (
549
- <Option key={item.apiKey} value={item.id}>
550
- {item.label}
551
- </Option>
552
- ))}
553
- </Select>
554
- );
555
- break;
556
- case 'datetime':
557
- // 日期时间选择器
558
- inputComponent = (
559
- <DatePicker
560
- placeholder={`请选择${field.label}`}
561
- format={'YYYY/MM/DD HH:mm:ss'}
562
- showTime={true}
563
- style={{ width: '100%' }}
564
- />
565
- );
566
- break;
567
- case 'date':
568
- // 日期选择器
569
- inputComponent = (
570
- <DatePicker
571
- placeholder={`请选择${field.label}`}
572
- format={'YYYY/MM/DD'}
573
- style={{ width: '100%' }}
574
- />
575
- );
576
- break;
577
- case 'time':
578
- // 时间选择器
579
- inputComponent = (
580
- <DatePicker
581
- placeholder={`请选择${field.label}`}
582
- format={'HH:mm:ss'}
583
- showTime={true}
584
- style={{ width: '100%' }}
585
- />
586
- );
587
- break;
588
- case 'int':
589
- case 'float':
590
- // 数字输入框
591
- inputComponent = (
592
- <InputNumber
593
- placeholder={`请输入${field.label}`}
594
- style={{ width: '100%' }}
595
- />
596
- );
597
- break;
598
- case 'email':
599
- // 邮箱输入框
600
- inputComponent = (
601
- <Input placeholder={`请输入${field.label}`} type="email" />
602
- );
603
- break;
604
- case 'url':
605
- // URL 输入框
606
- inputComponent = (
607
- <Input placeholder={`请输入${field.label}`} type="url" />
608
- );
609
- break;
610
- case 'phone':
611
- // 电话号码输入框
612
- inputComponent = (
613
- <Input placeholder={`请输入${field.label}`} type="tel" />
614
- );
615
- break;
616
- default:
617
- // 默认文本输入框
618
- inputComponent = (
619
- <Input placeholder={`请输入${field.label}`} maxLength={200} />
620
- );
621
- }
622
-
623
- const colSpan = columnCount === 2 ? 12 : 24;
624
-
625
- return (
626
- <Col span={colSpan} key={field.apiKey}>
627
- <Form.Item
628
- name={field.apiKey}
629
- label={field.label}
630
- required={field.required ?? false}
631
- rules={[
632
- {
633
- required: field.required,
634
- message: `请${
635
- field.type === 'picklist' ||
636
- field.type === 'multipicklist' ||
637
- field.type === 'entityType' ||
638
- field.type === 'entitytype' ||
639
- field.type === 'date' ||
640
- field.type === 'datetime' ||
641
- field.type === 'time'
642
- ? '选择'
643
- : '输入'
644
- }${field.label}`,
659
+ })}
660
+ </Row>
661
+
662
+ {submitSuccess && (
663
+ <div className="submit-success-message">
664
+ <CheckCircleOutlined /> 数据已成功提交
665
+ </div>
666
+ )}
667
+ </Form>
668
+
669
+ <Modal
670
+ open={referModalVisible}
671
+ onCancel={this.closeReferModal}
672
+ footer={null}
673
+ width={900}
674
+ title={`选择${currentReferField?.label || ''}`}
675
+ destroyOnClose
676
+ >
677
+ {currentReferField && currentReferField.referTo && (
678
+ <NeoEntityGrid
679
+ render={this.props.render}
680
+ objectApiKey={currentReferField.referTo.apiKey}
681
+ referData={{
682
+ referObjectApiKey: xObjectDataApi?.xObjectApiKey,
683
+ referItemApiKey: currentReferField.apiKey,
684
+ }}
685
+ selectedCount={1}
686
+ hiddenHeader={true}
687
+ onCancel={this.closeReferModal}
688
+ onSelectedCall={(selectedData: any) => {
689
+ const { currentReferField: curField, currentReferField } =
690
+ this.state;
691
+ if (!curField) return;
692
+
693
+ const items = Array.isArray(selectedData)
694
+ ? selectedData
695
+ : [selectedData];
696
+ const firstItem = items[0];
697
+ const selectedId = firstItem?.id ?? firstItem;
698
+ const selectedName =
699
+ firstItem[`${currentReferField?.referTo?.apiKey}Name`] ||
700
+ firstItem?.label ||
701
+ firstItem?.name ||
702
+ firstItem?.id;
703
+
704
+ if (selectedId !== undefined && selectedId !== null) {
705
+ this.state.form?.setFieldsValue({
706
+ [curField.apiKey]: selectedId,
707
+ });
708
+ this.setState((prev) => ({
709
+ referSelectedLabels: {
710
+ ...prev.referSelectedLabels,
711
+ [curField.apiKey]: selectedName,
645
712
  },
646
- ]}
647
- >
648
- {inputComponent}
649
- </Form.Item>
650
- </Col>
651
- );
652
- })}
653
- </Row>
654
-
655
- {submitSuccess && (
656
- <div className="submit-success-message">
657
- <CheckCircleOutlined /> 数据已成功提交
658
- </div>
659
- )}
660
- </Form>
661
-
662
- <Modal
663
- open={referModalVisible}
664
- onCancel={this.closeReferModal}
665
- footer={null}
666
- width={900}
667
- title={`选择${currentReferField?.label || ''}`}
668
- destroyOnClose
669
- >
670
- {currentReferField && currentReferField.referTo && (
671
- <NeoEntityGrid
672
- render={this.props.render}
673
- objectApiKey={currentReferField.referTo.apiKey}
674
- referData={{
675
- referObjectApiKey: xObjectDataApi?.xObjectApiKey,
676
- referItemApiKey: currentReferField.apiKey,
677
- }}
678
- selectedCount={1}
679
- hiddenHeader={true}
680
- onCancel={this.closeReferModal}
681
- onSelectedCall={(selectedData: any) => {
682
- const { currentReferField: curField, currentReferField } = this.state;
683
- if (!curField) return;
684
-
685
- const items = Array.isArray(selectedData)
686
- ? selectedData
687
- : [selectedData];
688
- const firstItem = items[0];
689
- const selectedId = firstItem?.id ?? firstItem;
690
- const selectedName = firstItem[`${currentReferField?.referTo?.apiKey}Name`] || firstItem?.label || firstItem?.name || firstItem?.id;
691
-
692
- if (selectedId !== undefined && selectedId !== null) {
693
- this.state.form?.setFieldsValue({
694
- [curField.apiKey]: selectedId,
695
- });
696
- this.setState((prev) => ({
697
- referSelectedLabels: {
698
- ...prev.referSelectedLabels,
699
- [curField.apiKey]: selectedName,
700
- },
701
- referModalVisible: false,
702
- currentReferField: null,
703
- }));
704
- }
705
- return false; // 阻止事件冒泡
706
- }}
707
- />
708
- )}
709
- </Modal>
713
+ referModalVisible: false,
714
+ currentReferField: null,
715
+ }));
716
+ }
717
+ return false; // 阻止事件冒泡
718
+ }}
719
+ />
720
+ )}
721
+ </Modal>
710
722
  </>
711
723
  );
712
724
  }
@@ -52,7 +52,14 @@ export class CreateFormModel {
52
52
  columnCount: 2,
53
53
  xObjectDataApi: {
54
54
  xObjectApiKey: 'opportunity',
55
- fields: ['entityType', 'ownerId', 'opportunityName', 'accountId', 'money', 'closeDate'],
55
+ fields: [
56
+ 'entityType',
57
+ 'ownerId',
58
+ 'opportunityName',
59
+ 'accountId',
60
+ 'money',
61
+ 'closeDate',
62
+ ],
56
63
  },
57
64
  };
58
65
 
@@ -65,8 +72,15 @@ export class CreateFormModel {
65
72
  apiKey: 'onSubmit', // 事件名称
66
73
  label: '提交表单后', // 事件
67
74
  helpText: '表单提交后触发该事件', // 信息icon hover 时的提示文本
68
- eventParams: // 定义事件触发时接收到的事件数据格式
69
- '[{"apiKey":"eventParam","children":[{"apiKey":"data","label":"当前表单数据","type":"Object"}],"label":"事件入参","type":"Object"}]',
75
+ // 定义事件触发时接收到的事件数据格式
76
+ eventParams: [
77
+ {
78
+ apiKey: 'eventParam',
79
+ children: [{ apiKey: 'data', label: '当前表单数据', type: 'Object' }],
80
+ label: '事件入参',
81
+ type: 'Object',
82
+ },
83
+ ],
70
84
  },
71
85
  ];
72
86
 
@@ -1,4 +1,3 @@
1
-
2
1
  // Spin 加载样式
3
2
  .ant-spin {
4
3
  .ant-spin-dot {
@@ -55,7 +55,11 @@ export default class NeoEntityGridCmp extends BaseCmp<
55
55
  */
56
56
  @NeoEvent.function
57
57
  handleCustomSearchEvent(eventData: any) {
58
- console.log('设置自定义筛选条件(handleCustomSearchEvent): ', eventData, this.props);
58
+ console.log(
59
+ '设置自定义筛选条件(handleCustomSearchEvent): ',
60
+ eventData,
61
+ this.props,
62
+ );
59
63
 
60
64
  if (!eventData) {
61
65
  this.setState({ additionalConditions: [] });
@@ -67,14 +67,15 @@ export class NeoEntityGridModel {
67
67
  apiKey: 'handleCustomSearchEvent',
68
68
  label: '更新筛选条件',
69
69
  helpTextKey: '更新自定义筛选条件',
70
- funcInParams: [ // 定义组件函数入参
70
+ funcInParams: [
71
+ // 定义组件函数入参
71
72
  {
72
73
  apiKey: 'eventData',
73
74
  label: '自定义筛选条件',
74
75
  type: 'Array',
75
- required: true
76
+ required: true,
76
77
  },
77
- ]
78
+ ],
78
79
  },
79
80
  ];
80
81
 
@@ -61,7 +61,7 @@ export default class NeoEntityGridCmp extends React.PureComponent<NeoEntityGridP
61
61
  objectApiKey={objectApiKey || 'account'}
62
62
  pattern={'pickView'} // Picker 列表(选择器)
63
63
  referData={referData}
64
- selectionMode={selectionMode ?? "single"} // 多选模式
64
+ selectionMode={selectionMode ?? 'single'} // 多选模式
65
65
  shouldCloseDialog={restProps.shouldCloseDialog ?? true}
66
66
  onRowSelected={(data: any, event: any) => {
67
67
  const selectedIds = data.map(({ data }: any) => data.id);
@@ -335,10 +335,11 @@ export default class SearchForm extends React.PureComponent<
335
335
  const payload: CustomQueryPayload = {
336
336
  xObjectApiKey, // 冗余数据
337
337
  conditions, // 冗余数据
338
- data: { // 事件动作的入参数据
338
+ data: {
339
+ // 事件动作的入参数据
339
340
  xObjectApiKey,
340
- conditions
341
- }
341
+ conditions,
342
+ },
342
343
  };
343
344
 
344
345
  this.onQuery(payload);
@@ -66,10 +66,15 @@ export class SearchFormModel {
66
66
  label: '点击查询后',
67
67
  helpText:
68
68
  '点击「查询」后触发;事件参数为 { xObjectApiKey, conditions },conditions 每项含 apiKey、type(1 等于 / 3 包含)、value',
69
- eventParams1: // 测试使用:定义事件触发时接收到的事件数据格式
70
- '[{"apiKey":"eventParam","label":"当前表单数据","type":"Object"}]',
71
- eventParams: // 定义事件触发时接收到的事件数据格式
72
- '[{"apiKey":"eventParam","children":[{"apiKey":"data","label":"当前表单数据","type":"Object"}],"label":"事件入参","type":"Object"}]',
69
+ // 定义事件触发时接收到的事件数据格式
70
+ eventParams: [
71
+ {
72
+ apiKey: 'eventParam',
73
+ children: [{ apiKey: 'data', label: '当前表单数据', type: 'Object' }],
74
+ label: '事件入参',
75
+ type: 'Object',
76
+ },
77
+ ],
73
78
  },
74
79
  ];
75
80
 
@@ -189,7 +189,8 @@
189
189
  font-weight: 400;
190
190
  min-width: auto;
191
191
  margin-left: 10px;
192
- transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
192
+ transition: border-color 0.2s ease, background 0.2s ease,
193
+ box-shadow 0.2s ease;
193
194
 
194
195
  &:first-child {
195
196
  margin-left: 0;
@@ -332,17 +332,11 @@ export default class BatchAddTable extends React.PureComponent<
332
332
  (it) => it.id === raw || String(it.id) === s,
333
333
  );
334
334
  if (byId) return byId.id;
335
- const byLabel = entityTypeList.find(
336
- (it) => String(it.label).trim() === s,
337
- );
335
+ const byLabel = entityTypeList.find((it) => String(it.label).trim() === s);
338
336
  return byLabel ? byLabel.id : raw;
339
337
  }
340
338
 
341
- parseImportedCell(
342
- field: FieldInfo,
343
- raw: any,
344
- entityTypeList: any[],
345
- ): any {
339
+ parseImportedCell(field: FieldInfo, raw: any, entityTypeList: any[]): any {
346
340
  if (raw === undefined || raw === null || raw === '') return undefined;
347
341
  if (raw instanceof Date) {
348
342
  if (
@@ -430,7 +424,9 @@ export default class BatchAddTable extends React.PureComponent<
430
424
  const ws = XLSX.utils.aoa_to_sheet([headers]); // 将标题行转换为工作表
431
425
  const wb = XLSX.utils.book_new(); // 创建新的工作簿
432
426
  XLSX.utils.book_append_sheet(wb, ws, '导入模板'); // 将工作表添加到工作簿
433
- const name = `${this.props.xObjectDataApi?.xObjectApiKey || 'data'}_导入模板.xlsx`; // 生成文件名
427
+ const name = `${
428
+ this.props.xObjectDataApi?.xObjectApiKey || 'data'
429
+ }_导入模板.xlsx`; // 生成文件名
434
430
  XLSX.writeFile(wb, name); // 将工作簿写入文件
435
431
  message.success('模板已下载');
436
432
  }
@@ -775,11 +771,7 @@ export default class BatchAddTable extends React.PureComponent<
775
771
  style={{ minWidth: 140 }}
776
772
  >
777
773
  {entityTypeList.map((item) => (
778
- <Option
779
- key={item.apiKey}
780
- value={item.id}
781
- disabled={!item.active}
782
- >
774
+ <Option key={item.apiKey} value={item.id} disabled={!item.active}>
783
775
  {item.label}
784
776
  </Option>
785
777
  ))}
@@ -912,7 +904,17 @@ export default class BatchAddTable extends React.PureComponent<
912
904
  }
913
905
 
914
906
  render() {
915
- const { loading, error, rows, submitting, title, importLoading, importProgress, currentPage, pageSize } = this.state;
907
+ const {
908
+ loading,
909
+ error,
910
+ rows,
911
+ submitting,
912
+ title,
913
+ importLoading,
914
+ importProgress,
915
+ currentPage,
916
+ pageSize,
917
+ } = this.state;
916
918
  const { tableTitle, className, data } = this.props;
917
919
  const curAmisData = data || {};
918
920
  const systemInfo = curAmisData.__NeoSystemInfo || {};
@@ -974,12 +976,10 @@ export default class BatchAddTable extends React.PureComponent<
974
976
  const endIndex = startIndex + pageSize;
975
977
  const paginatedRows = rows.slice(startIndex, endIndex);
976
978
 
977
- const displayTitle =
978
- tableTitle || title || '批量新增数据';
979
+ const displayTitle = tableTitle || title || '批量新增数据';
979
980
  const batchImportButtonTitle =
980
981
  this.props.batchImportButtonTitle ?? '批量导入';
981
- const batchImportButtonAlign =
982
- this.props.batchImportButtonAlign ?? 'right';
982
+ const batchImportButtonAlign = this.props.batchImportButtonAlign ?? 'right';
983
983
 
984
984
  const showModalFooter = !error && !!xObjectApiKey && fields.length > 0;
985
985
 
@@ -31,21 +31,17 @@ export class BatchAddTableModel {
31
31
  apiKey: 'onSubmit',
32
32
  label: '点击提交',
33
33
  helpText: '点击提交按钮时触发,事件参数包含当前表格中所有行数据',
34
- /*
35
- eventParams:
36
- [{
37
- "apiKey": "eventParam",
38
- "children":
39
- [
40
- { "apiKey": "xObjectApiKey", "label": "实体 API Key", "type": "String" },
41
- { "apiKey": "rows", "label": "表格数据列表", "type": "Array" }
42
- ],
43
- "label": "事件入参",
44
- "type": "Object"
45
- }],
46
- */
47
- eventParams:
48
- '[{"apiKey":"eventParam","children":[{"apiKey":"xObjectApiKey","label":"实体 API Key","type":"String"},{"apiKey":"rows","label":"表格数据列表","type":"Array"}],"label":"事件入参","type":"Object"}]',
34
+ eventParams: [
35
+ {
36
+ apiKey: 'eventParam',
37
+ children: [
38
+ { apiKey: 'xObjectApiKey', label: '实体 API Key', type: 'String' },
39
+ { apiKey: 'rows', label: '表格数据列表', type: 'Array' },
40
+ ],
41
+ label: '事件入参',
42
+ type: 'Object',
43
+ },
44
+ ],
49
45
  },
50
46
  ];
51
47
 
@@ -29,7 +29,9 @@ interface ListSummaryState {
29
29
  listData: any[];
30
30
  }
31
31
 
32
- function getFirstFieldApiKey(desc?: FieldDescItem[] | null): string | undefined {
32
+ function getFirstFieldApiKey(
33
+ desc?: FieldDescItem[] | null,
34
+ ): string | undefined {
33
35
  if (!desc || !Array.isArray(desc) || desc.length === 0) return undefined;
34
36
  const first = desc[0];
35
37
  return first?.value;
@@ -84,12 +86,11 @@ class ListSummary extends BaseCmp<ListSummaryProps, ListSummaryState> {
84
86
 
85
87
  const hasRows = Array.isArray(listData) && listData.length > 0;
86
88
  const totalQty = hasRows && qtyKey ? sumField(listData, qtyKey) : 0;
87
- const totalAmount = hasRows && amountKey ? sumField(listData, amountKey) : 0;
89
+ const totalAmount =
90
+ hasRows && amountKey ? sumField(listData, amountKey) : 0;
88
91
 
89
92
  const qtyDisplay =
90
- !hasRows || !qtyKey
91
- ? '0'
92
- : totalQty.toLocaleString('zh-CN');
93
+ !hasRows || !qtyKey ? '0' : totalQty.toLocaleString('zh-CN');
93
94
 
94
95
  const amountDisplay =
95
96
  !hasRows || !amountKey