neo-cmp-cli 1.13.16 → 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 (182) 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/env.js +1 -1
  5. package/dist/neo/neoLogin.js +1 -1
  6. package/dist/neo/pushCmp.js +1 -1
  7. package/dist/package.json.js +1 -1
  8. package/package.json +3 -2
  9. package/template/antd-custom-cmp-template/package.json +1 -1
  10. package/template/asset-manage-template/docs/README.md +1 -232
  11. package/template/asset-manage-template/package.json +2 -2
  12. package/template/echarts-custom-cmp-template/package.json +1 -1
  13. package/template/empty-custom-cmp-template/package.json +2 -2
  14. package/template/map-custom-cmp-template/package.json +1 -1
  15. package/template/neo-bi-cmps/neo.config.js +7 -1
  16. package/template/neo-bi-cmps/package.json +8 -7
  17. package/template/neo-bi-cmps/public/403.html +77 -0
  18. package/template/neo-bi-cmps/public/demo.html +2453 -0
  19. package/template/neo-bi-cmps/src/assets/icon/barChart.svg +1 -0
  20. package/template/neo-bi-cmps/src/assets/icon/card.svg +1 -0
  21. package/template/neo-bi-cmps/src/assets/icon/filter.svg +1 -0
  22. package/template/neo-bi-cmps/src/assets/icon/funnel.svg +1 -0
  23. package/template/neo-bi-cmps/src/assets/icon/tab.svg +1 -0
  24. package/template/neo-bi-cmps/src/components/filterBar__c/README.md +3 -14
  25. package/template/neo-bi-cmps/src/components/filterBar__c/common.scss +29 -0
  26. package/template/neo-bi-cmps/src/components/filterBar__c/index.tsx +668 -146
  27. package/template/neo-bi-cmps/src/components/filterBar__c/model.ts +26 -48
  28. package/template/neo-bi-cmps/src/components/filterBar__c/style.scss +46 -139
  29. package/template/neo-bi-cmps/src/components/targetNumber__c/customStyleConfig/index.tsx +11 -10
  30. package/template/neo-bi-cmps/src/components/targetNumber__c/index.tsx +9 -16
  31. package/template/neo-bi-cmps/src/components/targetNumber__c/model.ts +1 -1
  32. package/template/neo-bi-cmps/src/utils/common.ts +231 -0
  33. package/template/neo-bi-cmps/src/utils/filter2chartFilter.ts +268 -0
  34. package/template/neo-bi-cmps/src/utils/filterBar.ts +140 -0
  35. package/template/neo-bi-cmps/src/utils/pipelineFunnel.ts +341 -0
  36. package/template/{neo-h5-cmps/src/utils/queryObjectData.ts → neo-bi-cmps/src/utils/queryByCustomSQL.ts} +18 -13
  37. package/template/neo-bi-cmps/src/utils/requestDebounce.ts +22 -0
  38. package/template/neo-bi-cmps/src/utils/simpleTable.tsx +344 -0
  39. package/template/neo-bi-cmps/src/utils/stageSwitch.ts +15 -0
  40. package/template/neo-bi-cmps/src/utils/stageTimeChart.ts +90 -0
  41. package/template/neo-bi-cmps/src/utils/targetNumber.ts +12 -0
  42. package/template/neo-custom-cmp-template/docs/README.md +0 -231
  43. package/template/neo-custom-cmp-template/package.json +2 -2
  44. package/template/neo-h5-cmps/package.json +2 -2
  45. package/template/neo-h5-cmps/src/components/entityList__c/index.tsx +1 -2
  46. package/template/neo-h5-cmps/src/components/entityTabs__c/index.tsx +1 -1
  47. package/template/neo-h5-cmps/src/components/globalSearchInput__c/index.tsx +1 -1
  48. package/template/neo-h5-cmps/src/components/openChatPageBtn__c/index.tsx +1 -2
  49. package/template/neo-order-cmps/package.json +2 -2
  50. package/template/neo-pipeline-cmps/.prettierrc.js +12 -0
  51. package/template/neo-pipeline-cmps/@types/neo-ui-common.d.ts +36 -0
  52. package/template/neo-pipeline-cmps/README.md +99 -0
  53. package/template/neo-pipeline-cmps/commitlint.config.js +59 -0
  54. package/template/neo-pipeline-cmps/neo.config.js +135 -0
  55. package/template/neo-pipeline-cmps/package.json +66 -0
  56. package/template/neo-pipeline-cmps/public/403.html +77 -0
  57. package/template/neo-pipeline-cmps/public/css/base.css +283 -0
  58. package/template/neo-pipeline-cmps/public/demo.html +2453 -0
  59. package/template/neo-pipeline-cmps/public/scripts/app/bluebird.js +6679 -0
  60. package/template/neo-pipeline-cmps/public/template.html +13 -0
  61. package/template/neo-pipeline-cmps/src/assets/css/common.scss +127 -0
  62. package/template/neo-pipeline-cmps/src/assets/css/mixin.scss +47 -0
  63. package/template/neo-pipeline-cmps/src/assets/icon/barChart.svg +1 -0
  64. package/template/neo-pipeline-cmps/src/assets/icon/card.svg +1 -0
  65. package/template/neo-pipeline-cmps/src/assets/icon/filter.svg +1 -0
  66. package/template/neo-pipeline-cmps/src/assets/icon/funnel.svg +1 -0
  67. package/template/neo-pipeline-cmps/src/assets/icon/tab.svg +1 -0
  68. package/template/neo-pipeline-cmps/src/assets/img/AIBtn.gif +0 -0
  69. package/template/neo-pipeline-cmps/src/assets/img/NeoCRM.jpg +0 -0
  70. package/template/neo-pipeline-cmps/src/assets/img/aiLogo.png +0 -0
  71. package/template/neo-pipeline-cmps/src/assets/img/card-list.svg +1 -0
  72. package/template/neo-pipeline-cmps/src/assets/img/contact-form.svg +1 -0
  73. package/template/neo-pipeline-cmps/src/assets/img/custom-form.svg +1 -0
  74. package/template/neo-pipeline-cmps/src/assets/img/custom-widget.svg +1 -0
  75. package/template/neo-pipeline-cmps/src/assets/img/data-list.svg +1 -0
  76. package/template/neo-pipeline-cmps/src/assets/img/detail.svg +1 -0
  77. package/template/neo-pipeline-cmps/src/assets/img/favicon.png +0 -0
  78. package/template/neo-pipeline-cmps/src/assets/img/map.svg +1 -0
  79. package/template/neo-pipeline-cmps/src/assets/img/search.svg +1 -0
  80. package/template/neo-pipeline-cmps/src/assets/img/table.svg +1 -0
  81. package/template/neo-pipeline-cmps/src/components/filterBar__c/README.md +24 -0
  82. package/template/neo-pipeline-cmps/src/components/filterBar__c/common.scss +29 -0
  83. package/template/neo-pipeline-cmps/src/components/filterBar__c/index.tsx +731 -0
  84. package/template/neo-pipeline-cmps/src/components/filterBar__c/model.ts +52 -0
  85. package/template/neo-pipeline-cmps/src/components/filterBar__c/style.scss +119 -0
  86. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/README.md +39 -0
  87. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/index.tsx +416 -0
  88. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/model.ts +80 -0
  89. package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/style.scss +83 -0
  90. package/template/neo-pipeline-cmps/src/components/showHealthResult__c/index.tsx +470 -0
  91. package/template/neo-pipeline-cmps/src/components/showHealthResult__c/model.ts +45 -0
  92. package/template/neo-pipeline-cmps/src/components/showHealthResult__c/style.scss +137 -0
  93. package/template/neo-pipeline-cmps/src/components/simpleTable__c/README.md +89 -0
  94. package/template/neo-pipeline-cmps/src/components/simpleTable__c/common.scss +195 -0
  95. package/template/neo-pipeline-cmps/src/components/simpleTable__c/index.tsx +667 -0
  96. package/template/neo-pipeline-cmps/src/components/simpleTable__c/model.ts +124 -0
  97. package/template/neo-pipeline-cmps/src/components/simpleTable__c/style.scss +192 -0
  98. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/README.md +36 -0
  99. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/index.tsx +513 -0
  100. package/template/neo-pipeline-cmps/src/components/stageSwitch__c/model.ts +71 -0
  101. package/template/{neo-bi-cmps → neo-pipeline-cmps}/src/components/stageSwitch__c/style.scss +4 -2
  102. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/README.md +37 -0
  103. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/index.tsx +455 -0
  104. package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/model.ts +106 -0
  105. package/template/{neo-bi-cmps → neo-pipeline-cmps}/src/components/stageTimeChart__c/style.scss +3 -2
  106. package/template/neo-pipeline-cmps/src/utils/common.ts +229 -0
  107. package/template/neo-pipeline-cmps/src/utils/filter2chartFilter.ts +266 -0
  108. package/template/neo-pipeline-cmps/src/utils/filterBar.ts +140 -0
  109. package/template/neo-pipeline-cmps/src/utils/pipelineFunnel.ts +343 -0
  110. package/template/neo-pipeline-cmps/src/utils/queryByCustomSQL.ts +121 -0
  111. package/template/neo-pipeline-cmps/src/utils/requestDebounce.ts +22 -0
  112. package/template/neo-pipeline-cmps/src/utils/simpleTable.tsx +349 -0
  113. package/template/neo-pipeline-cmps/src/utils/stageSwitch.ts +15 -0
  114. package/template/neo-pipeline-cmps/src/utils/stageTimeChart.ts +90 -0
  115. package/template/neo-pipeline-cmps/src/utils/targetNumber.ts +12 -0
  116. package/template/neo-pipeline-cmps/tsconfig.json +40 -0
  117. package/template/neo-web-entity-grid/package.json +2 -2
  118. package/template/neo-web-form/package.json +2 -2
  119. package/template/neo-web-form/src/components/batchAddTable__c/index.tsx +161 -41
  120. package/template/neo-web-form/src/components/batchAddTable__c/model.ts +4 -2
  121. package/template/react-custom-cmp-template/package.json +1 -1
  122. package/template/react-ts-custom-cmp-template/package.json +1 -1
  123. package/template/vue2-custom-cmp-template/package.json +1 -1
  124. package/template/asset-manage-template/src/utils/axiosFetcher.ts +0 -37
  125. package/template/asset-manage-template/src/utils/queryObjectData.ts +0 -112
  126. package/template/asset-manage-template/src/utils/xobjects.ts +0 -162
  127. package/template/neo-bi-cmps/.npmrc copy +0 -1
  128. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/README.md +0 -52
  129. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/index.tsx +0 -183
  130. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/model.ts +0 -90
  131. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/style.scss +0 -218
  132. package/template/neo-bi-cmps/src/components/forecastChart__c/README.md +0 -31
  133. package/template/neo-bi-cmps/src/components/forecastChart__c/index.tsx +0 -158
  134. package/template/neo-bi-cmps/src/components/forecastChart__c/model.ts +0 -40
  135. package/template/neo-bi-cmps/src/components/forecastChart__c/style.scss +0 -154
  136. package/template/neo-bi-cmps/src/components/forecastGrid__c/README.md +0 -36
  137. package/template/neo-bi-cmps/src/components/forecastGrid__c/index.tsx +0 -86
  138. package/template/neo-bi-cmps/src/components/forecastGrid__c/model.ts +0 -62
  139. package/template/neo-bi-cmps/src/components/forecastGrid__c/style.scss +0 -48
  140. package/template/neo-bi-cmps/src/components/gapCloser__c/README.md +0 -24
  141. package/template/neo-bi-cmps/src/components/gapCloser__c/index.tsx +0 -100
  142. package/template/neo-bi-cmps/src/components/gapCloser__c/model.ts +0 -46
  143. package/template/neo-bi-cmps/src/components/gapCloser__c/style.scss +0 -60
  144. package/template/neo-bi-cmps/src/components/kpiCards__c/README.md +0 -35
  145. package/template/neo-bi-cmps/src/components/kpiCards__c/index.tsx +0 -70
  146. package/template/neo-bi-cmps/src/components/kpiCards__c/model.ts +0 -50
  147. package/template/neo-bi-cmps/src/components/kpiCards__c/style.scss +0 -33
  148. package/template/neo-bi-cmps/src/components/oppList__c/README.md +0 -52
  149. package/template/neo-bi-cmps/src/components/oppList__c/index.tsx +0 -285
  150. package/template/neo-bi-cmps/src/components/oppList__c/model.ts +0 -86
  151. package/template/neo-bi-cmps/src/components/oppList__c/style.scss +0 -133
  152. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/README.md +0 -39
  153. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/index.tsx +0 -130
  154. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/model.ts +0 -66
  155. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/style.scss +0 -133
  156. package/template/neo-bi-cmps/src/components/stageSwitch__c/README.md +0 -36
  157. package/template/neo-bi-cmps/src/components/stageSwitch__c/index.tsx +0 -118
  158. package/template/neo-bi-cmps/src/components/stageSwitch__c/model.ts +0 -92
  159. package/template/neo-bi-cmps/src/components/stageTimeChart__c/README.md +0 -37
  160. package/template/neo-bi-cmps/src/components/stageTimeChart__c/index.tsx +0 -126
  161. package/template/neo-bi-cmps/src/components/stageTimeChart__c/model.ts +0 -57
  162. package/template/neo-bi-cmps/src/components/tabSwitch__c/README.md +0 -37
  163. package/template/neo-bi-cmps/src/components/tabSwitch__c/index.tsx +0 -80
  164. package/template/neo-bi-cmps/src/components/tabSwitch__c/model.ts +0 -45
  165. package/template/neo-bi-cmps/src/components/tabSwitch__c/style.scss +0 -37
  166. package/template/neo-bi-cmps/src/utils/axiosFetcher.ts +0 -37
  167. package/template/neo-bi-cmps/src/utils/queryObjectData.ts +0 -76
  168. package/template/neo-bi-cmps/src/utils/xobjects.ts +0 -162
  169. package/template/neo-custom-cmp-template/src/utils/axiosFetcher.ts +0 -37
  170. package/template/neo-custom-cmp-template/src/utils/queryObjectData.ts +0 -112
  171. package/template/neo-custom-cmp-template/src/utils/xobjects.ts +0 -162
  172. package/template/neo-h5-cmps/src/utils/axiosFetcher.ts +0 -37
  173. package/template/neo-h5-cmps/src/utils/xobjects.ts +0 -167
  174. package/template/neo-order-cmps/src/utils/axiosFetcher.ts +0 -37
  175. package/template/neo-order-cmps/src/utils/queryObjectData.ts +0 -112
  176. package/template/neo-order-cmps/src/utils/xobjects.ts +0 -162
  177. package/template/neo-web-entity-grid/src/utils/axiosFetcher.ts +0 -37
  178. package/template/neo-web-entity-grid/src/utils/queryObjectData.ts +0 -112
  179. package/template/neo-web-entity-grid/src/utils/xobjects.ts +0 -167
  180. package/template/neo-web-form/src/utils/axiosFetcher.ts +0 -37
  181. package/template/neo-web-form/src/utils/queryObjectData.ts +0 -112
  182. package/template/neo-web-form/src/utils/xobjects.ts +0 -167
@@ -0,0 +1,268 @@
1
+ /**
2
+ * 过滤条件格式化
3
+ * 将筛选栏组件得到的过滤条件格式化为接口需要的格式。
4
+ *
5
+ * 数据转换规则:
6
+ 1. closeDate
7
+
8
+ 非 custom:用 toFiniteNumber 把选项值(如 201 / "201")转成数字,timeType: 'relative',value: [{ val, baseType: 'system' }]。
9
+ custom:读取 closeDateCustomRange.start / end,二者均为有效数字时,timeType: 'absolute',value 为两条 { val, close: 1 };缺区间则不生成该项。
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 }。
14
+
15
+ 3. businessType → entityType
16
+ 有值且能转成数字时,生成 refer + value: [{ val }];空字符串不传 entityType。
17
+
18
+ 4. relation
19
+ 按最终条目的 seq 拼成 "1 and 2 and 3";没有任何条件时为 '',filter 为 []。
20
+
21
+ *
22
+ * 例如:
23
+ * 筛选栏组件得到的过滤条件:
24
+ {
25
+ "closeDate": "custom",
26
+ "closeDateCustomRange": {
27
+ "start": 1775577600000,
28
+ "end": 1777996799999
29
+ },
30
+ "opportunityOwner": ["1255807", 2088134315786370],
31
+ "businessType": "8150459",
32
+ "changesSince": "Custom",
33
+ "changesSinceCustomTime": 1776268800000
34
+ }
35
+
36
+ 接口需要的格式:
37
+ {
38
+ "relation": "1 and 2 and 3",
39
+ "filter": [
40
+ {
41
+ "seq": 1,
42
+ "fieldKey": "closeDate",
43
+ "modelKey": "opportunity",
44
+ "serialNo": 1,
45
+ "type": "date",
46
+ "entityOnlyFilter": 0,
47
+ "timeType": "relative",
48
+ "operate": "eq",
49
+ "value": [
50
+ {
51
+ "val": 101,
52
+ "baseType": "system"
53
+ }
54
+ ]
55
+ },
56
+ {
57
+ "seq": 2,
58
+ "fieldKey": "ownerId",
59
+ "modelKey": "opportunity",
60
+ "serialNo": 1,
61
+ "type": "refer",
62
+ "referKey": "user",
63
+ "optionType": "user",
64
+ "entityOnlyFilter": 0,
65
+ "operate": "in",
66
+ "value": [
67
+ {
68
+ "val": 1255807,
69
+ "sub": false,
70
+ "source": "internal",
71
+ "specialType": 0
72
+ },
73
+ {
74
+ "val": 2088134315786370,
75
+ "sub": false,
76
+ "source": "internal",
77
+ "specialType": 0
78
+ }
79
+ ],
80
+ "includeNullValue": 0
81
+ },
82
+ {
83
+ "seq": 3,
84
+ "fieldKey": "entityType",
85
+ "modelKey": "opportunity",
86
+ "serialNo": 1,
87
+ "type": "refer",
88
+ "entityOnlyFilter": 0,
89
+ "operate": "in",
90
+ "value": [
91
+ {
92
+ "val": 8150459
93
+ }
94
+ ]
95
+ }
96
+ ]
97
+ }
98
+
99
+ 如果是 closeDate 为 custom,则需要将 closeDateCustomRange 格式化为接口需要的格式
100
+ {
101
+ "seq": 3,
102
+ "fieldKey": "closeDate",
103
+ "modelKey": "opportunity",
104
+ "serialNo": 1,
105
+ "type": "date",
106
+ "entityOnlyFilter": 0,
107
+ "timeType": "absolute",
108
+ "operate": "eq",
109
+ "value": [
110
+ {
111
+ "val": 1777305600000,
112
+ "close": 1
113
+ },
114
+ {
115
+ "val": 1780156799999,
116
+ "close": 1
117
+ }
118
+ ]
119
+ }
120
+ */
121
+
122
+ import { toFiniteNumber } from './common';
123
+
124
+ const MODEL_KEY = 'opportunity';
125
+ const SERIAL_NO = 1;
126
+
127
+ type ChartFilterItem = {
128
+ seq: number;
129
+ fieldKey: string;
130
+ modelKey: string;
131
+ serialNo: number;
132
+ type: string;
133
+ entityOnlyFilter: number;
134
+ operate: string;
135
+ value: unknown[];
136
+ timeType?: string;
137
+ referKey?: string;
138
+ optionType?: string;
139
+ includeNullValue?: number;
140
+ };
141
+
142
+ export interface ChartFilterPayload {
143
+ relation: string;
144
+ filter: ChartFilterItem[];
145
+ }
146
+
147
+ function closeDateChunk(
148
+ filter: Record<string, unknown>,
149
+ ): Omit<ChartFilterItem, 'seq'> | null {
150
+ const raw = filter.closeDate;
151
+ const isCustom = String(raw ?? '').toLowerCase() === 'custom';
152
+
153
+ if (isCustom) {
154
+ const range = filter.closeDateCustomRange as
155
+ | { start?: unknown; end?: unknown }
156
+ | undefined;
157
+ const start = toFiniteNumber(range?.start);
158
+ const end = toFiniteNumber(range?.end);
159
+ if (start == null || end == null) return null;
160
+ return {
161
+ modelKey: MODEL_KEY,
162
+ serialNo: SERIAL_NO,
163
+ fieldKey: 'closeDate',
164
+ type: 'date',
165
+ entityOnlyFilter: 0,
166
+ timeType: 'absolute',
167
+ operate: 'eq',
168
+ value: [
169
+ { val: start, close: 1 },
170
+ { val: end, close: 1 },
171
+ ],
172
+ };
173
+ }
174
+
175
+ const n = toFiniteNumber(raw);
176
+ if (n == null) return null;
177
+ return {
178
+ modelKey: MODEL_KEY,
179
+ serialNo: SERIAL_NO,
180
+ fieldKey: 'closeDate',
181
+ type: 'date',
182
+ entityOnlyFilter: 0,
183
+ timeType: 'relative',
184
+ operate: 'eq',
185
+ value: [{ val: n, baseType: 'system' }],
186
+ };
187
+ }
188
+
189
+ const ownerUserValueItem = (val: number) => ({
190
+ val,
191
+ sub: false as const,
192
+ source: 'internal' as const,
193
+ specialType: 0,
194
+ });
195
+
196
+ /** 从 opportunityOwner(单值或 id 数组)解析出有效的用户 id 列表 */
197
+ function normalizeOwnerIds(owner: unknown): number[] {
198
+ if (owner == null || owner === '') return [];
199
+ const raw = Array.isArray(owner) ? owner : [owner];
200
+ const out: number[] = [];
201
+ for (const item of raw) {
202
+ if (item == null || item === '') continue;
203
+ const n = toFiniteNumber(item);
204
+ if (n != null) out.push(n);
205
+ }
206
+ return out;
207
+ }
208
+
209
+ function ownerChunk(
210
+ filter: Record<string, unknown>,
211
+ ): Omit<ChartFilterItem, 'seq'> | null {
212
+ const ids = normalizeOwnerIds(filter.opportunityOwner);
213
+ if (ids.length === 0) return null;
214
+ return {
215
+ modelKey: MODEL_KEY,
216
+ serialNo: SERIAL_NO,
217
+ fieldKey: 'ownerId',
218
+ type: 'refer',
219
+ referKey: 'user',
220
+ optionType: 'user',
221
+ entityOnlyFilter: 0,
222
+ operate: 'in',
223
+ value: ids.map(ownerUserValueItem),
224
+ includeNullValue: 0,
225
+ };
226
+ }
227
+
228
+ function entityTypeChunk(
229
+ filter: Record<string, unknown>,
230
+ ): Omit<ChartFilterItem, 'seq'> | null {
231
+ const busi = filter.businessType;
232
+ if (busi == null || busi === '') return null;
233
+ const val = toFiniteNumber(busi);
234
+ if (val == null) return null;
235
+ return {
236
+ modelKey: MODEL_KEY,
237
+ serialNo: SERIAL_NO,
238
+ fieldKey: 'entityType',
239
+ type: 'refer',
240
+ entityOnlyFilter: 0,
241
+ operate: 'in',
242
+ value: [{ val }],
243
+ };
244
+ }
245
+
246
+ /**
247
+ * 将筛选栏 payload 转为图表/接口 filter 结构;仅映射 closeDate、ownerId、entityType。
248
+ */
249
+ export const filter2chartFilter = (filter: any): ChartFilterPayload => {
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'>[];
256
+
257
+ const filterOut: ChartFilterItem[] = parts.map((p, i) => ({
258
+ ...p,
259
+ seq: i + 1,
260
+ }));
261
+
262
+ const relation =
263
+ filterOut.length === 0
264
+ ? ''
265
+ : filterOut.map((x) => String(x.seq)).join(' and ');
266
+
267
+ return { relation, filter: filterOut };
268
+ };
@@ -0,0 +1,140 @@
1
+ /**
2
+ * 筛选栏 filterBar 专用工具方法
3
+ */
4
+ import moment from 'moment';
5
+
6
+ export interface FilterOption {
7
+ value: string | number;
8
+ label: string;
9
+ /** 业务类型等接口项上的 apiKey,用于与 defaultBusiType 配置对齐 */
10
+ apiKey?: string;
11
+ }
12
+
13
+ /** 自定义日期区间:起止为 Unix 毫秒时间戳(日为本地 startOfDay / endOfDay) */
14
+ export interface TimestampRange {
15
+ start?: number;
16
+ end?: number;
17
+ }
18
+
19
+ /** 规范化下拉项的 value / label */
20
+ export function normalizeOptions(list?: FilterOption[]): FilterOption[] {
21
+ if (!Array.isArray(list) || list.length === 0) return [];
22
+ return list.map((o) => ({
23
+ value: o.value,
24
+ label: String(o.label ?? o.value),
25
+ }));
26
+ }
27
+
28
+ /** Changes Since 下拉默认项 */
29
+ export function defaultChangesSinceOptions(): FilterOption[] {
30
+ return [
31
+ { value: 'Start of the Period', label: 'Start of the Period' },
32
+ { value: 'Custom', label: 'Custom' },
33
+ ];
34
+ }
35
+
36
+ /** RangePicker 选中的两天转为起止时间戳(含当日) */
37
+ export function momentRangeToTimestamps(dates: any): TimestampRange | null {
38
+ const m0 = dates?.[0];
39
+ const m1 = dates?.[1];
40
+ if (!m0 || !m1) return null;
41
+ return {
42
+ start: moment(m0).startOf('day').valueOf(),
43
+ end: moment(m1).endOf('day').valueOf(),
44
+ };
45
+ }
46
+
47
+ /**
48
+ * 将 Close Date 相对周期编码转为本地自然日的起止时间戳(起点 0 点,终点 23:59:59.999)。
49
+ * 约定:百位 2=本周(iso 周)、3=本月、4=本季度(如 201/301/401 及同段其它编码)。
50
+ */
51
+ export function relativeCloseDateRangeFromCode(
52
+ encoded: number | string,
53
+ ): TimestampRange | null {
54
+ const curEncoded = typeof encoded === 'number' ? encoded : Number(encoded);
55
+ if (!Number.isFinite(curEncoded)) return null;
56
+ const now = moment();
57
+ if (curEncoded === 201) {
58
+ // This Week
59
+ return {
60
+ start: now.clone().startOf('isoWeek').startOf('day').valueOf(),
61
+ end: now.clone().endOf('isoWeek').endOf('day').valueOf(),
62
+ };
63
+ }
64
+ if (curEncoded === 301) {
65
+ // This Month(起点为月初次日 0 点)
66
+ return {
67
+ start: now
68
+ .clone()
69
+ .startOf('month')
70
+ .startOf('day')
71
+ .add(1, 'day')
72
+ .valueOf(),
73
+ end: now.clone().endOf('month').endOf('day').valueOf(),
74
+ };
75
+ }
76
+ if (curEncoded === 401) {
77
+ // This Quarter(起点为季首次日 0 点)
78
+ return {
79
+ start: now
80
+ .clone()
81
+ .startOf('quarter')
82
+ .startOf('day')
83
+ .add(1, 'day')
84
+ .valueOf(),
85
+ end: now.clone().endOf('quarter').endOf('day').valueOf(),
86
+ };
87
+ }
88
+ return null;
89
+ }
90
+
91
+ /** 将 user 实体查询结果转为负责人下拉项(按 id 去重) */
92
+ export function parseUserRecordsToOwnerOptions(records: any): FilterOption[] {
93
+ const arr = Array.isArray(records) ? records : [];
94
+ const seen = new Set<string>();
95
+ const out: FilterOption[] = [];
96
+ for (const row of arr) {
97
+ if (row == null || typeof row !== 'object') continue;
98
+ const id = row.id;
99
+ const name = row.name != null ? String(row.name) : '';
100
+ if (!id || !name || seen.has(id)) continue;
101
+ seen.add(id);
102
+ out.push({ value: id, label: name });
103
+ }
104
+ return out;
105
+ }
106
+
107
+ /** 从业务类型接口响应中取出列表数组 */
108
+ export function getBusinessTypeRawList(res: any): any[] {
109
+ const raw = res?.data !== undefined ? res.data : res;
110
+ const arr = Array.isArray(raw)
111
+ ? raw
112
+ : raw?.records || raw?.items || raw?.list || raw?.data || [];
113
+ return Array.isArray(arr) ? arr : [];
114
+ }
115
+
116
+ /** 解析业务类型接口结果为下拉选项(保留 apiKey 供默认项匹配) */
117
+ export function parseBusinessTypes(res: any): FilterOption[] {
118
+ const arr = getBusinessTypeRawList(res);
119
+ return arr
120
+ .map((x: any) => ({
121
+ value: x.id ?? x.apiKey ?? x.value,
122
+ label: String(x.label ?? x.name ?? x.title ?? x.apiKey ?? ''),
123
+ apiKey: x.apiKey != null ? String(x.apiKey) : undefined,
124
+ }))
125
+ .filter((o) => o.value != null && o.value !== '' && o.label);
126
+ }
127
+
128
+ /**
129
+ * 在业务类型选项中按 apiKey === defaultBusiType 解析默认选中值(与下拉 value 一致,一般为 id)
130
+ */
131
+ export function resolveDefaultBusinessTypeValue(
132
+ options: FilterOption[],
133
+ defaultBusiTypeKey?: string,
134
+ ): string | number {
135
+ if (defaultBusiTypeKey == null || defaultBusiTypeKey === '') return '';
136
+ const key = String(defaultBusiTypeKey);
137
+ const hit = options.find((o) => o.apiKey != null && o.apiKey === key);
138
+ if (!hit) return '';
139
+ return hit.value;
140
+ }