neo-cmp-cli 1.13.16 → 1.13.17

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 (151) hide show
  1. package/README.md +2 -1
  2. package/dist/index2.js +1 -1
  3. package/dist/main2.js +1 -1
  4. package/dist/neo/neoLogin.js +1 -1
  5. package/dist/package.json.js +1 -1
  6. package/package.json +1 -1
  7. package/template/antd-custom-cmp-template/package.json +1 -1
  8. package/template/asset-manage-template/package.json +2 -2
  9. package/template/echarts-custom-cmp-template/package.json +1 -1
  10. package/template/empty-custom-cmp-template/package.json +2 -2
  11. package/template/map-custom-cmp-template/package.json +1 -1
  12. package/template/neo-bi-cmps/neo.config.js +7 -1
  13. package/template/neo-bi-cmps/package.json +8 -7
  14. package/template/neo-bi-cmps/public/403.html +77 -0
  15. package/template/neo-bi-cmps/public/demo.html +2453 -0
  16. package/template/neo-bi-cmps/src/assets/icon/barChart.svg +1 -0
  17. package/template/neo-bi-cmps/src/assets/icon/card.svg +1 -0
  18. package/template/neo-bi-cmps/src/assets/icon/filter.svg +1 -0
  19. package/template/neo-bi-cmps/src/assets/icon/funnel.svg +1 -0
  20. package/template/neo-bi-cmps/src/assets/icon/tab.svg +1 -0
  21. package/template/neo-bi-cmps/src/components/filterBar__c/README.md +3 -14
  22. package/template/neo-bi-cmps/src/components/filterBar__c/common.scss +29 -0
  23. package/template/neo-bi-cmps/src/components/filterBar__c/index.tsx +668 -146
  24. package/template/neo-bi-cmps/src/components/filterBar__c/model.ts +26 -48
  25. package/template/neo-bi-cmps/src/components/filterBar__c/style.scss +46 -139
  26. package/template/neo-bi-cmps/src/components/targetNumber__c/customStyleConfig/index.tsx +11 -10
  27. package/template/neo-bi-cmps/src/components/targetNumber__c/index.tsx +9 -16
  28. package/template/neo-bi-cmps/src/utils/common.ts +231 -0
  29. package/template/neo-bi-cmps/src/utils/filter2chartFilter.ts +268 -0
  30. package/template/neo-bi-cmps/src/utils/filterBar.ts +140 -0
  31. package/template/neo-bi-cmps/src/utils/pipelineFunnel.ts +341 -0
  32. package/template/neo-bi-cmps/src/utils/queryByCustomSQL.ts +117 -0
  33. package/template/neo-bi-cmps/src/utils/requestDebounce.ts +22 -0
  34. package/template/neo-bi-cmps/src/utils/simpleTable.tsx +344 -0
  35. package/template/neo-bi-cmps/src/utils/stageSwitch.ts +15 -0
  36. package/template/neo-bi-cmps/src/utils/stageTimeChart.ts +90 -0
  37. package/template/neo-bi-cmps/src/utils/targetNumber.ts +12 -0
  38. package/template/neo-custom-cmp-template/package.json +2 -2
  39. package/template/neo-h5-cmps/package.json +2 -2
  40. package/template/neo-order-cmps/package.json +2 -2
  41. package/template/neo-pipeline-cmps/.prettierrc.js +12 -0
  42. package/template/neo-pipeline-cmps/@types/neo-ui-common.d.ts +36 -0
  43. package/template/neo-pipeline-cmps/README.md +99 -0
  44. package/template/neo-pipeline-cmps/commitlint.config.js +59 -0
  45. package/template/neo-pipeline-cmps/neo.config.js +124 -0
  46. package/template/neo-pipeline-cmps/package.json +66 -0
  47. package/template/neo-pipeline-cmps/public/403.html +77 -0
  48. package/template/neo-pipeline-cmps/public/css/base.css +283 -0
  49. package/template/neo-pipeline-cmps/public/demo.html +2453 -0
  50. package/template/neo-pipeline-cmps/public/scripts/app/bluebird.js +6679 -0
  51. package/template/neo-pipeline-cmps/public/template.html +13 -0
  52. package/template/neo-pipeline-cmps/src/assets/css/common.scss +127 -0
  53. package/template/neo-pipeline-cmps/src/assets/css/mixin.scss +47 -0
  54. package/template/neo-pipeline-cmps/src/assets/icon/barChart.svg +1 -0
  55. package/template/neo-pipeline-cmps/src/assets/icon/card.svg +1 -0
  56. package/template/neo-pipeline-cmps/src/assets/icon/filter.svg +1 -0
  57. package/template/neo-pipeline-cmps/src/assets/icon/funnel.svg +1 -0
  58. package/template/neo-pipeline-cmps/src/assets/icon/tab.svg +1 -0
  59. package/template/neo-pipeline-cmps/src/assets/img/AIBtn.gif +0 -0
  60. package/template/neo-pipeline-cmps/src/assets/img/NeoCRM.jpg +0 -0
  61. package/template/neo-pipeline-cmps/src/assets/img/aiLogo.png +0 -0
  62. package/template/neo-pipeline-cmps/src/assets/img/card-list.svg +1 -0
  63. package/template/neo-pipeline-cmps/src/assets/img/contact-form.svg +1 -0
  64. package/template/neo-pipeline-cmps/src/assets/img/custom-form.svg +1 -0
  65. package/template/neo-pipeline-cmps/src/assets/img/custom-widget.svg +1 -0
  66. package/template/neo-pipeline-cmps/src/assets/img/data-list.svg +1 -0
  67. package/template/neo-pipeline-cmps/src/assets/img/detail.svg +1 -0
  68. package/template/neo-pipeline-cmps/src/assets/img/favicon.png +0 -0
  69. package/template/neo-pipeline-cmps/src/assets/img/map.svg +1 -0
  70. package/template/neo-pipeline-cmps/src/assets/img/search.svg +1 -0
  71. package/template/neo-pipeline-cmps/src/assets/img/table.svg +1 -0
  72. package/template/neo-pipeline-cmps/src/components/filterBar__c/README.md +24 -0
  73. package/template/neo-pipeline-cmps/src/components/filterBar__c/common.scss +29 -0
  74. package/template/neo-pipeline-cmps/src/components/filterBar__c/index.tsx +730 -0
  75. package/template/neo-pipeline-cmps/src/components/filterBar__c/model.ts +50 -0
  76. package/template/neo-pipeline-cmps/src/components/filterBar__c/style.scss +119 -0
  77. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/index.tsx +415 -0
  78. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/model.ts +79 -0
  79. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/style.scss +83 -0
  80. package/template/neo-pipeline-cmps/src/components/showHealthResult__c/index.tsx +463 -0
  81. package/template/neo-pipeline-cmps/src/components/showHealthResult__c/model.ts +45 -0
  82. package/template/neo-pipeline-cmps/src/components/showHealthResult__c/style.scss +137 -0
  83. package/template/neo-pipeline-cmps/src/components/simpleTable__c/README.md +90 -0
  84. package/template/neo-pipeline-cmps/src/components/simpleTable__c/common.scss +195 -0
  85. package/template/neo-pipeline-cmps/src/components/simpleTable__c/index.tsx +665 -0
  86. package/template/neo-pipeline-cmps/src/components/simpleTable__c/model.ts +124 -0
  87. package/template/neo-pipeline-cmps/src/components/simpleTable__c/style.scss +193 -0
  88. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/index.tsx +511 -0
  89. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/model.ts +70 -0
  90. package/template/{neo-bi-cmps → neo-pipeline-cmps}/src/components/stageSwitch__c/style.scss +4 -2
  91. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/index.tsx +455 -0
  92. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/model.ts +103 -0
  93. package/template/{neo-bi-cmps → neo-pipeline-cmps}/src/components/stageTimeChart__c/style.scss +3 -2
  94. package/template/neo-pipeline-cmps/src/utils/common.ts +229 -0
  95. package/template/neo-pipeline-cmps/src/utils/filter2chartFilter.ts +268 -0
  96. package/template/neo-pipeline-cmps/src/utils/filterBar.ts +140 -0
  97. package/template/neo-pipeline-cmps/src/utils/pipelineFunnel.ts +343 -0
  98. package/template/neo-pipeline-cmps/src/utils/queryByCustomSQL.ts +117 -0
  99. package/template/neo-pipeline-cmps/src/utils/requestDebounce.ts +22 -0
  100. package/template/neo-pipeline-cmps/src/utils/simpleTable.tsx +344 -0
  101. package/template/neo-pipeline-cmps/src/utils/stageSwitch.ts +15 -0
  102. package/template/neo-pipeline-cmps/src/utils/stageTimeChart.ts +90 -0
  103. package/template/neo-pipeline-cmps/src/utils/targetNumber.ts +12 -0
  104. package/template/neo-pipeline-cmps/tsconfig.json +40 -0
  105. package/template/neo-web-entity-grid/package.json +2 -2
  106. package/template/neo-web-form/package.json +2 -2
  107. package/template/react-custom-cmp-template/package.json +1 -1
  108. package/template/react-ts-custom-cmp-template/package.json +1 -1
  109. package/template/vue2-custom-cmp-template/package.json +1 -1
  110. package/template/neo-bi-cmps/.npmrc copy +0 -1
  111. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/README.md +0 -52
  112. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/index.tsx +0 -183
  113. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/model.ts +0 -90
  114. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/style.scss +0 -218
  115. package/template/neo-bi-cmps/src/components/forecastChart__c/README.md +0 -31
  116. package/template/neo-bi-cmps/src/components/forecastChart__c/index.tsx +0 -158
  117. package/template/neo-bi-cmps/src/components/forecastChart__c/model.ts +0 -40
  118. package/template/neo-bi-cmps/src/components/forecastChart__c/style.scss +0 -154
  119. package/template/neo-bi-cmps/src/components/forecastGrid__c/README.md +0 -36
  120. package/template/neo-bi-cmps/src/components/forecastGrid__c/index.tsx +0 -86
  121. package/template/neo-bi-cmps/src/components/forecastGrid__c/model.ts +0 -62
  122. package/template/neo-bi-cmps/src/components/forecastGrid__c/style.scss +0 -48
  123. package/template/neo-bi-cmps/src/components/gapCloser__c/README.md +0 -24
  124. package/template/neo-bi-cmps/src/components/gapCloser__c/index.tsx +0 -100
  125. package/template/neo-bi-cmps/src/components/gapCloser__c/model.ts +0 -46
  126. package/template/neo-bi-cmps/src/components/gapCloser__c/style.scss +0 -60
  127. package/template/neo-bi-cmps/src/components/kpiCards__c/README.md +0 -35
  128. package/template/neo-bi-cmps/src/components/kpiCards__c/index.tsx +0 -70
  129. package/template/neo-bi-cmps/src/components/kpiCards__c/model.ts +0 -50
  130. package/template/neo-bi-cmps/src/components/kpiCards__c/style.scss +0 -33
  131. package/template/neo-bi-cmps/src/components/oppList__c/README.md +0 -52
  132. package/template/neo-bi-cmps/src/components/oppList__c/index.tsx +0 -285
  133. package/template/neo-bi-cmps/src/components/oppList__c/model.ts +0 -86
  134. package/template/neo-bi-cmps/src/components/oppList__c/style.scss +0 -133
  135. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/index.tsx +0 -130
  136. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/model.ts +0 -66
  137. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/style.scss +0 -133
  138. package/template/neo-bi-cmps/src/components/stageSwitch__c/index.tsx +0 -118
  139. package/template/neo-bi-cmps/src/components/stageSwitch__c/model.ts +0 -92
  140. package/template/neo-bi-cmps/src/components/stageTimeChart__c/index.tsx +0 -126
  141. package/template/neo-bi-cmps/src/components/stageTimeChart__c/model.ts +0 -57
  142. package/template/neo-bi-cmps/src/components/tabSwitch__c/README.md +0 -37
  143. package/template/neo-bi-cmps/src/components/tabSwitch__c/index.tsx +0 -80
  144. package/template/neo-bi-cmps/src/components/tabSwitch__c/model.ts +0 -45
  145. package/template/neo-bi-cmps/src/components/tabSwitch__c/style.scss +0 -37
  146. package/template/neo-bi-cmps/src/utils/axiosFetcher.ts +0 -37
  147. package/template/neo-bi-cmps/src/utils/queryObjectData.ts +0 -76
  148. package/template/neo-bi-cmps/src/utils/xobjects.ts +0 -162
  149. /package/template/{neo-bi-cmps → neo-pipeline-cmps}/src/components/pipelineFunnel__c/README.md +0 -0
  150. /package/template/{neo-bi-cmps → neo-pipeline-cmps}/src/components/stageSwitch__c/README.md +0 -0
  151. /package/template/{neo-bi-cmps → neo-pipeline-cmps}/src/components/stageTimeChart__c/README.md +0 -0
@@ -1,72 +1,50 @@
1
1
  export class FilterBarModel {
2
2
  label: string = '筛选栏';
3
3
  description: string = '支持日期范围、负责人、业务类型等多维度筛选';
4
- iconUrl: string = 'https://custom-widgets.bj.bcebos.com/filterBar.svg';
4
+ iconUrl: string = 'https://custom-widgets.bj.bcebos.com/filter.svg';
5
5
  targetPage: string[] = ['all'];
6
6
  targetDevice: string = 'all';
7
7
 
8
8
  defaultComProps = {
9
- filters: [
10
- {
11
- name: 'closeDate',
12
- label: 'Close Date',
13
- type: 'select',
14
- options: [
15
- { value: 'This Week', label: 'This Week' },
16
- { value: 'This Month', label: 'This Month' },
17
- { value: 'This Quarter', label: 'This Quarter' },
18
- { value: 'Custom', label: 'Custom' },
19
- ],
20
- },
21
- {
22
- name: 'owner',
23
- label: 'Opportunity Owner',
24
- type: 'owner',
25
- },
26
- {
27
- name: 'businessType',
28
- label: 'Business Type',
29
- type: 'select',
30
- options: [
31
- { value: 'New Business', label: 'New Business' },
32
- { value: 'Renewal', label: 'Renewal' },
33
- { value: 'Expansion', label: 'Expansion' },
34
- ],
35
- },
36
- {
37
- name: 'changesSince',
38
- label: 'Changes Since',
39
- type: 'select',
40
- options: [
41
- { value: 'Start of the Period', label: 'Start of the Period' },
42
- { value: 'Custom', label: 'Custom' },
43
- ],
44
- },
9
+ closeDateOptions: [
10
+ { value: 201, label: 'This Week' },
11
+ { value: 301, label: 'This Month' },
12
+ { value: 401, label: 'This Quarter' },
13
+ { value: 'custom', label: 'Custom' },
45
14
  ],
46
- values: {},
15
+ /** 与商机业务类型接口返回项的 apiKey 一致时,作为 Business Type 默认选中项 */
16
+ defaultBusiType: 'defaultBusiType_1', // New Business
47
17
  };
48
18
 
19
+ /**
20
+ * 声明当前组件会触发的所有事件(与组件内 @NeoEvent.dispatch 方法名一致)
21
+ */
22
+ events = [
23
+ {
24
+ apiKey: 'onFiltersChange',
25
+ label: '筛选条件变化后',
26
+ helpText:
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"}]',
30
+ },
31
+ ];
32
+
49
33
  functions = [
50
34
  {
51
35
  apiKey: 'resetFilters',
52
36
  label: '重置筛选条件',
53
- helpTextKey: '重置所有筛选条件为默认值',
37
+ helpTextKey: '重置所有筛选条件为默认值并触发「筛选条件变化后」事件',
54
38
  },
55
39
  {
56
40
  apiKey: 'getFilters',
57
41
  label: '获取筛选条件',
58
- helpTextKey: '获取当前筛选条件',
42
+ helpTextKey:
43
+ '返回当前筛选快照对象;closeDate 非 custom 时 closeDateCustomRange 为相对周期起止时间戳;custom 时为自定义区间;businessTypeLabel 为业务类型展示名;changesSinceCustomTime 在 Changes Since 为 Custom 时为所选日 0 点,否则在 Close Date 非 custom 时为周期起点 0 点',
59
44
  },
60
45
  ];
61
46
 
62
- propsSchema = [
63
- {
64
- type: 'object',
65
- name: 'filters',
66
- label: '筛选配置',
67
- schema: [],
68
- },
69
- ];
47
+ propsSchema = [];
70
48
  }
71
49
 
72
50
  export default FilterBarModel;
@@ -1,39 +1,59 @@
1
- .filter-bar__c {
1
+ .filterBar__c {
2
2
  background: #fff;
3
3
  border-radius: 8px;
4
4
  padding: 16px 20px;
5
5
  display: flex;
6
- gap: 24px;
7
- align-items: center;
8
- margin-bottom: 20px;
6
+ flex-wrap: wrap;
7
+ justify-content: flex-start;
8
+ gap: 10px 12px;
9
+ align-items: flex-start;
10
+ align-content: flex-start;
11
+ margin-bottom: 12px;
9
12
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
10
13
 
11
- .filter-group {
14
+ .filter-block {
12
15
  display: flex;
16
+ flex-wrap: nowrap;
13
17
  align-items: center;
14
- gap: 8px;
15
- position: relative;
18
+ gap: 6px 8px;
19
+ flex: 0 1 auto;
20
+ min-width: 0;
21
+ max-width: 100%;
22
+ }
23
+
24
+ .filter-field {
25
+ display: flex;
26
+ flex-wrap: nowrap;
27
+ align-items: center;
28
+ gap: 6px;
29
+ min-width: 0;
16
30
 
17
31
  label {
18
32
  font-size: 13px;
19
33
  color: #666;
20
34
  white-space: nowrap;
35
+ display: inline-flex;
36
+ align-items: center;
37
+ gap: 4px;
21
38
  }
22
39
 
23
- select,
24
- input {
25
- padding: 6px 12px;
26
- border: 1px solid #ddd;
27
- border-radius: 6px;
28
- font-size: 13px;
29
- background: #fff;
30
- cursor: pointer;
40
+ &.filter-field-range {
41
+ flex: 0 0 auto;
31
42
  }
43
+ }
32
44
 
33
- select:focus {
34
- border-color: #6366f1;
35
- outline: none;
36
- }
45
+ .filter-select {
46
+ min-width: 160px;
47
+ max-width: 100%;
48
+ }
49
+
50
+ .filter-select-wide {
51
+ min-width: 220px;
52
+ }
53
+
54
+ .filter-select-spin-wrap {
55
+ min-width: 220px;
56
+ min-height: 32px;
37
57
  }
38
58
 
39
59
  .filter-btn {
@@ -51,133 +71,20 @@
51
71
  }
52
72
  }
53
73
 
54
- /* Owner选人选部门组件 */
55
- .owner-picker-wrap {
56
- position: relative;
57
- }
58
-
59
- .owner-picker-trigger {
60
- display: flex;
61
- align-items: center;
62
- gap: 6px;
63
- padding: 6px 12px;
64
- border: 1px solid #ddd;
65
- border-radius: 6px;
66
- font-size: 13px;
67
- cursor: pointer;
68
- background: #fff;
69
- min-width: 140px;
70
-
71
- &:hover {
72
- border-color: #6366f1;
73
- }
74
- }
75
-
76
- .owner-selected-text {
77
- flex: 1;
78
- }
79
-
80
- .owner-arrow {
81
- font-size: 10px;
82
- color: #999;
83
- }
84
-
85
- .owner-picker-dropdown {
86
- display: none;
87
- position: absolute;
88
- top: 100%;
89
- left: 0;
90
- margin-top: 4px;
91
- width: 260px;
92
- background: #fff;
93
- border-radius: 8px;
94
- box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
95
- z-index: 250;
96
- padding: 8px 0;
97
- max-height: 340px;
98
- overflow-y: auto;
99
-
100
- &.open {
101
- display: block;
102
- }
103
- }
104
-
105
- .owner-search {
106
- width: calc(100% - 16px);
107
- margin: 0 8px 8px;
108
- padding: 8px 10px;
109
- border: 1px solid #eee;
110
- border-radius: 6px;
111
- font-size: 12px;
112
- outline: none;
113
-
114
- &:focus {
115
- border-color: #6366f1;
116
- }
117
- }
118
-
119
- .owner-section-label {
120
- padding: 6px 14px;
121
- font-size: 11px;
122
- color: #999;
123
- font-weight: 600;
124
- text-transform: uppercase;
125
- letter-spacing: 0.5px;
126
- }
127
-
128
- .owner-item {
129
- display: flex;
130
- align-items: center;
131
- gap: 8px;
132
- padding: 8px 14px;
133
- font-size: 13px;
134
- cursor: pointer;
135
- transition: background 0.15s;
136
-
137
- &:hover {
138
- background: #f5f5ff;
139
- }
140
-
141
- &.selected {
142
- background: #f0f0ff;
143
- color: #6366f1;
144
- font-weight: 600;
145
- }
146
- }
147
-
148
- .owner-icon {
149
- font-size: 14px;
150
- width: 20px;
151
- text-align: center;
152
- }
153
-
154
- .owner-check {
155
- width: 16px;
156
- height: 16px;
157
- border: 1.5px solid #ccc;
158
- border-radius: 3px;
159
- display: flex;
160
- align-items: center;
161
- justify-content: center;
162
- font-size: 11px;
163
- color: transparent;
164
- flex-shrink: 0;
165
- }
166
-
167
- .owner-item.selected .owner-check {
168
- background: #6366f1;
169
- border-color: #6366f1;
170
- color: #fff;
171
- }
172
-
173
74
  /* Changes Since 问号提示 */
174
75
  .help-tip {
175
76
  position: relative;
176
- display: inline-block;
77
+ display: inline-flex;
78
+ align-items: center;
79
+ justify-content: center;
177
80
  cursor: help;
178
81
  color: #999;
179
82
  font-size: 12px;
180
83
  margin-left: 2px;
84
+ width: 16px;
85
+ height: 16px;
86
+ border-radius: 50%;
87
+ border: 1px solid #ddd;
181
88
 
182
89
  .help-tip-text {
183
90
  display: none;
@@ -41,13 +41,14 @@ export default class CustomStyleConfigRenderer extends React.Component<
41
41
  this.handleModalOk = this.handleModalOk.bind(this);
42
42
  this.handleModalCancel = this.handleModalCancel.bind(this);
43
43
  this.handleEditorChange = this.handleEditorChange.bind(this);
44
+ this.getDisplayValue = this.getDisplayValue.bind(this);
44
45
  }
45
46
 
46
- handleEditorChange = (value: any) => {
47
+ handleEditorChange(value: any) {
47
48
  this.setState({ editorValue: value });
48
- };
49
+ }
49
50
 
50
- handleModalOk = () => {
51
+ handleModalOk() {
51
52
  const { editorValue } = this.state;
52
53
  const { onChange } = this.props;
53
54
 
@@ -57,26 +58,26 @@ export default class CustomStyleConfigRenderer extends React.Component<
57
58
  } catch (error) {
58
59
  message.error('保存配置失败');
59
60
  }
60
- };
61
+ }
61
62
 
62
- handleModalCancel = () => {
63
+ handleModalCancel() {
63
64
  // 取消时恢复原始值
64
65
  const value = this.props.value || {};
65
66
  this.setState({
66
67
  isModalVisible: false,
67
68
  editorValue: value,
68
69
  });
69
- };
70
+ }
70
71
 
71
- showModal = () => {
72
+ showModal() {
72
73
  const value = this.props.value || {};
73
74
  this.setState({
74
75
  isModalVisible: true,
75
76
  editorValue: value,
76
77
  });
77
- };
78
+ }
78
79
 
79
- getDisplayValue = () => {
80
+ getDisplayValue() {
80
81
  const { value } = this.props;
81
82
 
82
83
  if (!value || Object.keys(value).length === 0) {
@@ -84,7 +85,7 @@ export default class CustomStyleConfigRenderer extends React.Component<
84
85
  }
85
86
 
86
87
  return '已配置自定义样式';
87
- };
88
+ }
88
89
 
89
90
  render() {
90
91
  const { disabled, viewStyle, wideScreen, value } = this.props;
@@ -8,7 +8,9 @@ import { xObject } from 'neo-open-api'; // Neo Open API
8
8
 
9
9
  // 引入 neo-ui-common / NeoEvent
10
10
  // @ts-ignore
11
- import { BaseCmp, StatusHoc, NeoEvent } from 'neo-ui-common';
11
+ import { BaseCmp, NeoEvent } from 'neo-ui-common';
12
+
13
+ import { formatCssSpacing } from '../../utils/targetNumber';
12
14
 
13
15
  import './style.scss';
14
16
 
@@ -123,8 +125,10 @@ class TargetNumber extends BaseCmp<TargetNumberProps, TargetNumberState> {
123
125
  error: null,
124
126
  };
125
127
 
126
- // 绑定方法上下文
127
128
  this.loadData = this.loadData.bind(this);
129
+ this.hasValidFieldDesc = this.hasValidFieldDesc.bind(this);
130
+ this.getTargetNumbers = this.getTargetNumbers.bind(this);
131
+ this.formatValue = this.formatValue.bind(this);
128
132
  }
129
133
 
130
134
  componentDidMount() {
@@ -314,20 +318,10 @@ class TargetNumber extends BaseCmp<TargetNumberProps, TargetNumberState> {
314
318
  const padding = paddingMargin.padding || '0';
315
319
  const quantity = paddingMargin.quantity || 'px';
316
320
 
317
- // 应用单位到 margin 和 padding
318
- const formatSpacing = (value: string, unit: string) => {
319
- if (!value || value === '0') return '0';
320
- // 如果值已经包含单位,直接返回;否则添加单位
321
- if (/\d+(px|rem|em|%)$/.test(value.trim())) {
322
- return value;
323
- }
324
- return `${value}${unit}`;
325
- };
326
-
327
- baseStyleObj.margin = formatSpacing(margin, quantity);
321
+ baseStyleObj.margin = formatCssSpacing(margin, quantity);
328
322
  // 如果 padding 为 0,使用默认的 16px(保持原有样式)
329
323
  const finalPadding =
330
- padding === '0' ? '16px' : formatSpacing(padding, quantity);
324
+ padding === '0' ? '16px' : formatCssSpacing(padding, quantity);
331
325
  baseStyleObj.padding = finalPadding;
332
326
 
333
327
  // 数值样式
@@ -436,5 +430,4 @@ class TargetNumber extends BaseCmp<TargetNumberProps, TargetNumberState> {
436
430
  }
437
431
  }
438
432
 
439
- // 使用 StatusHoc 包裹组件,用于支持组件显示隐藏控制
440
- export default StatusHoc(TargetNumber);
433
+ export default TargetNumber;
@@ -0,0 +1,231 @@
1
+ /**
2
+ * 多组件共用的纯工具方法(筛选 where、阶段名、金额展示、NeoBI 请求体等)
3
+ */
4
+
5
+ export interface PropsContext {
6
+ data?: {
7
+ __NeoCurrentUser?: {
8
+ id?: number;
9
+ name?: string | null;
10
+ };
11
+ };
12
+ }
13
+ /** 筛选项转有限数字,无效返回 null(与 filter2chartFilter 等一致) */
14
+ export function toFiniteNumber(v: unknown): number | null {
15
+ if (v == null || v === '') return null;
16
+ if (typeof v === 'number' && Number.isFinite(v)) return v;
17
+ const n = Number(v);
18
+ return Number.isFinite(n) ? n : null;
19
+ }
20
+
21
+ /** 时间区间起止:均为有效数字时返回闭区间 [start, end](毫秒时间戳,与 FilterBar 一致) */
22
+ export function closeRangeFromFilter(
23
+ range: unknown,
24
+ ): { start: number; end: number } | null {
25
+ if (!range || typeof range !== 'object') return null;
26
+ const r = range as { start?: unknown; end?: unknown };
27
+ const start = toFiniteNumber(r.start);
28
+ const end = toFiniteNumber(r.end);
29
+ if (start == null || end == null) return null;
30
+ return { start, end };
31
+ }
32
+
33
+ /** opportunityOwner → 用于 where 的用户 id 列表(字符串避免大整数精度丢失) */
34
+ export function normalizeOwnerIdsForWhere(owner: unknown): string[] {
35
+ if (owner == null || owner === '') return [];
36
+ const raw = Array.isArray(owner) ? owner : [owner];
37
+ const out: string[] = [];
38
+ for (const item of raw) {
39
+ if (item == null || item === '') continue;
40
+ const s = String(item).trim().replace(/,/g, '');
41
+ if (s === '' || !/^-?\d+$/.test(s)) continue;
42
+ out.push(s);
43
+ }
44
+ return out;
45
+ }
46
+
47
+ export function entityTypeIdForWhere(businessType: unknown): string | null {
48
+ if (businessType == null || businessType === '') return null;
49
+ const s = String(businessType).trim();
50
+ if (s === '' || !/^-?\d+$/.test(s.replace(/,/g, ''))) return null;
51
+ return s.replace(/,/g, '');
52
+ }
53
+
54
+ /** 从阶段展示名取「第一个 . 之后」的片段,用于匹配 customItem1__c 等 */
55
+ export function extractStageKeyFromStageName(stageName: string): string {
56
+ const s = String(stageName ?? '').trim();
57
+ const i = s.indexOf('.');
58
+ if (i < 0) return s;
59
+ return s.slice(i + 1).trim();
60
+ }
61
+
62
+ /** 商机行等:空或无法解析时为 0 */
63
+ export function parseNumberOrZero(raw: unknown): number {
64
+ if (raw === null || raw === undefined || raw === '') return 0;
65
+ const n =
66
+ typeof raw === 'number'
67
+ ? raw
68
+ : parseFloat(String(raw).replace(/,/g, '').trim());
69
+ return Number.isFinite(n) ? n : 0;
70
+ }
71
+
72
+ /** 阈值配置等:空或无法解析时为 NaN */
73
+ export function parseNumberOrNaN(raw: unknown): number {
74
+ if (raw === null || raw === undefined || raw === '') return NaN;
75
+ const n =
76
+ typeof raw === 'number'
77
+ ? raw
78
+ : parseFloat(String(raw).replace(/,/g, '').trim());
79
+ return Number.isFinite(n) ? n : NaN;
80
+ }
81
+
82
+ /** 展示用金额:$ 前缀;≥1e3 时使用 K / M / B / T 缩写 */
83
+ export function formatAmountDisplay(n: number): string {
84
+ if (!Number.isFinite(n)) return '-';
85
+ const sign = n < 0 ? '-' : '';
86
+ const abs = Math.abs(n);
87
+ if (abs === 0) return '$0';
88
+
89
+ if (abs < 1000) {
90
+ const part = Number.isInteger(abs)
91
+ ? abs.toLocaleString('en-US')
92
+ : abs.toLocaleString('en-US', {
93
+ minimumFractionDigits: 0,
94
+ maximumFractionDigits: 2,
95
+ });
96
+ return `${sign}$${part}`;
97
+ }
98
+
99
+ const tier = Math.min(Math.floor(Math.log10(abs) / 3), 4);
100
+ const suffixes = ['', 'K', 'M', 'B', 'T'] as const;
101
+ const suffix = suffixes[tier];
102
+ const divisor = 1000 ** tier;
103
+ const scaled = abs / divisor;
104
+
105
+ let body: string;
106
+ if (scaled >= 100) body = String(Math.round(scaled));
107
+ else if (scaled >= 10) body = scaled.toFixed(1).replace(/\.0$/, '');
108
+ else body = scaled.toFixed(2).replace(/\.?0+$/, '');
109
+
110
+ return `${sign}$${body}${suffix}`;
111
+ }
112
+
113
+ /** queryDataTask:x-www-form-urlencoded 表单体(filter 以 JSON 字符串传递) */
114
+ export function buildQueryDataTaskFormBody(params: {
115
+ viewId: string;
116
+ userId: string | number;
117
+ type: string;
118
+ filter: Record<string, unknown>;
119
+ }): string {
120
+ const form = new URLSearchParams();
121
+ form.set('viewId', String(params.viewId));
122
+ form.set('userId', String(params.userId));
123
+ form.set('type', params.type);
124
+ form.set('filter', JSON.stringify(params.filter));
125
+ return form.toString();
126
+ }
127
+
128
+ /** 负责人多选默认值:当前登录用户 id(与 __NeoCurrentUser 一致) */
129
+ export function getDefaultOpportunityOwnerIds(
130
+ props: PropsContext,
131
+ ): (number | string)[] {
132
+ // return [1246045]; // 默认用户改成 (Alice)
133
+ const curUser = props.data?.__NeoCurrentUser;
134
+ if (curUser?.id == null || curUser.name == null || String(curUser.name).trim() === '') {
135
+ return [];
136
+ }
137
+ return [curUser.id];
138
+ }
139
+
140
+ /** 负责人多选默认值:当前登录用户 id(与 __NeoCurrentUser 一致) */
141
+ export function getDefaultFilterWhereByProps(
142
+ props: any = {},
143
+ ): any {
144
+ let userId = 1246045; // 默认用户(Alice)
145
+ const curUser = props.data?.__NeoCurrentUser;
146
+ if (curUser?.id) {
147
+ userId = curUser.id;
148
+ }
149
+ const defaultFilter = {
150
+ relation: '1 and 2 and 3',
151
+ filter: [
152
+ {
153
+ modelKey: 'opportunity',
154
+ serialNo: 1,
155
+ fieldKey: 'closeDate',
156
+ type: 'date',
157
+ entityOnlyFilter: 0,
158
+ timeType: 'relative',
159
+ operate: 'eq',
160
+ value: [
161
+ {
162
+ val: 401,
163
+ baseType: 'system',
164
+ },
165
+ ],
166
+ seq: 1,
167
+ },
168
+ {
169
+ modelKey: 'opportunity',
170
+ serialNo: 1,
171
+ fieldKey: 'ownerId',
172
+ type: 'refer',
173
+ referKey: 'user',
174
+ optionType: 'user',
175
+ entityOnlyFilter: 0,
176
+ operate: 'in',
177
+ value: [
178
+ {
179
+ val: userId,
180
+ sub: false,
181
+ source: 'internal',
182
+ specialType: 0,
183
+ },
184
+ ],
185
+ includeNullValue: 0,
186
+ seq: 2,
187
+ },
188
+ {
189
+ modelKey: 'opportunity',
190
+ serialNo: 1,
191
+ fieldKey: 'entityType',
192
+ type: 'refer',
193
+ entityOnlyFilter: 0,
194
+ operate: 'in',
195
+ value: [
196
+ {
197
+ val: 8150459,
198
+ },
199
+ ],
200
+ seq: 3,
201
+ },
202
+ ],
203
+ };
204
+ return defaultFilter;
205
+ }
206
+
207
+ export function getDefaultFilterByProps(
208
+ props: any = {},
209
+ ): any {
210
+ let userId = 1246045; // 默认用户(Alice)
211
+ const curUser = props.data?.__NeoCurrentUser;
212
+ if (curUser?.id) {
213
+ userId = curUser.id;
214
+ }
215
+ const defaultFilter = {
216
+ "closeDate": 401,
217
+ "closeDateCustomRange": {
218
+ "start": 1775059200000,
219
+ "end": 1782835199999
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
229
+ };
230
+ return defaultFilter;
231
+ }