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,70 +0,0 @@
1
- /**
2
- * @file KPI指标卡片组件
3
- * @description 展示Quota、Closed、Forecast、AI Forecast等核心KPI指标
4
- */
5
- import * as React from 'react';
6
- // @ts-ignore
7
- import { BaseCmp, StatusHoc, NeoEvent } from 'neo-ui-common';
8
-
9
- import './style.scss';
10
-
11
- interface KpiItem {
12
- label: string;
13
- value: string;
14
- subLabel?: string;
15
- subDirection?: 'negative' | 'positive';
16
- }
17
-
18
- interface KpiCardsProps {
19
- items?: KpiItem[];
20
- columns?: number;
21
- className?: string;
22
- style?: React.CSSProperties;
23
- }
24
-
25
- interface KpiCardsState {
26
- loading: boolean;
27
- }
28
-
29
- class KpiCards extends BaseCmp<KpiCardsProps, KpiCardsState> {
30
- constructor(props: KpiCardsProps) {
31
- super(props);
32
- this.state = {
33
- loading: false,
34
- };
35
- }
36
-
37
- componentDidMount() {
38
- console.log('KpiCards 组件挂载');
39
- }
40
-
41
- render() {
42
- const { items = [], columns = 2, className, style } = this.props;
43
-
44
- return (
45
- <div
46
- className={`kpi-cards__c ${className || ''}`}
47
- style={{
48
- ...style,
49
- display: 'grid',
50
- gridTemplateColumns: `repeat(${columns}, 1fr)`,
51
- gap: '8px',
52
- }}
53
- >
54
- {items.map((item, index) => (
55
- <div key={index} className="kpi-card">
56
- <div className="kpi-label">{item.label}</div>
57
- <div className="kpi-value">{item.value}</div>
58
- {item.subLabel && (
59
- <div className={`kpi-sub ${item.subDirection || ''}`}>
60
- {item.subLabel}
61
- </div>
62
- )}
63
- </div>
64
- ))}
65
- </div>
66
- );
67
- }
68
- }
69
-
70
- export default StatusHoc(KpiCards);
@@ -1,50 +0,0 @@
1
- export class KpiCardsModel {
2
- label: string = 'KPI指标卡片';
3
- description: string = '展示Quota、Closed、Forecast、AI Forecast等核心KPI指标';
4
- iconUrl: string = 'https://custom-widgets.bj.bcebos.com/kpiCards.svg';
5
- targetPage: string[] = ['all'];
6
- targetDevice: string = 'all';
7
-
8
- defaultComProps = {
9
- columns: 2,
10
- items: [
11
- { label: 'Quota', value: '$10,000,000' },
12
- {
13
- label: 'Closed',
14
- value: '$3,200,000',
15
- subLabel: 'Gap: $6,800,000',
16
- subDirection: 'negative',
17
- },
18
- {
19
- label: 'Forecast',
20
- value: '$7,500,000',
21
- subLabel: 'Gap: $2,500,000',
22
- subDirection: 'negative',
23
- },
24
- {
25
- label: '✨ AI Forecast',
26
- value: '$6,800,000',
27
- subLabel: 'Gap: $3,200,000',
28
- subDirection: 'negative',
29
- },
30
- ],
31
- };
32
-
33
- functions = [
34
- {
35
- apiKey: 'refreshData',
36
- label: '刷新数据',
37
- helpTextKey: '刷新KPI指标数据',
38
- },
39
- ];
40
-
41
- propsSchema = [
42
- {
43
- type: 'number',
44
- name: 'columns',
45
- label: '列数',
46
- },
47
- ];
48
- }
49
-
50
- export default KpiCardsModel;
@@ -1,33 +0,0 @@
1
- .kpi-cards__c {
2
- .kpi-card {
3
- background: #fff;
4
- border-radius: 8px;
5
- padding: 16px 20px;
6
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
7
-
8
- .kpi-label {
9
- font-size: 12px;
10
- color: #888;
11
- margin-bottom: 4px;
12
- }
13
-
14
- .kpi-value {
15
- font-size: 22px;
16
- font-weight: 700;
17
- }
18
-
19
- .kpi-sub {
20
- font-size: 12px;
21
- color: #999;
22
- margin-top: 4px;
23
-
24
- &.negative {
25
- color: #ef4444;
26
- }
27
-
28
- &.positive {
29
- color: #22c55e;
30
- }
31
- }
32
- }
33
- }
@@ -1,52 +0,0 @@
1
- # OppList 组件
2
-
3
- 商机列表组件,展示商机数据表格,支持排序、筛选、Tab切换等功能。
4
-
5
- ## 使用方式
6
-
7
- ```tsx
8
- import OppList from './components/oppList__c';
9
-
10
- <OppList
11
- title="Opportunity List"
12
- tabs={[
13
- { key: 'watch', label: '✨ Prioritized Deals' },
14
- { key: 'all', label: 'All Opportunities' },
15
- ]}
16
- filterChips={['All (3)', 'Rescue (1)', 'Upgrade (2)']}
17
- columns={['Name', 'Amount', 'Close Date', 'Stage']}
18
- rows={[...]}
19
- onRowClick={(opp) => console.log('Clicked:', opp)}
20
- />
21
- ```
22
-
23
- ## Props
24
-
25
- | 属性 | 说明 | 类型 | 默认值 |
26
- |------|------|------|--------|
27
- | title | 标题 | string | 'Opportunity List' |
28
- | summaryText | 摘要文本 | string | - |
29
- | tabs | Tab配置 | OppTab[] | [] |
30
- | activeTab | 当前Tab | string | 第一个Tab |
31
- | filterChips | 筛选 Chips | string[] | [] |
32
- | columns | 表头列 | string[] | [] |
33
- | rows | 商机数据 | Opportunity[] | [] |
34
- | onTabChange | Tab切换回调 | (tab: string) => void | - |
35
- | onChipChange | Chip切换回调 | (chip: string) => void | - |
36
- | onSort | 排序回调 | (column: string) => void | - |
37
- | onRowClick | 行点击回调 | (opp: Opportunity) => void | - |
38
-
39
- ## Opportunity
40
-
41
- | 属性 | 说明 | 类型 |
42
- |------|------|------|
43
- | name | 商机名称 | string |
44
- | account | 账户 | string |
45
- | forecastType | 预测类型 | string |
46
- | amount | 金额 | string |
47
- | closeDate | 关闭日期 | string |
48
- | stage | 阶段 | string |
49
- | aiScore | AI评分 | string |
50
- | aiWinRate | AI赢率 | string |
51
- | lastActivity | 最近活动 | string |
52
- | source | 来源 | 'rescue' \| 'upgrade' \| 'all' |
@@ -1,285 +0,0 @@
1
- /**
2
- * @file 商机列表组件
3
- * @description 展示商机数据表格,支持排序、筛选、Tab切换等功能
4
- */
5
- import * as React from 'react';
6
- // @ts-ignore
7
- import { BaseCmp, StatusHoc, NeoEvent } from 'neo-ui-common';
8
-
9
- import './style.scss';
10
-
11
- interface OppTab {
12
- key: string;
13
- label: string;
14
- icon?: string;
15
- }
16
-
17
- interface Opportunity {
18
- name: string;
19
- account?: string;
20
- forecastType?: string;
21
- amount: string;
22
- closeDate: string;
23
- stage: string;
24
- aiScore?: string;
25
- aiScoreColor?: string;
26
- aiWinRate?: string;
27
- lastActivity?: string;
28
- source?: 'rescue' | 'upgrade' | 'all';
29
- }
30
-
31
- interface OppListProps {
32
- title?: string;
33
- summaryText?: string;
34
- tabs?: OppTab[];
35
- activeTab?: string;
36
- filterChips?: string[];
37
- activeChip?: string;
38
- columns?: string[];
39
- rows?: Opportunity[];
40
- onTabChange?: (tab: string) => void;
41
- onChipChange?: (chip: string) => void;
42
- onSort?: (column: string) => void;
43
- onRowClick?: (opp: Opportunity) => void;
44
- className?: string;
45
- style?: React.CSSProperties;
46
- }
47
-
48
- interface OppListState {
49
- activeTab: string;
50
- activeChip: string;
51
- sortColumn?: string;
52
- sortDirection?: 'asc' | 'desc';
53
- }
54
-
55
- class OppList extends BaseCmp<OppListProps, OppListState> {
56
- constructor(props: OppListProps) {
57
- super(props);
58
- this.state = {
59
- activeTab: props.activeTab || (props.tabs?.[0]?.key ?? 'watch'),
60
- activeChip: props.activeChip || (props.filterChips?.[0] ?? 'all'),
61
- sortColumn: undefined,
62
- sortDirection: undefined,
63
- };
64
- }
65
-
66
- componentDidMount() {
67
- console.log('OppList 组件挂载');
68
- }
69
-
70
- handleTabChange = (tab: string) => {
71
- this.setState({ activeTab: tab });
72
- const { onTabChange } = this.props;
73
- if (onTabChange) {
74
- onTabChange(tab);
75
- }
76
- };
77
-
78
- handleChipChange = (chip: string) => {
79
- this.setState({ activeChip: chip });
80
- const { onChipChange } = this.props;
81
- if (onChipChange) {
82
- onChipChange(chip);
83
- }
84
- };
85
-
86
- handleSort = (column: string) => {
87
- const { sortColumn, sortDirection } = this.state;
88
- let newDirection: 'asc' | 'desc' = 'asc';
89
-
90
- if (sortColumn === column) {
91
- newDirection = sortDirection === 'asc' ? 'desc' : 'asc';
92
- }
93
-
94
- this.setState({ sortColumn: column, sortDirection: newDirection });
95
- const { onSort } = this.props;
96
- if (onSort) {
97
- onSort(column);
98
- }
99
- };
100
-
101
- getScoreBadgeStyle = (score: string, color?: string) => {
102
- const bgColor = color || '#22c55e';
103
- return {
104
- backgroundColor: bgColor,
105
- color: '#fff',
106
- padding: '2px 8px',
107
- borderRadius: '10px',
108
- fontSize: '11px',
109
- };
110
- };
111
-
112
- filterRows = () => {
113
- const { rows = [] } = this.props;
114
- const { activeChip } = this.state;
115
-
116
- if (activeChip === 'all') {
117
- return rows;
118
- }
119
-
120
- return rows.filter((row) => row.source === activeChip);
121
- };
122
-
123
- render() {
124
- const {
125
- title = 'Opportunity List',
126
- summaryText,
127
- tabs = [],
128
- filterChips = [],
129
- columns = [],
130
- className,
131
- style,
132
- } = this.props;
133
-
134
- const { activeTab, activeChip, sortColumn, sortDirection } = this.state;
135
- const filteredRows = this.filterRows();
136
-
137
- return (
138
- <div className={`opp-list__c ${className || ''}`} style={style}>
139
- {/* Tab切换 */}
140
- {tabs.length > 0 && (
141
- <div className="opp-tabs">
142
- {tabs.map((tab) => (
143
- <button
144
- key={tab.key}
145
- className={`opp-tab-btn ${
146
- activeTab === tab.key ? 'active' : ''
147
- }`}
148
- onClick={() => this.handleTabChange(tab.key)}
149
- >
150
- {tab.icon} {tab.label}
151
- </button>
152
- ))}
153
- </div>
154
- )}
155
-
156
- {/* 筛选Chips */}
157
- {filterChips.length > 0 && (
158
- <div className="filter-chips">
159
- {filterChips.map((chip, index) => (
160
- <button
161
- key={index}
162
- className={`watch-sub-tab ${
163
- activeChip === chip.split('(')[0].trim().toLowerCase()
164
- ? 'active'
165
- : ''
166
- }`}
167
- onClick={() =>
168
- this.handleChipChange(chip.split('(')[0].trim().toLowerCase())
169
- }
170
- >
171
- {chip}
172
- </button>
173
- ))}
174
- </div>
175
- )}
176
-
177
- {/* 标题和摘要 */}
178
- <div className="list-header">
179
- <h3 className="list-title">{title}</h3>
180
- {summaryText && <div className="list-summary">{summaryText}</div>}
181
- </div>
182
-
183
- {/* 表格 */}
184
- <div className="table-wrapper">
185
- <table className="opp-table">
186
- <thead>
187
- <tr>
188
- {columns.map((col, index) => (
189
- <th
190
- key={index}
191
- style={{
192
- textAlign:
193
- col === 'Amount'
194
- ? 'right'
195
- : col === 'Close Date' ||
196
- col === 'Stage' ||
197
- col === 'Last Activity' ||
198
- col === 'AI Score' ||
199
- col === 'AI Win Rate'
200
- ? 'center'
201
- : 'left',
202
- }}
203
- >
204
- {col}
205
- <span
206
- className="sort-icon"
207
- onClick={() => this.handleSort(col)}
208
- style={{
209
- color: sortColumn === col ? '#6366f1' : '#ccc',
210
- marginLeft: '4px',
211
- }}
212
- >
213
- {sortColumn === col
214
- ? sortDirection === 'asc'
215
- ? '↑'
216
- : '↓'
217
- : '⇅'}
218
- </span>
219
- </th>
220
- ))}
221
- </tr>
222
- </thead>
223
- <tbody>
224
- {filteredRows.map((opp, index) => (
225
- <tr
226
- key={index}
227
- className={opp.source ? `opp-row source-${opp.source}` : ''}
228
- >
229
- <td
230
- style={{
231
- textAlign: 'left',
232
- color: '#3b82f6',
233
- cursor: 'pointer',
234
- }}
235
- >
236
- {opp.name}
237
- </td>
238
- {opp.account && (
239
- <td style={{ textAlign: 'left' }}>{opp.account}</td>
240
- )}
241
- {opp.forecastType && (
242
- <td style={{ textAlign: 'left' }}>{opp.forecastType}</td>
243
- )}
244
- <td style={{ textAlign: 'right' }}>{opp.amount}</td>
245
- <td style={{ textAlign: 'center' }}>{opp.closeDate}</td>
246
- <td style={{ textAlign: 'center' }}>{opp.stage}</td>
247
- {opp.aiScore && (
248
- <td style={{ textAlign: 'center' }}>
249
- <span
250
- style={this.getScoreBadgeStyle(
251
- opp.aiScore,
252
- opp.aiScoreColor,
253
- )}
254
- >
255
- {opp.aiScore}
256
- </span>
257
- </td>
258
- )}
259
- {opp.aiWinRate && (
260
- <td
261
- style={{
262
- textAlign: 'center',
263
- color: '#6366f1',
264
- fontWeight: 600,
265
- }}
266
- >
267
- {opp.aiWinRate}
268
- </td>
269
- )}
270
- {opp.lastActivity && (
271
- <td style={{ textAlign: 'center', color: '#999' }}>
272
- {opp.lastActivity}
273
- </td>
274
- )}
275
- </tr>
276
- ))}
277
- </tbody>
278
- </table>
279
- </div>
280
- </div>
281
- );
282
- }
283
- }
284
-
285
- export default StatusHoc(OppList);
@@ -1,86 +0,0 @@
1
- export class OppListModel {
2
- label: string = '商机列表';
3
- description: string = '展示商机数据表格,支持排序、筛选、Tab切换等功能';
4
- iconUrl: string = 'https://custom-widgets.bj.bcebos.com/oppList.svg';
5
- targetPage: string[] = ['all'];
6
- targetDevice: string = 'all';
7
-
8
- defaultComProps = {
9
- title: 'Opportunity List',
10
- tabs: [
11
- { key: 'watch', label: '✨ Prioritized Deals', icon: '' },
12
- { key: 'all', label: 'All Opportunities', icon: '' },
13
- ],
14
- filterChips: ['All (3)', 'Rescue (1)', 'Upgrade (2)'],
15
- columns: [
16
- 'Opportunity Name',
17
- 'Account',
18
- 'Forecast Type',
19
- 'Amount',
20
- 'Close Date',
21
- 'Stage',
22
- '✨ AI Score',
23
- '✨ AI Win Rate',
24
- 'Last Activity',
25
- ],
26
- rows: [
27
- {
28
- name: 'Apollo Project',
29
- account: 'Huawei Tech',
30
- forecastType: 'Commit',
31
- amount: '$1,000,000',
32
- closeDate: '2026-04-15',
33
- stage: 'Negotiation',
34
- aiScore: 'Medium',
35
- aiScoreColor: '#f59e0b',
36
- aiWinRate: '42%',
37
- lastActivity: '2026-03-28',
38
- source: 'rescue',
39
- },
40
- {
41
- name: 'Aurora Solution',
42
- account: 'ByteDance',
43
- forecastType: 'Best Case',
44
- amount: '$800,000',
45
- closeDate: '2026-04-30',
46
- stage: 'Proposal',
47
- aiScore: 'High',
48
- aiScoreColor: '#22c55e',
49
- aiWinRate: '91%',
50
- lastActivity: '2026-03-29',
51
- source: 'upgrade',
52
- },
53
- {
54
- name: 'Cloud Migration',
55
- account: 'Tencent',
56
- forecastType: 'Pipeline',
57
- amount: '$1,700,000',
58
- closeDate: '2026-05-20',
59
- stage: 'Discovery',
60
- aiScore: 'Medium',
61
- aiScoreColor: '#f59e0b',
62
- aiWinRate: '78%',
63
- lastActivity: '2026-03-27',
64
- source: 'upgrade',
65
- },
66
- ],
67
- };
68
-
69
- functions = [
70
- {
71
- apiKey: 'refreshData',
72
- label: '刷新数据',
73
- helpTextKey: '刷新商机列表数据',
74
- },
75
- ];
76
-
77
- propsSchema = [
78
- {
79
- type: 'string',
80
- name: 'title',
81
- label: '标题',
82
- },
83
- ];
84
- }
85
-
86
- export default OppListModel;
@@ -1,133 +0,0 @@
1
- .opp-list__c {
2
- background: #fff;
3
- border-radius: 8px;
4
- padding: 20px;
5
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
6
- overflow-x: auto;
7
-
8
- .opp-tabs {
9
- display: flex;
10
- gap: 0;
11
- margin-bottom: 16px;
12
- border-bottom: 2px solid #e5e7eb;
13
- }
14
-
15
- .opp-tab-btn {
16
- padding: 8px 20px;
17
- font-size: 13px;
18
- font-weight: 600;
19
- cursor: pointer;
20
- border: none;
21
- background: none;
22
- color: #999;
23
- border-bottom: 2px solid transparent;
24
- margin-bottom: -2px;
25
- transition: all 0.2s;
26
-
27
- &:hover {
28
- color: #6366f1;
29
- }
30
-
31
- &.active {
32
- color: #6366f1;
33
- border-bottom-color: #6366f1;
34
- }
35
- }
36
-
37
- .filter-chips {
38
- display: flex;
39
- gap: 8px;
40
- margin-bottom: 16px;
41
- }
42
-
43
- .watch-sub-tab {
44
- padding: 6px 14px;
45
- font-size: 12px;
46
- font-weight: 600;
47
- cursor: pointer;
48
- border: 1px solid #ddd;
49
- background: #fff;
50
- color: #666;
51
- border-radius: 20px;
52
- transition: all 0.2s;
53
-
54
- &:hover {
55
- border-color: #6366f1;
56
- }
57
-
58
- &.active {
59
- border: 1px solid #6366f1;
60
- background: #f0f0ff;
61
- color: #6366f1;
62
- }
63
- }
64
-
65
- .list-header {
66
- display: flex;
67
- justify-content: space-between;
68
- align-items: center;
69
- margin-bottom: 12px;
70
- }
71
-
72
- .list-title {
73
- font-size: 14px;
74
- font-weight: 600;
75
- margin: 0;
76
- }
77
-
78
- .list-summary {
79
- font-size: 13px;
80
- color: #666;
81
-
82
- span {
83
- font-weight: 700;
84
- color: #333;
85
- }
86
- }
87
-
88
- .table-wrapper {
89
- overflow-x: auto;
90
- }
91
-
92
- .opp-table {
93
- width: 100%;
94
- border-collapse: collapse;
95
- font-size: 13px;
96
-
97
- th,
98
- td {
99
- padding: 10px 12px;
100
- border-bottom: 1px solid #f0f0f0;
101
- }
102
-
103
- th {
104
- background: #f8f9fa;
105
- font-weight: 600;
106
- color: #333;
107
- border-bottom: 2px solid #e5e7eb;
108
- user-select: none;
109
- }
110
-
111
- td {
112
- color: #333;
113
- }
114
-
115
- tbody tr {
116
- transition: background 0.15s;
117
- border-bottom: 1px solid #f0f0f0;
118
-
119
- &:hover {
120
- background: #fafafa;
121
- }
122
- }
123
-
124
- .sort-icon {
125
- cursor: pointer;
126
- font-size: 10px;
127
-
128
- &:hover {
129
- color: #6366f1 !important;
130
- }
131
- }
132
- }
133
- }