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,341 @@
1
+ /**
2
+ * Pipeline 漏斗 pipelineFunnel 专用(解析表格行、ECharts 配置)
3
+ */
4
+ import * as echarts from 'echarts';
5
+
6
+ import { formatAmountDisplay } from './common';
7
+
8
+ export const FUNNEL_COLORS = [
9
+ '#3b82f6',
10
+ '#22c55e',
11
+ '#f59e0b',
12
+ '#8b5cf6',
13
+ '#ec4899',
14
+ '#06b6d4',
15
+ ];
16
+
17
+ export interface FunnelStage {
18
+ name: string;
19
+ amountNum: number;
20
+ amount: string;
21
+ count: number;
22
+ conversionRate?: string;
23
+ color: string;
24
+ }
25
+
26
+ export function parseAmountToNumber(raw: unknown): number {
27
+ if (raw === null || raw === undefined) return 0;
28
+ const s = String(raw)
29
+ .replace(/,/g, '')
30
+ .replace(/[^\d.-]/g, '');
31
+ const n = parseFloat(s);
32
+ return Number.isFinite(n) ? n : 0;
33
+ }
34
+
35
+ export function formatSharePercent(amount: number, total: number): string {
36
+ if (!total || !Number.isFinite(amount)) return '—';
37
+ return `${((amount / total) * 100).toFixed(1)}%`;
38
+ }
39
+
40
+ export function isTruthyProp(v: unknown): boolean {
41
+ return v === true || v === 'true' || v === 1 || v === '1';
42
+ }
43
+
44
+ /** 与后端阶段名比对时忽略大小写与连续空白 */
45
+ export function isClosedLostStageName(raw: unknown): boolean {
46
+ const n = String(raw ?? '')
47
+ .trim()
48
+ .toLowerCase()
49
+ .replace(/\s+/g, ' ');
50
+ return n === 'closed lost';
51
+ }
52
+
53
+ /** 去掉 Closed Lost 阶段行,保留表头;须在 parseRowsToStages 之前调用,以免计入总额与占比 */
54
+ export function filterOutClosedLostRows(table: unknown[][]): unknown[][] {
55
+ if (!Array.isArray(table) || table.length < 2) return table;
56
+ const header = table[0];
57
+ const rest = table
58
+ .slice(1)
59
+ .filter((row) => !(Array.isArray(row) && isClosedLostStageName(row[0])));
60
+ return [header, ...rest];
61
+ }
62
+
63
+ export function parseRowsToStages(rows: unknown[][]): {
64
+ stages: FunnelStage[];
65
+ totalAmountNum: number;
66
+ } {
67
+ if (!Array.isArray(rows) || rows.length < 2) {
68
+ return { stages: [], totalAmountNum: 0 };
69
+ }
70
+ const dataRows = rows.slice(1);
71
+ const stages: FunnelStage[] = [];
72
+ const amountNums: number[] = [];
73
+ let totalAmountNum = 0;
74
+
75
+ for (let i = 0; i < dataRows.length; i++) {
76
+ const row = dataRows[i];
77
+ if (!Array.isArray(row) || row.length < 4) continue;
78
+
79
+ const name = String(row[0] ?? '');
80
+ const countRaw = row[2];
81
+ const amountNum = parseAmountToNumber(row[3]);
82
+ totalAmountNum += amountNum;
83
+ amountNums.push(amountNum);
84
+
85
+ const countNum = parseInt(String(countRaw).replace(/\D/g, ''), 10);
86
+ const count = Number.isFinite(countNum) ? countNum : 0;
87
+
88
+ stages.push({
89
+ name,
90
+ amountNum,
91
+ amount: formatAmountDisplay(amountNum),
92
+ count,
93
+ color: FUNNEL_COLORS[i % FUNNEL_COLORS.length],
94
+ });
95
+ }
96
+
97
+ for (let j = 0; j < stages.length; j++) {
98
+ stages[j].conversionRate = formatSharePercent(
99
+ amountNums[j],
100
+ totalAmountNum,
101
+ );
102
+ }
103
+
104
+ return { stages, totalAmountNum };
105
+ }
106
+
107
+ export function funnelLayerValue(index: number, total: number): number {
108
+ return Math.max(total - index, 1);
109
+ }
110
+
111
+ export function funnelValueForStage(
112
+ stage: FunnelStage,
113
+ index: number,
114
+ stageCount: number,
115
+ useClassicFunnelShape: boolean,
116
+ ): number {
117
+ if (useClassicFunnelShape) {
118
+ return funnelLayerValue(index, stageCount);
119
+ }
120
+ const v = stage.amountNum;
121
+ if (Number.isFinite(v) && v > 0) return v;
122
+ return 0;
123
+ }
124
+
125
+ /** 经典漏斗:宽度仍由 value(顺序)控制;层高按金额占比分配(与 series.gap 一致,单位为 px) */
126
+ export function classicFunnelLayerHeightPercents(
127
+ amountNums: number[],
128
+ viewHeightPx: number,
129
+ gapPx: number,
130
+ ): string[] {
131
+ const n = amountNums.length;
132
+ if (n === 0) return [];
133
+ const h = Math.max(viewHeightPx, 1);
134
+ const factor = (h - gapPx * Math.max(n - 1, 0)) / h;
135
+ const positives = amountNums.map((v) => (Number.isFinite(v) && v > 0 ? v : 0));
136
+ const sum = positives.reduce((a, v) => a + v, 0);
137
+ if (sum <= 0) {
138
+ const even = (100 / n) * factor;
139
+ return Array(n).fill(`${even}%`);
140
+ }
141
+ return positives.map((v) => `${(100 * (v / sum)) * factor}%`);
142
+ }
143
+
144
+ export interface BuildFunnelChartOptionParams {
145
+ /** 容器高度(px),经典模式下用于计算各层 height 百分比;变化时应重新 setOption */
146
+ chartViewHeightPx?: number;
147
+ funnelGap?: number;
148
+ }
149
+
150
+ export function buildFunnelChartOption(
151
+ stages: FunnelStage[],
152
+ useClassicFunnelShape: boolean,
153
+ params?: BuildFunnelChartOptionParams,
154
+ ): echarts.EChartsOption {
155
+ const n = stages.length;
156
+ const values = stages.map((s, i) =>
157
+ funnelValueForStage(s, i, n, useClassicFunnelShape),
158
+ );
159
+ const funnelMax = useClassicFunnelShape
160
+ ? Math.max(n, 1)
161
+ : Math.max(...values, 1);
162
+
163
+ const gap = params?.funnelGap ?? 2;
164
+ const viewH = params?.chartViewHeightPx;
165
+ const classicHeights =
166
+ useClassicFunnelShape && viewH != null && viewH > 0
167
+ ? classicFunnelLayerHeightPercents(
168
+ stages.map((s) => s.amountNum),
169
+ viewH,
170
+ gap,
171
+ )
172
+ : null;
173
+
174
+ const coloredData = stages.map((s, i) => ({
175
+ name: s.name,
176
+ value: values[i],
177
+ itemStyle: {
178
+ color: s.color,
179
+ ...(classicHeights?.[i] ? { height: classicHeights[i] } : {}),
180
+ },
181
+ }));
182
+
183
+ const alignData = stages.map((s, i) => ({
184
+ name: s.name,
185
+ value: values[i],
186
+ ...(classicHeights?.[i]
187
+ ? { itemStyle: { height: classicHeights[i] } }
188
+ : {}),
189
+ }));
190
+
191
+ const labelLineStyle = {
192
+ length: 28,
193
+ lineStyle: {
194
+ width: 1,
195
+ color: '#d0d0d0',
196
+ type: 'solid' as const,
197
+ },
198
+ };
199
+
200
+ const labelLayoutLeft = () => ({
201
+ x: 0,
202
+ align: 'left' as const,
203
+ dx: 4,
204
+ });
205
+
206
+ const labelLayoutRight = () => ({
207
+ x: '100%',
208
+ align: 'right' as const,
209
+ dx: -6,
210
+ });
211
+
212
+ const funnelLayout = {
213
+ left: '12%',
214
+ top: 4,
215
+ bottom: 4,
216
+ width: '76%',
217
+ min: 0,
218
+ max: funnelMax,
219
+ minSize: '0%',
220
+ maxSize: '100%',
221
+ sort: 'none' as const,
222
+ gap: 1,
223
+ };
224
+
225
+ return {
226
+ backgroundColor: 'transparent',
227
+ legend: { show: false },
228
+ tooltip: {
229
+ trigger: 'item',
230
+ backgroundColor: 'rgba(0, 0, 0, 0.8)',
231
+ borderColor: '#333',
232
+ textStyle: { color: '#fff' },
233
+ formatter: (params: unknown) => {
234
+ const p = params as { dataIndex?: number; seriesName?: string };
235
+ const idx = p.dataIndex ?? 0;
236
+ const st = stages[idx];
237
+ if (!st) return '';
238
+ return [
239
+ `${st.name}`,
240
+ `Percentage: ${st.conversionRate ?? '—'}`,
241
+ `Amount: ${st.amount}`,
242
+ `Quantity: ${st.count}`,
243
+ ].join('<br/>');
244
+ },
245
+ },
246
+ series: [
247
+ {
248
+ name: 'Pipeline',
249
+ type: 'funnel',
250
+ z: 1,
251
+ ...funnelLayout,
252
+ itemStyle: {
253
+ borderColor: '#fff',
254
+ borderWidth: 1,
255
+ },
256
+ emphasis: {
257
+ itemStyle: {
258
+ shadowBlur: 10,
259
+ shadowColor: 'rgba(0, 0, 0, 0.15)',
260
+ },
261
+ },
262
+ label: {
263
+ show: true,
264
+ position: 'left',
265
+ color: '#888',
266
+ fontSize: 11,
267
+ formatter: (p: { dataIndex?: number }) => {
268
+ const idx = typeof p.dataIndex === 'number' ? p.dataIndex : 0;
269
+ return stages[idx]?.conversionRate ?? '—';
270
+ },
271
+ },
272
+ labelLine: {
273
+ show: true,
274
+ ...labelLineStyle,
275
+ },
276
+ labelLayout: labelLayoutLeft,
277
+ data: coloredData,
278
+ },
279
+ {
280
+ name: 'PipelineLabels',
281
+ type: 'funnel',
282
+ z: 2,
283
+ animation: false,
284
+ animationDurationUpdate: 0,
285
+ ...funnelLayout,
286
+ itemStyle: {
287
+ color: 'rgba(0,0,0,0)',
288
+ borderWidth: 0,
289
+ },
290
+ emphasis: { disabled: true },
291
+ label: {
292
+ show: true,
293
+ position: 'right',
294
+ color: '#555',
295
+ fontSize: 11,
296
+ formatter: (p: { dataIndex?: number }) => {
297
+ const idx = typeof p.dataIndex === 'number' ? p.dataIndex : 0;
298
+ const st = stages[idx];
299
+ return st ? `${st.amount} / ${st.count}` : '';
300
+ },
301
+ },
302
+ labelLine: {
303
+ show: true,
304
+ ...labelLineStyle,
305
+ },
306
+ labelLayout: labelLayoutRight,
307
+ data: alignData,
308
+ },
309
+ {
310
+ name: 'PipelineName',
311
+ type: 'funnel',
312
+ z: 3,
313
+ silent: true,
314
+ animation: false,
315
+ animationDurationUpdate: 0,
316
+ tooltip: { show: false },
317
+ ...funnelLayout,
318
+ itemStyle: {
319
+ color: 'rgba(0,0,0,0)',
320
+ borderWidth: 0,
321
+ },
322
+ emphasis: { disabled: true },
323
+ label: {
324
+ show: true,
325
+ position: 'inside',
326
+ color: '#fff',
327
+ fontSize: 12,
328
+ fontWeight: 600,
329
+ textBorderColor: 'rgba(0,0,0,0.4)',
330
+ textBorderWidth: 1,
331
+ formatter: (p: { name?: string; dataIndex?: number }) => {
332
+ const idx = typeof p.dataIndex === 'number' ? p.dataIndex : 0;
333
+ return stages[idx]?.name ?? p.name ?? '';
334
+ },
335
+ },
336
+ labelLine: { show: false },
337
+ data: alignData,
338
+ },
339
+ ],
340
+ };
341
+ }
@@ -1,4 +1,5 @@
1
- import axiosFetcher from '$utils/axiosFetcher';
1
+ // @ts-nocheck
2
+ import { request as axiosFetcher } from 'neo-open-api';
2
3
 
3
4
  /**
4
5
  * 这里存放通用查询类 Open API
@@ -21,12 +22,12 @@ function normalizeWhere(where: unknown): string {
21
22
  return '';
22
23
  }
23
24
 
24
- // 获取业务对象数据列表
25
- export const queryXObjectData = async (options?: any) => {
26
- const apiUrl = '/rest/data/v2/query';
25
+ // 根据 sql 查询 BI 数据
26
+ export const queryByCustomSQL = async (options?: any) => {
27
+ const apiUrl = '/rest/neobi/v2.0/query/queryByCustomSQL';
27
28
  const curOptions = options || {};
28
29
  const xObjectApiKey = curOptions.xObjectApiKey || '';
29
- const fields = curOptions.fields || [];
30
+ const fields = Object.assign([], curOptions.fields || []);
30
31
  const page = curOptions.page || 1;
31
32
  const pageSize = curOptions.pageSize || 10;
32
33
 
@@ -60,34 +61,38 @@ export const queryXObjectData = async (options?: any) => {
60
61
  * `where` 可为字符串,或字符串数组(多项默认以 and 连接,等价于手写 `a and b`)。
61
62
  */
62
63
  const whereClause = normalizeWhere(curOptions.where);
63
- console.log('whereClause:', whereClause);
64
+
64
65
  if (whereClause) {
65
66
  querySql += ` where ${whereClause}`;
66
67
  }
67
68
 
68
69
  if (curOptions.page || curOptions.pageSize) {
69
70
  // 添加分页限制
70
- querySql += ` limit ${pageSize} offset ${offset}`;
71
+ querySql += ` limit ${offset},${pageSize}`;
71
72
  }
72
73
 
74
+ const querySqlForm = new URLSearchParams();
75
+ querySqlForm.set('sqlObject', querySql);
76
+
73
77
  try {
74
78
  const config = {
75
79
  url: apiUrl,
76
- method: 'GET',
77
- data: {
78
- q: querySql,
80
+ method: 'POST',
81
+ data: querySqlForm.toString(),
82
+ headers: {
83
+ 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
79
84
  },
80
85
  };
81
86
 
82
87
  const resultData = await axiosFetcher(config);
83
88
 
84
89
  if (resultData.code === 200) {
85
- const { records, totalSize } = resultData.result || {};
90
+ const records = resultData.data || [];
86
91
  return {
87
92
  status: true,
88
93
  code: resultData.code,
89
94
  msg: resultData.msg || '获取业务对象数据列表成功',
90
- totalSize,
95
+ totalSize: records.length,
91
96
  data: records || [],
92
97
  };
93
98
  }
@@ -109,4 +114,4 @@ export const queryXObjectData = async (options?: any) => {
109
114
  }
110
115
  };
111
116
 
112
- export default queryXObjectData;
117
+ export default queryByCustomSQL;
@@ -0,0 +1,22 @@
1
+ // @ts-nocheck
2
+ import debounce from 'lodash/debounce';
3
+
4
+ /** 组件内数据请求防抖间隔(毫秒),用于合并短时间内的重复触发 */
5
+ export const REQUEST_DEBOUNCE_MS = 280;
6
+
7
+ /** lodash debounce 实例(避免依赖 @types/lodash) */
8
+ export type DebouncedRequestFn = {
9
+ (): void;
10
+ cancel(): void;
11
+ flush(): void;
12
+ };
13
+
14
+ /**
15
+ * 尾部防抖:连续触发时仅在停顿后执行一次,适合 filter / props 连更新场景。
16
+ */
17
+ export function createRequestDebounce(
18
+ fn: () => void,
19
+ wait: number = REQUEST_DEBOUNCE_MS,
20
+ ): DebouncedRequestFn {
21
+ return debounce(fn, wait) as DebouncedRequestFn;
22
+ }