neo-cmp-cli 1.13.12 → 1.13.13

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 (61) hide show
  1. package/dist/neo/neoService.js +1 -1
  2. package/dist/package.json.js +1 -1
  3. package/package.json +1 -1
  4. package/template/antd-custom-cmp-template/package.json +1 -1
  5. package/template/asset-manage-template/package.json +1 -1
  6. package/template/echarts-custom-cmp-template/package.json +1 -1
  7. package/template/empty-custom-cmp-template/package.json +1 -1
  8. package/template/map-custom-cmp-template/package.json +1 -1
  9. package/template/neo-bi-cmps/package.json +1 -1
  10. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/README.md +52 -0
  11. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/index.tsx +176 -0
  12. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/model.ts +49 -0
  13. package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/style.scss +218 -0
  14. package/template/neo-bi-cmps/src/components/filterBar__c/README.md +35 -0
  15. package/template/neo-bi-cmps/src/components/filterBar__c/index.tsx +186 -0
  16. package/template/neo-bi-cmps/src/components/filterBar__c/model.ts +72 -0
  17. package/template/neo-bi-cmps/src/components/filterBar__c/style.scss +212 -0
  18. package/template/neo-bi-cmps/src/components/forecastChart__c/README.md +31 -0
  19. package/template/neo-bi-cmps/src/components/forecastChart__c/index.tsx +161 -0
  20. package/template/neo-bi-cmps/src/components/forecastChart__c/model.ts +39 -0
  21. package/template/neo-bi-cmps/src/components/forecastChart__c/style.scss +154 -0
  22. package/template/neo-bi-cmps/src/components/forecastGrid__c/README.md +36 -0
  23. package/template/neo-bi-cmps/src/components/forecastGrid__c/index.tsx +86 -0
  24. package/template/neo-bi-cmps/src/components/forecastGrid__c/model.ts +34 -0
  25. package/template/neo-bi-cmps/src/components/forecastGrid__c/style.scss +48 -0
  26. package/template/neo-bi-cmps/src/components/gapCloser__c/README.md +24 -0
  27. package/template/neo-bi-cmps/src/components/gapCloser__c/index.tsx +95 -0
  28. package/template/neo-bi-cmps/src/components/gapCloser__c/model.ts +43 -0
  29. package/template/neo-bi-cmps/src/components/gapCloser__c/style.scss +60 -0
  30. package/template/neo-bi-cmps/src/components/kpiCards__c/README.md +35 -0
  31. package/template/neo-bi-cmps/src/components/kpiCards__c/index.tsx +70 -0
  32. package/template/neo-bi-cmps/src/components/kpiCards__c/model.ts +35 -0
  33. package/template/neo-bi-cmps/src/components/kpiCards__c/style.scss +33 -0
  34. package/template/neo-bi-cmps/src/components/oppList__c/README.md +52 -0
  35. package/template/neo-bi-cmps/src/components/oppList__c/index.tsx +228 -0
  36. package/template/neo-bi-cmps/src/components/oppList__c/model.ts +40 -0
  37. package/template/neo-bi-cmps/src/components/oppList__c/style.scss +133 -0
  38. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/README.md +39 -0
  39. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/index.tsx +128 -0
  40. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/model.ts +42 -0
  41. package/template/neo-bi-cmps/src/components/pipelineFunnel__c/style.scss +133 -0
  42. package/template/neo-bi-cmps/src/components/stageSwitch__c/README.md +36 -0
  43. package/template/neo-bi-cmps/src/components/stageSwitch__c/index.tsx +103 -0
  44. package/template/neo-bi-cmps/src/components/stageSwitch__c/model.ts +37 -0
  45. package/template/neo-bi-cmps/src/components/stageSwitch__c/style.scss +89 -0
  46. package/template/neo-bi-cmps/src/components/stageTimeChart__c/README.md +37 -0
  47. package/template/neo-bi-cmps/src/components/stageTimeChart__c/index.tsx +126 -0
  48. package/template/neo-bi-cmps/src/components/stageTimeChart__c/model.ts +35 -0
  49. package/template/neo-bi-cmps/src/components/stageTimeChart__c/style.scss +140 -0
  50. package/template/neo-bi-cmps/src/components/tabSwitch__c/README.md +37 -0
  51. package/template/neo-bi-cmps/src/components/tabSwitch__c/index.tsx +80 -0
  52. package/template/neo-bi-cmps/src/components/tabSwitch__c/model.ts +45 -0
  53. package/template/neo-bi-cmps/src/components/tabSwitch__c/style.scss +37 -0
  54. package/template/neo-custom-cmp-template/package.json +1 -1
  55. package/template/neo-h5-cmps/package.json +1 -1
  56. package/template/neo-order-cmps/package.json +1 -1
  57. package/template/neo-web-entity-grid/package.json +1 -1
  58. package/template/neo-web-form/package.json +1 -1
  59. package/template/react-custom-cmp-template/package.json +1 -1
  60. package/template/react-ts-custom-cmp-template/package.json +1 -1
  61. package/template/vue2-custom-cmp-template/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ export class PipelineFunnelModel {
2
+ label: string = 'Pipeline漏斗图';
3
+ description: string = '展示销售管道的漏斗转化情况,直观显示各阶段金额和数量';
4
+ iconUrl: string = 'https://custom-widgets.bj.bcebos.com/pipelineFunnel.svg';
5
+ targetPage: string[] = ['all'];
6
+ targetDevice: string = 'all';
7
+
8
+ defaultComProps = {
9
+ title: 'Pipeline Funnel',
10
+ totalAmount: '$11.1M',
11
+ stages: [
12
+ { name: 'Prospecting', amount: '$3.2M', count: 15, conversionRate: '—', color: '#3b82f6' },
13
+ { name: 'Needs Analysis', amount: '$1.8M', count: 7, conversionRate: '56.3%', color: '#22c55e' },
14
+ { name: 'Proposal/Price Quote', amount: '$4.5M', count: 8, conversionRate: '28.1%', color: '#f59e0b' },
15
+ { name: 'Closed Won', amount: '$1.6M', count: 3, conversionRate: '10.0%', color: '#8b5cf6' },
16
+ ],
17
+ showAiButton: true,
18
+ };
19
+
20
+ functions = [
21
+ {
22
+ apiKey: 'refreshData',
23
+ label: '刷新数据',
24
+ helpTextKey: '刷新漏斗图数据',
25
+ },
26
+ ];
27
+
28
+ propsSchema = [
29
+ {
30
+ type: 'string',
31
+ name: 'title',
32
+ label: '标题',
33
+ },
34
+ {
35
+ type: 'string',
36
+ name: 'totalAmount',
37
+ label: '总金额',
38
+ },
39
+ ];
40
+ }
41
+
42
+ export default PipelineFunnelModel;
@@ -0,0 +1,133 @@
1
+ .pipeline-funnel__c {
2
+ background: #fff;
3
+ border-radius: 8px;
4
+ padding: 20px;
5
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
6
+
7
+ .funnel-header {
8
+ display: flex;
9
+ justify-content: space-between;
10
+ align-items: center;
11
+ margin-bottom: 16px;
12
+ }
13
+
14
+ .funnel-title {
15
+ font-size: 14px;
16
+ font-weight: 600;
17
+ margin: 0;
18
+ }
19
+
20
+ .ai-btn {
21
+ cursor: pointer;
22
+ font-size: 16px;
23
+ transition: transform 0.2s;
24
+
25
+ &:hover {
26
+ transform: scale(1.1);
27
+ }
28
+ }
29
+
30
+ .funnel-total {
31
+ text-align: center;
32
+ margin-bottom: 16px;
33
+
34
+ .funnel-total-label {
35
+ font-size: 12px;
36
+ color: #888;
37
+ }
38
+
39
+ .funnel-total-value {
40
+ font-size: 22px;
41
+ font-weight: 700;
42
+ }
43
+ }
44
+
45
+ .funnel-body {
46
+ display: flex;
47
+ align-items: stretch;
48
+ gap: 0;
49
+ }
50
+
51
+ .funnel-left-rates {
52
+ width: 100px;
53
+ display: flex;
54
+ flex-direction: column;
55
+ justify-content: center;
56
+ gap: 0;
57
+ font-size: 11px;
58
+ color: #888;
59
+ }
60
+
61
+ .funnel-rate {
62
+ height: 48px;
63
+ display: flex;
64
+ align-items: center;
65
+ }
66
+
67
+ .funnel-main {
68
+ flex: 1;
69
+ display: flex;
70
+ flex-direction: column;
71
+ align-items: center;
72
+ }
73
+
74
+ .funnel-segment {
75
+ width: 100%;
76
+ height: 48px;
77
+ display: flex;
78
+ align-items: center;
79
+ justify-content: center;
80
+ color: #fff;
81
+ font-size: 12px;
82
+ font-weight: 600;
83
+ cursor: pointer;
84
+ transition: opacity 0.2s;
85
+
86
+ &:hover {
87
+ opacity: 0.85;
88
+ }
89
+ }
90
+
91
+ .funnel-right-data {
92
+ width: 110px;
93
+ display: flex;
94
+ flex-direction: column;
95
+ justify-content: center;
96
+ gap: 0;
97
+ font-size: 11px;
98
+ color: #555;
99
+ text-align: right;
100
+ }
101
+
102
+ .funnel-data {
103
+ height: 48px;
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: flex-end;
107
+ }
108
+
109
+ .funnel-legend {
110
+ display: flex;
111
+ gap: 12px;
112
+ justify-content: center;
113
+ flex-wrap: wrap;
114
+ margin-top: 16px;
115
+ font-size: 11px;
116
+ color: #666;
117
+ }
118
+
119
+ .legend-item {
120
+ display: flex;
121
+ align-items: center;
122
+ gap: 4px;
123
+ }
124
+
125
+ .legend-dot {
126
+ display: inline-block;
127
+ width: 10px;
128
+ height: 10px;
129
+ border-radius: 50%;
130
+ margin-right: 4px;
131
+ vertical-align: middle;
132
+ }
133
+ }
@@ -0,0 +1,36 @@
1
+ # StageSwitch 组件
2
+
3
+ 阶段切换卡片组件,切换显示不同销售阶段的数据。
4
+
5
+ ## 使用方式
6
+
7
+ ```tsx
8
+ import StageSwitch from './components/stageSwitch__c';
9
+
10
+ <StageSwitch
11
+ stages={[
12
+ { key: 'Prospecting', name: 'Prospecting', amount: '$3.2M', count: 15 },
13
+ { key: 'Proposal', name: 'Proposal', amount: '$4.5M', count: 8 },
14
+ ]}
15
+ activeStage="Prospecting"
16
+ onStageChange={(stage) => console.log('Changed:', stage.key)}
17
+ />
18
+ ```
19
+
20
+ ## Props
21
+
22
+ | 属性 | 说明 | 类型 | 默认值 |
23
+ |------|------|------|--------|
24
+ | stages | 阶段数据 | StageTab[] | [] |
25
+ | activeStage | 当前阶段 | string | 第一个阶段 |
26
+ | onStageChange | 阶段切换回调 | (stage: StageTab) => void | - |
27
+
28
+ ## StageTab
29
+
30
+ | 属性 | 说明 | 类型 |
31
+ |------|------|------|
32
+ | key | 唯一标识 | string |
33
+ | name | 阶段名称 | string |
34
+ | amount | 金额 | string |
35
+ | count | 数量 | number |
36
+ | changes | 变化数据 | { amount, amountDirection, count, countDirection } |
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @file 阶段切换卡片组件
3
+ * @description 切换显示不同销售阶段的数据
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 StageTab {
12
+ key: string;
13
+ name: string;
14
+ amount: string;
15
+ count: number;
16
+ changes?: {
17
+ amount: string;
18
+ amountDirection: 'up' | 'down';
19
+ count: string;
20
+ countDirection: 'up' | 'down';
21
+ };
22
+ }
23
+
24
+ interface StageSwitchProps {
25
+ stages?: StageTab[];
26
+ activeStage?: string;
27
+ onStageChange?: (stage: StageTab) => void;
28
+ className?: string;
29
+ style?: React.CSSProperties;
30
+ }
31
+
32
+ interface StageSwitchState {
33
+ activeStage: string;
34
+ }
35
+
36
+ class StageSwitch extends BaseCmp<StageSwitchProps, StageSwitchState> {
37
+ constructor(props: StageSwitchProps) {
38
+ super(props);
39
+ this.state = {
40
+ activeStage: props.activeStage || (props.stages?.[0]?.key ?? ''),
41
+ };
42
+ }
43
+
44
+ componentDidMount() {
45
+ console.log('StageSwitch 组件挂载');
46
+ }
47
+
48
+ componentWillReceiveProps(nextProps: StageSwitchProps) {
49
+ if (nextProps.activeStage && nextProps.activeStage !== this.props.activeStage) {
50
+ this.setState({ activeStage: nextProps.activeStage });
51
+ }
52
+ }
53
+
54
+ handleStageClick(stage: StageTab) {
55
+ this.setState({ activeStage: stage.key });
56
+ const { onStageChange } = this.props;
57
+ if (onStageChange) {
58
+ onStageChange(stage);
59
+ }
60
+ }
61
+
62
+ render() {
63
+ const { stages = [], className, style } = this.props;
64
+ const { activeStage } = this.state;
65
+
66
+ return (
67
+ <div className={`stage-switch__c ${className || ''}`} style={style}>
68
+ <div className="stage-tabs">
69
+ {stages.map((stage) => (
70
+ <div
71
+ key={stage.key}
72
+ className={`stage-tab ${activeStage === stage.key ? 'active' : ''}`}
73
+ onClick={() => this.handleStageClick(stage)}
74
+ >
75
+ <div className="stage-name">{stage.name}</div>
76
+ <div className="stage-amount-row">
77
+ <span className="stage-amount">{stage.amount}</span>
78
+ <span className="stage-count">({stage.count})</span>
79
+ </div>
80
+ {stage.changes && (
81
+ <div className="stage-sub">
82
+ <span
83
+ className={`change-amount ${stage.changes.amountDirection === 'up' ? 'positive' : 'negative'}`}
84
+ >
85
+ {stage.changes.amountDirection === 'up' ? '↑' : '↓'} {stage.changes.amount}
86
+ </span>
87
+ <span> &nbsp; </span>
88
+ <span
89
+ className={`change-count ${stage.changes.countDirection === 'up' ? 'positive' : 'negative'}`}
90
+ >
91
+ {stage.changes.countDirection === 'up' ? '↑' : '↓'} {stage.changes.count}
92
+ </span>
93
+ </div>
94
+ )}
95
+ </div>
96
+ ))}
97
+ </div>
98
+ </div>
99
+ );
100
+ }
101
+ }
102
+
103
+ export default StatusHoc(StageSwitch);
@@ -0,0 +1,37 @@
1
+ export class StageSwitchModel {
2
+ label: string = '阶段切换卡片';
3
+ description: string = '切换显示不同销售阶段的数据,包含金额、数量和变化趋势';
4
+ iconUrl: string = 'https://custom-widgets.bj.bcebos.com/stageSwitch.svg';
5
+ targetPage: string[] = ['all'];
6
+ targetDevice: string = 'all';
7
+
8
+ defaultComProps = {
9
+ stages: [
10
+ { key: 'Prospecting', name: 'Prospecting', amount: '$3.2M', count: 15, changes: { amount: '$280K', amountDirection: 'up', count: '3', countDirection: 'up' } },
11
+ { key: 'Needs Analysis', name: 'Needs Analysis', amount: '$1.8M', count: 7, changes: { amount: '$320K', amountDirection: 'down', count: '2', countDirection: 'down' } },
12
+ { key: 'Proposal', name: 'Proposal/Price Quote', amount: '$4.5M', count: 8, changes: { amount: '$500K', amountDirection: 'up', count: '3', countDirection: 'up' } },
13
+ { key: 'Closed Won', name: 'Closed Won', amount: '$1.6M', count: 3, changes: { amount: '$400K', amountDirection: 'up', count: '1', countDirection: 'up' } },
14
+ { key: 'Closed Lost', name: 'Closed Lost', amount: '$0.9M', count: 4, changes: { amount: '$200K', amountDirection: 'down', count: '2', countDirection: 'up' } },
15
+ ],
16
+ activeStage: 'Prospecting',
17
+ };
18
+
19
+ functions = [
20
+ {
21
+ apiKey: 'setActiveStage',
22
+ label: '设置当前阶段',
23
+ helpTextKey: '设置当前激活的销售阶段',
24
+ },
25
+ ];
26
+
27
+ propsSchema = [
28
+ {
29
+ type: 'object',
30
+ name: 'stages',
31
+ label: '阶段配置',
32
+ schema: [],
33
+ },
34
+ ];
35
+ }
36
+
37
+ export default StageSwitchModel;
@@ -0,0 +1,89 @@
1
+ .stage-switch__c {
2
+ .stage-tabs {
3
+ display: flex;
4
+ gap: 0;
5
+ margin-bottom: 20px;
6
+ background: #fff;
7
+ border-radius: 8px;
8
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
9
+ overflow: hidden;
10
+ }
11
+
12
+ .stage-tab {
13
+ flex: 1;
14
+ padding: 10px 16px;
15
+ cursor: pointer;
16
+ border-right: 1px solid #f0f0f0;
17
+ transition: all 0.2s;
18
+ position: relative;
19
+
20
+ &:last-child {
21
+ border-right: none;
22
+ }
23
+
24
+ &:hover {
25
+ background: #fafafa;
26
+ }
27
+
28
+ &.active {
29
+ background: #fff;
30
+
31
+ &::before {
32
+ content: '';
33
+ position: absolute;
34
+ top: 0;
35
+ left: 0;
36
+ right: 0;
37
+ height: 3px;
38
+ background: #6366f1;
39
+ }
40
+
41
+ .stage-name {
42
+ color: #6366f1;
43
+ font-weight: 600;
44
+ }
45
+ }
46
+ }
47
+
48
+ .stage-name {
49
+ font-size: 11px;
50
+ color: #888;
51
+ margin-bottom: 2px;
52
+ }
53
+
54
+ .stage-amount-row {
55
+ display: flex;
56
+ align-items: baseline;
57
+ gap: 4px;
58
+ }
59
+
60
+ .stage-amount {
61
+ font-size: 15px;
62
+ font-weight: 700;
63
+ color: #333;
64
+ }
65
+
66
+ .stage-count {
67
+ font-size: 11px;
68
+ color: #999;
69
+ }
70
+
71
+ .stage-sub {
72
+ font-size: 10px;
73
+ color: #999;
74
+ margin-top: 2px;
75
+ }
76
+
77
+ .change-amount,
78
+ .change-count {
79
+ font-weight: 700;
80
+ }
81
+
82
+ .positive {
83
+ color: #16a34a;
84
+ }
85
+
86
+ .negative {
87
+ color: #dc2626;
88
+ }
89
+ }
@@ -0,0 +1,37 @@
1
+ # StageTimeChart 组件
2
+
3
+ 阶段停留时间组件,展示各销售阶段的平均停留时间。
4
+
5
+ ## 使用方式
6
+
7
+ ```tsx
8
+ import StageTimeChart from './components/stageTimeChart__c';
9
+
10
+ <StageTimeChart
11
+ title="Avg. Time in Stage"
12
+ items={[
13
+ { stageName: 'Prospecting', actualTime: '8天6时', actualPercent: 28, actualColor: '#22c55e', targetPercent: 33, limitPercent: 50 },
14
+ ]}
15
+ onStageClick={(name) => console.log('Clicked:', name)}
16
+ />
17
+ ```
18
+
19
+ ## Props
20
+
21
+ | 属性 | 说明 | 类型 | 默认值 |
22
+ |------|------|------|--------|
23
+ | title | 标题 | string | 'Avg. Time in Stage' |
24
+ | items | 阶段数据 | StageTimeItem[] | [] |
25
+ | showAiButton | 显示AI按钮 | boolean | true |
26
+ | onStageClick | 阶段点击回调 | (stageName: string) => void | - |
27
+
28
+ ## StageTimeItem
29
+
30
+ | 属性 | 说明 | 类型 |
31
+ |------|------|------|
32
+ | stageName | 阶段名称 | string |
33
+ | actualTime | 实际时间 | string |
34
+ | actualPercent | 实际百分比 | number |
35
+ | actualColor | 实际颜色 | string |
36
+ | targetPercent | 目标百分比 | number |
37
+ | limitPercent | 限制百分比 | number |
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @file 阶段停留时间组件
3
+ * @description 展示各销售阶段的平均停留时间,包含实际值、目标值和限制值
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 StageTimeItem {
12
+ stageName: string;
13
+ actualTime: string;
14
+ actualPercent: number;
15
+ actualColor: string;
16
+ targetPercent: number;
17
+ limitPercent: number;
18
+ }
19
+
20
+ interface StageTimeChartProps {
21
+ title?: string;
22
+ items?: StageTimeItem[];
23
+ showAiButton?: boolean;
24
+ onStageClick?: (stageName: string) => void;
25
+ className?: string;
26
+ style?: React.CSSProperties;
27
+ }
28
+
29
+ interface StageTimeChartState {
30
+ loading: boolean;
31
+ }
32
+
33
+ class StageTimeChart extends BaseCmp<StageTimeChartProps, StageTimeChartState> {
34
+ constructor(props: StageTimeChartProps) {
35
+ super(props);
36
+ this.state = {
37
+ loading: false,
38
+ };
39
+ }
40
+
41
+ componentDidMount() {
42
+ console.log('StageTimeChart 组件挂载');
43
+ }
44
+
45
+ render() {
46
+ const {
47
+ title = 'Avg. Time in Stage',
48
+ items = [],
49
+ showAiButton = true,
50
+ onStageClick,
51
+ className,
52
+ style,
53
+ } = this.props;
54
+
55
+ return (
56
+ <div className={`stage-time-chart__c ${className || ''}`} style={style}>
57
+ <div className="chart-header">
58
+ <h3 className="chart-title">{title}</h3>
59
+ {showAiButton && (
60
+ <span
61
+ className="ai-btn"
62
+ onClick={() => console.log('AI Analysis clicked')}
63
+ title="AI Analysis"
64
+ >
65
+
66
+ </span>
67
+ )}
68
+ </div>
69
+
70
+ <div className="chart-legend">
71
+ <span className="legend-item">
72
+ <span className="legend-actual" />
73
+ Actual
74
+ </span>
75
+ <span className="legend-item">
76
+ <span className="legend-target" />
77
+ Target
78
+ </span>
79
+ <span className="legend-item">
80
+ <span className="legend-limit" />
81
+ Limit
82
+ </span>
83
+ </div>
84
+
85
+ <div className="chart-body">
86
+ {items.map((item, index) => (
87
+ <div
88
+ key={index}
89
+ className="stage-time-item"
90
+ onClick={() => onStageClick?.(item.stageName)}
91
+ >
92
+ <div className="stage-time-header">
93
+ <span className="stage-name">{item.stageName}</span>
94
+ <span
95
+ className="stage-time-value"
96
+ style={{ color: item.actualColor }}
97
+ >
98
+ {item.actualTime}
99
+ </span>
100
+ </div>
101
+ <div className="stage-time-bar">
102
+ <div
103
+ className="stage-time-actual"
104
+ style={{
105
+ width: `${item.actualPercent}%`,
106
+ backgroundColor: item.actualColor,
107
+ }}
108
+ />
109
+ <div
110
+ className="stage-time-target"
111
+ style={{ left: `${item.targetPercent}%` }}
112
+ />
113
+ <div
114
+ className="stage-time-limit"
115
+ style={{ left: `${item.limitPercent}%` }}
116
+ />
117
+ </div>
118
+ </div>
119
+ ))}
120
+ </div>
121
+ </div>
122
+ );
123
+ }
124
+ }
125
+
126
+ export default StatusHoc(StageTimeChart);
@@ -0,0 +1,35 @@
1
+ export class StageTimeChartModel {
2
+ label: string = '阶段停留时间';
3
+ description: string = '展示各销售阶段的平均停留时间,包含实际值、目标值和限制值';
4
+ iconUrl: string = 'https://custom-widgets.bj.bcebos.com/stageTimeChart.svg';
5
+ targetPage: string[] = ['all'];
6
+ targetDevice: string = 'all';
7
+
8
+ defaultComProps = {
9
+ title: 'Avg. Time in Stage',
10
+ items: [
11
+ { stageName: 'Prospecting', actualTime: '8天6时', actualPercent: 28, actualColor: '#22c55e', targetPercent: 33, limitPercent: 50 },
12
+ { stageName: 'Needs Analysis', actualTime: '15天12时', actualPercent: 52, actualColor: '#eab308', targetPercent: 40, limitPercent: 60 },
13
+ { stageName: 'Proposal/Price Quote', actualTime: '22天8时', actualPercent: 74, actualColor: '#ef4444', targetPercent: 50, limitPercent: 67 },
14
+ ],
15
+ showAiButton: true,
16
+ };
17
+
18
+ functions = [
19
+ {
20
+ apiKey: 'refreshData',
21
+ label: '刷新数据',
22
+ helpTextKey: '刷新停留时间数据',
23
+ },
24
+ ];
25
+
26
+ propsSchema = [
27
+ {
28
+ type: 'string',
29
+ name: 'title',
30
+ label: '标题',
31
+ },
32
+ ];
33
+ }
34
+
35
+ export default StageTimeChartModel;