neo-cmp-cli 1.12.8 → 1.12.9

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 (132) hide show
  1. package/README.md +204 -6
  2. package/dist/index2.js +1 -1
  3. package/dist/neo/env.js +1 -1
  4. package/dist/package.json.js +1 -1
  5. package/package.json +1 -1
  6. package/template/antd-custom-cmp-template/package.json +1 -1
  7. package/template/{neo-bi-cmps → asset-manage-template}/README.md +65 -10
  8. package/template/asset-manage-template/docs/README.md +244 -0
  9. package/template/asset-manage-template/neo.config.js +60 -0
  10. package/template/{neo-bi-cmps → asset-manage-template}/package.json +28 -16
  11. package/template/asset-manage-template/src/assets/img/chart.svg +1 -0
  12. package/template/asset-manage-template/src/components/README.md +3 -0
  13. package/template/asset-manage-template/src/components/assetManage__c/assetApi.ts +70 -0
  14. package/template/asset-manage-template/src/components/assetManage__c/cmps/AssetCreateModal.tsx +260 -0
  15. package/template/asset-manage-template/src/components/assetManage__c/cmps/AssetGrid.tsx +48 -0
  16. package/template/asset-manage-template/src/components/assetManage__c/cmps/AssetSidebar.tsx +74 -0
  17. package/template/asset-manage-template/src/components/assetManage__c/cmps/AssetToolbar.tsx +79 -0
  18. package/template/asset-manage-template/src/components/assetManage__c/cmps/assetDisplay.tsx +72 -0
  19. package/template/asset-manage-template/src/components/assetManage__c/constants.ts +28 -0
  20. package/template/asset-manage-template/src/components/assetManage__c/index.tsx +258 -0
  21. package/template/asset-manage-template/src/components/assetManage__c/model.ts +75 -0
  22. package/template/asset-manage-template/src/components/assetManage__c/style.scss +425 -0
  23. package/template/asset-manage-template/src/components/assetManage__c/types.ts +60 -0
  24. package/template/asset-manage-template/src/components/bidList__c/cmps/BidCard.tsx +47 -0
  25. package/template/asset-manage-template/src/components/bidList__c/constants.ts +6 -0
  26. package/template/asset-manage-template/src/components/bidList__c/formatUtils.ts +14 -0
  27. package/template/asset-manage-template/src/components/bidList__c/index.tsx +194 -0
  28. package/template/asset-manage-template/src/components/bidList__c/model.ts +57 -0
  29. package/template/asset-manage-template/src/components/bidList__c/style.scss +179 -0
  30. package/template/asset-manage-template/src/components/bidList__c/types.ts +10 -0
  31. package/template/asset-manage-template/src/components/bidPackage__c/cmps/BidPackageHeader.tsx +140 -0
  32. package/template/asset-manage-template/src/components/bidPackage__c/cmps/PackageItemTable.tsx +148 -0
  33. package/template/asset-manage-template/src/components/bidPackage__c/index.tsx +394 -0
  34. package/template/asset-manage-template/src/components/bidPackage__c/mainTableColumns.tsx +57 -0
  35. package/template/asset-manage-template/src/components/bidPackage__c/model.ts +86 -0
  36. package/template/asset-manage-template/src/components/bidPackage__c/style.scss +256 -0
  37. package/template/asset-manage-template/src/components/bidPackage__c/types.ts +35 -0
  38. package/template/asset-manage-template/src/components/bidPackage__c/utils.ts +19 -0
  39. package/template/{neo-bi-cmps → asset-manage-template}/src/utils/axiosFetcher.ts +0 -0
  40. package/template/{neo-bi-cmps → asset-manage-template}/src/utils/queryObjectData.ts +0 -0
  41. package/template/asset-manage-template/src/utils/url.ts +82 -0
  42. package/template/{neo-bi-cmps → asset-manage-template}/src/utils/xobjects.ts +0 -0
  43. package/template/{neo-bi-cmps → asset-manage-template}/tsconfig.json +1 -1
  44. package/template/echarts-custom-cmp-template/package.json +1 -1
  45. package/template/empty-custom-cmp-template/package.json +2 -2
  46. package/template/neo-custom-cmp-template/package.json +2 -2
  47. package/template/neo-custom-cmp-template/src/components/entityTable__c/index.tsx +62 -6
  48. package/template/neo-h5-cmps/package.json +2 -2
  49. package/template/neo-order-cmps/package.json +2 -2
  50. package/template/react-custom-cmp-template/package.json +1 -1
  51. package/template/react-ts-custom-cmp-template/package.json +1 -1
  52. package/template/vue2-custom-cmp-template/package.json +1 -1
  53. package/template/develop/BI /351/241/271/347/233/256/345/210/206/346/236/220/346/212/245/345/221/212.md" +0 -562
  54. package/template/develop/ChatPage /347/273/204/344/273/266/344/275/277/347/224/250/350/257/264/346/230/216/346/226/207/346/241/243.md" +0 -507
  55. package/template/develop/EntityGrid Web /347/273/204/344/273/266/347/232/204/350/257/246/347/273/206/345/210/206/346/236/220/346/226/207/346/241/243.md" +0 -868
  56. package/template/develop/EntityList H5 /347/273/204/344/273/266/347/232/204/350/257/246/347/273/206/345/210/206/346/236/220/346/226/207/346/241/243.md" +0 -1386
  57. package/template/develop/GlobalSearch/347/273/204/344/273/266/345/257/271/346/257/224/345/210/206/346/236/220.md +0 -866
  58. package/template/develop/Neo /344/270/255/345/217/257/347/224/250 amis /347/273/204/344/273/266.md" +0 -1490
  59. package/template/develop/cmpEventFunctions.ts +0 -257
  60. package/template/develop/cmpEvents.ts +0 -864
  61. package/template/develop/comTree/347/224/237/346/210/220/350/277/207/347/250/213/345/210/206/346/236/220.md +0 -469
  62. package/template/develop/commonModules.js +0 -55
  63. package/template/develop/components-table.md +0 -50
  64. package/template/develop/neo-custom-cmp-template/README.md +0 -48
  65. package/template/develop/neo-custom-cmp-template/docs/README.md +0 -13
  66. package/template/develop/neo-custom-cmp-template/neo.config.js +0 -121
  67. package/template/develop/neo-custom-cmp-template/package.json +0 -63
  68. package/template/develop/neo-custom-cmp-template/src/components/contactCardList/README.md +0 -65
  69. package/template/develop/neo-custom-cmp-template/src/components/contactCardList/index.tsx +0 -180
  70. package/template/develop/neo-custom-cmp-template/src/components/contactCardList/model.ts +0 -50
  71. package/template/develop/neo-custom-cmp-template/src/components/contactCardList/style.scss +0 -260
  72. package/template/develop/neo-custom-cmp-template/src/components/contactForm/README.md +0 -94
  73. package/template/develop/neo-custom-cmp-template/src/components/contactForm/index.tsx +0 -252
  74. package/template/develop/neo-custom-cmp-template/src/components/contactForm/model.ts +0 -56
  75. package/template/develop/neo-custom-cmp-template/src/components/contactForm/style.scss +0 -120
  76. package/template/develop/neo-custom-cmp-template/src/components/neoEntityGrid/README.md +0 -115
  77. package/template/develop/neo-custom-cmp-template/src/components/neoEntityGrid/index.tsx +0 -304
  78. package/template/develop/neo-custom-cmp-template/src/components/neoEntityGrid/model.ts +0 -87
  79. package/template/develop/neo-custom-cmp-template/src/components/neoEntityGrid/style.scss +0 -127
  80. package/template/develop/neo-custom-cmp-template/src/utils/axiosFetcher.ts +0 -29
  81. package/template/develop/neo-custom-cmp-template/src/utils/queryObjectData.ts +0 -39
  82. package/template/develop/neo-custom-cmp-template/src/utils/xobjects.ts +0 -203
  83. package/template/develop/neo-custom-cmp-template/tsconfig.json +0 -68
  84. package/template/develop/neo-ui-component-h5.md +0 -105
  85. package/template/develop/neo-ui-component-web-xregister.md +0 -31
  86. package/template/develop/neo-ui-component-web.md +0 -292
  87. package/template/develop/neoCmps.ts +0 -7508
  88. package/template/develop/neoGlobalSearchInput /347/273/204/344/273/266/347/232/204/350/257/246/347/273/206/345/210/206/346/236/220/346/226/207/346/241/243.md" +0 -497
  89. package/template/develop/pageSchema1.json +0 -744
  90. package/template/develop//344/272/213/344/273/266/345/212/250/344/275/234/344/277/235/345/255/230/346/265/201/347/250/213/345/210/206/346/236/220.md +0 -390
  91. package/template/develop//345/215/225/345/205/203/346/265/213/350/257/225/344/275/277/347/224/250/350/257/264/346/230/216.md +0 -1139
  92. package/template/develop//345/261/236/346/200/247/351/205/215/347/275/256/351/241/271/347/261/273/345/236/213/346/261/207/346/200/273.md +0 -558
  93. package/template/neo-bi-cmps/.prettierrc.js +0 -12
  94. package/template/neo-bi-cmps/commitlint.config.js +0 -59
  95. package/template/neo-bi-cmps/neo.config.js +0 -124
  96. package/template/neo-bi-cmps/public/css/base.css +0 -283
  97. package/template/neo-bi-cmps/public/scripts/app/bluebird.js +0 -6679
  98. package/template/neo-bi-cmps/public/template.html +0 -13
  99. package/template/neo-bi-cmps/src/assets/css/common.scss +0 -127
  100. package/template/neo-bi-cmps/src/assets/css/mixin.scss +0 -47
  101. package/template/neo-bi-cmps/src/assets/img/NeoCRM.jpg +0 -0
  102. package/template/neo-bi-cmps/src/assets/img/custom-widget.svg +0 -1
  103. package/template/neo-bi-cmps/src/assets/img/favicon.png +0 -0
  104. package/template/neo-bi-cmps/src/assets/img/table.svg +0 -1
  105. package/template/neo-bi-cmps/src/components/targetNumber__c/README.md +0 -100
  106. package/template/neo-bi-cmps/src/components/targetNumber__c/customStyleConfig/configSchema.ts +0 -253
  107. package/template/neo-bi-cmps/src/components/targetNumber__c/customStyleConfig/index.scss +0 -76
  108. package/template/neo-bi-cmps/src/components/targetNumber__c/customStyleConfig/index.tsx +0 -148
  109. package/template/neo-bi-cmps/src/components/targetNumber__c/index.tsx +0 -440
  110. package/template/neo-bi-cmps/src/components/targetNumber__c/model.ts +0 -128
  111. package/template/neo-bi-cmps/src/components/targetNumber__c/style.scss +0 -173
  112. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/.prettierrc.js +0 -0
  113. /package/template/{neo-bi-cmps → asset-manage-template}/@types/neo-ui-common.d.ts +0 -0
  114. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/commitlint.config.js +0 -0
  115. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/public/css/base.css +0 -0
  116. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/public/scripts/app/bluebird.js +0 -0
  117. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/public/template.html +0 -0
  118. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/src/assets/css/common.scss +0 -0
  119. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/src/assets/css/mixin.scss +0 -0
  120. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/AIBtn.gif +0 -0
  121. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/src/assets/img/NeoCRM.jpg +0 -0
  122. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/aiLogo.png +0 -0
  123. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/card-list.svg +0 -0
  124. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/contact-form.svg +0 -0
  125. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/custom-form.svg +0 -0
  126. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/src/assets/img/custom-widget.svg +0 -0
  127. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/data-list.svg +0 -0
  128. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/detail.svg +0 -0
  129. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/src/assets/img/favicon.png +0 -0
  130. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/map.svg +0 -0
  131. /package/template/{neo-bi-cmps → asset-manage-template}/src/assets/img/search.svg +0 -0
  132. /package/template/{develop/neo-custom-cmp-template → asset-manage-template}/src/assets/img/table.svg +0 -0
@@ -0,0 +1,194 @@
1
+ /**
2
+ * @file 标书列表组件
3
+ * @description 窄面板侧边栏,展示标书列表,点击选中后通过 NeoEvent 广播通知标包组件加载数据
4
+ */
5
+ import * as React from 'react';
6
+ import { Input, Spin, Empty, Button, Badge } from 'antd';
7
+ import {
8
+ SearchOutlined,
9
+ ReloadOutlined,
10
+ FileTextOutlined,
11
+ } from '@ant-design/icons';
12
+ // @ts-ignore
13
+ import { xObject } from 'neo-open-api';
14
+ // @ts-ignore
15
+ import debounce from 'lodash/debounce';
16
+ // @ts-ignore
17
+ import { NeoEvent } from 'neo-ui-common';
18
+ import { BidCard } from './cmps/BidCard';
19
+ import type { BidItem } from './types';
20
+ import './style.scss';
21
+
22
+ interface BidListProps {
23
+ /** 标书实体 API Key */
24
+ bidApiKey?: string;
25
+ /** 组件标题 */
26
+ title?: string;
27
+ data?: any;
28
+ env?: any;
29
+ className?: string;
30
+ }
31
+
32
+ interface BidListState {
33
+ bids: BidItem[];
34
+ loading: boolean;
35
+ activeId: string | null;
36
+ keyword: string;
37
+ }
38
+
39
+ export default class BidList extends React.PureComponent<
40
+ BidListProps,
41
+ BidListState
42
+ > {
43
+ private debouncedSearch: () => void;
44
+
45
+ constructor(props: BidListProps) {
46
+ super(props);
47
+ this.state = {
48
+ bids: [],
49
+ loading: false,
50
+ activeId: null,
51
+ keyword: '',
52
+ };
53
+ this.debouncedSearch = debounce(() => this.loadBids(), 300);
54
+ }
55
+
56
+ componentDidMount() {
57
+ this.loadBids();
58
+ }
59
+
60
+ componentDidUpdate(prev: BidListProps) {
61
+ if (prev.bidApiKey !== this.props.bidApiKey) {
62
+ this.loadBids();
63
+ }
64
+ }
65
+
66
+ /** 选中标书事件 */
67
+ @NeoEvent.dispatch
68
+ onSelectBid() {}
69
+
70
+ async loadBids() {
71
+ const { bidApiKey } = this.props;
72
+ const { keyword } = this.state;
73
+
74
+ if (!bidApiKey) {
75
+ this.setState({ bids: [], loading: false });
76
+ return;
77
+ }
78
+
79
+ this.setState({ loading: true });
80
+ try {
81
+ const query: any = {
82
+ xObjectApiKey: bidApiKey,
83
+ fields: [
84
+ 'name',
85
+ 'bidNo__c',
86
+ 'status__c',
87
+ 'totalBudget__c',
88
+ 'deadline__c',
89
+ 'purchaser__c',
90
+ ],
91
+ pageSize: 100,
92
+ };
93
+ if (keyword) {
94
+ query.where = `(name like '%${keyword}%' or bidNo__c like '%${keyword}%')`;
95
+ }
96
+
97
+ const result = await xObject.query(query);
98
+ const records = result?.status ? result.data || [] : [];
99
+
100
+ this.setState({ bids: records, loading: false });
101
+ } catch (e) {
102
+ console.error('加载标书列表失败:', e);
103
+ this.setState({ bids: [], loading: false });
104
+ }
105
+ }
106
+
107
+ handleSelect = (bid: BidItem) => {
108
+ this.setState({ activeId: bid.id });
109
+ const payload = {
110
+ bidId: bid.id,
111
+ bidName: bid.name,
112
+ bidNo: bid.bidNo__c,
113
+ status: bid.status__c,
114
+ totalBudget: bid.totalBudget__c,
115
+ purchaser: bid.purchaser__c,
116
+ deadline: bid.deadline__c,
117
+ };
118
+ try {
119
+ NeoEvent.broadcast('bidSelected', payload);
120
+ } catch (e) {
121
+ // 预览模式 fallback:通过 window CustomEvent 通知
122
+ }
123
+ this.onSelectBid();
124
+ };
125
+
126
+ handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
127
+ this.setState({ keyword: e.target.value }, () => {
128
+ this.debouncedSearch();
129
+ });
130
+ };
131
+
132
+ render() {
133
+ const { title = '标书列表', className, bidApiKey } = this.props;
134
+ const { bids, loading, keyword, activeId } = this.state;
135
+
136
+ const emptyDescription = bidApiKey
137
+ ? '暂无标书'
138
+ : '请在设计器中配置标书实体 API Key(bidApiKey)';
139
+
140
+ return (
141
+ <div className={`bidList__c ${className || ''}`}>
142
+ <div className="list-header">
143
+ <div className="list-title">
144
+ <FileTextOutlined className="title-icon" />
145
+ <span>{title}</span>
146
+ <Badge count={bids.length} className="title-badge" />
147
+ </div>
148
+ <Button
149
+ type="text"
150
+ size="small"
151
+ icon={<ReloadOutlined />}
152
+ onClick={() => this.loadBids()}
153
+ loading={loading}
154
+ disabled={!bidApiKey}
155
+ />
156
+ </div>
157
+
158
+ <div className="list-search">
159
+ <Input
160
+ placeholder="搜索标书编号/名称"
161
+ prefix={<SearchOutlined style={{ color: '#bfbfbf' }} />}
162
+ value={keyword}
163
+ onChange={this.handleSearchChange}
164
+ allowClear
165
+ size="small"
166
+ disabled={!bidApiKey}
167
+ />
168
+ </div>
169
+
170
+ <div className="list-body">
171
+ <Spin spinning={loading} size="small">
172
+ {bids.length === 0 && !loading ? (
173
+ <Empty
174
+ description={emptyDescription}
175
+ image={Empty.PRESENTED_IMAGE_SIMPLE}
176
+ />
177
+ ) : (
178
+ <div className="bid-card-list">
179
+ {bids.map((bid) => (
180
+ <BidCard
181
+ key={bid.id}
182
+ bid={bid}
183
+ active={activeId === bid.id}
184
+ onSelect={this.handleSelect}
185
+ />
186
+ ))}
187
+ </div>
188
+ )}
189
+ </Spin>
190
+ </div>
191
+ </div>
192
+ );
193
+ }
194
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @file 标书列表组件 - 模型文件
3
+ */
4
+ export class BidListModel {
5
+ label: string = '标书列表';
6
+
7
+ description: string =
8
+ '窄面板侧边栏,展示标书列表,点击选中后联动标包概算组件';
9
+
10
+ targetPage: string[] = ['all'];
11
+
12
+ targetDevice: string = 'web';
13
+
14
+ enableDuplicate: boolean = true;
15
+
16
+ iconUrl: string = 'https://custom-widgets.bj.bcebos.com/data-list.svg';
17
+
18
+ defaultComProps = {
19
+ title: '标书列表',
20
+ bidApiKey: 'BidEntity__c',
21
+ };
22
+
23
+ events = [
24
+ {
25
+ apiKey: 'onSelectBid',
26
+ label: '选中标书后',
27
+ helpText: '点击标书列表项后触发,可联动标包组件加载数据',
28
+ },
29
+ ];
30
+
31
+ functions = [
32
+ {
33
+ apiKey: 'loadBids',
34
+ label: '刷新标书列表',
35
+ helpTextKey: '重新加载标书数据',
36
+ },
37
+ ];
38
+
39
+ propsSchema = [
40
+ {
41
+ type: 'panelInput',
42
+ name: 'title',
43
+ label: '组件标题',
44
+ value: '标书列表',
45
+ placeholder: '请输入组件标题',
46
+ },
47
+ {
48
+ type: 'panelInput',
49
+ name: 'bidApiKey',
50
+ label: '标书实体 API Key',
51
+ value: '',
52
+ placeholder: '请输入标书实体的 API Key',
53
+ },
54
+ ];
55
+ }
56
+
57
+ export default BidListModel;
@@ -0,0 +1,179 @@
1
+ .bidList__c {
2
+ width: 100%;
3
+ display: flex;
4
+ flex-direction: column;
5
+ background: #fff;
6
+ border-radius: 8px;
7
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
8
+ overflow: hidden;
9
+
10
+ /* ========== 顶部标题 ========== */
11
+ .list-header {
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: space-between;
15
+ padding: 12px 16px 10px;
16
+ border-bottom: 1px solid #f0f0f0;
17
+ flex-shrink: 0;
18
+
19
+ .list-title {
20
+ display: flex;
21
+ align-items: center;
22
+ gap: 6px;
23
+ font-size: 15px;
24
+ font-weight: 600;
25
+ color: #262626;
26
+
27
+ .title-icon {
28
+ color: #1890ff;
29
+ font-size: 16px;
30
+ }
31
+
32
+ .title-badge {
33
+ .ant-badge-count {
34
+ background: #e6f7ff;
35
+ color: #1890ff;
36
+ box-shadow: none;
37
+ font-size: 11px;
38
+ height: 18px;
39
+ min-width: 18px;
40
+ line-height: 18px;
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ /* ========== 搜索栏 ========== */
47
+ .list-search {
48
+ padding: 8px 16px;
49
+ flex-shrink: 0;
50
+
51
+ .ant-input-affix-wrapper {
52
+ border-radius: 20px;
53
+ background: #f5f5f5;
54
+ padding: 6px 12px;
55
+
56
+ .ant-input {
57
+ background: transparent;
58
+ font-size: 14px;
59
+ }
60
+ }
61
+ }
62
+
63
+ /* ========== 列表主体:纵向单列 ========== */
64
+ .list-body {
65
+ flex: 1;
66
+ overflow-y: auto;
67
+ padding: 8px 16px 14px;
68
+ -webkit-overflow-scrolling: touch;
69
+
70
+ .ant-empty {
71
+ padding: 32px 0;
72
+ }
73
+
74
+ .bid-card-list {
75
+ display: flex;
76
+ flex-direction: column;
77
+ gap: 8px;
78
+ }
79
+ }
80
+
81
+ /* ========== 标书卡片:移动端触摸友好 ========== */
82
+ .bid-card {
83
+ width: 100%;
84
+ padding: 12px 14px;
85
+ border-radius: 10px;
86
+ border: 1.5px solid #f0f0f0;
87
+ cursor: pointer;
88
+ transition: all 0.2s;
89
+ /* 触摸反馈 */
90
+ -webkit-tap-highlight-color: transparent;
91
+ user-select: none;
92
+
93
+ &:active {
94
+ transform: scale(0.97);
95
+ }
96
+
97
+ &:hover {
98
+ border-color: #d9d9d9;
99
+ background: #fafafa;
100
+ }
101
+
102
+ &.active {
103
+ border-color: #1890ff;
104
+ background: #e6f7ff;
105
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.18);
106
+
107
+ .bid-card-name {
108
+ color: #1890ff;
109
+ }
110
+ }
111
+
112
+ .bid-card-top {
113
+ display: flex;
114
+ align-items: center;
115
+ justify-content: space-between;
116
+ margin-bottom: 6px;
117
+
118
+ .bid-no {
119
+ font-size: 11px;
120
+ color: #8c8c8c;
121
+ font-family: 'SFMono-Regular', Consolas, monospace;
122
+ }
123
+
124
+ .ant-tag {
125
+ margin: 0;
126
+ font-size: 11px;
127
+ line-height: 18px;
128
+ padding: 0 6px;
129
+ border-radius: 4px;
130
+ }
131
+ }
132
+
133
+ .bid-card-name {
134
+ font-size: 14px;
135
+ font-weight: 500;
136
+ color: #262626;
137
+ line-height: 1.4;
138
+ margin-bottom: 8px;
139
+ overflow: hidden;
140
+ text-overflow: ellipsis;
141
+ display: -webkit-box;
142
+ -webkit-line-clamp: 2;
143
+ -webkit-box-orient: vertical;
144
+ }
145
+
146
+ .bid-card-meta {
147
+ display: flex;
148
+ align-items: center;
149
+ justify-content: space-between;
150
+ font-size: 12px;
151
+ gap: 8px;
152
+
153
+ .meta-budget {
154
+ color: #1890ff;
155
+ font-weight: 600;
156
+ font-size: 13px;
157
+ }
158
+
159
+ .meta-deadline {
160
+ color: #8c8c8c;
161
+ white-space: nowrap;
162
+
163
+ .anticon {
164
+ margin-right: 3px;
165
+ font-size: 11px;
166
+ }
167
+ }
168
+ }
169
+
170
+ .bid-card-purchaser {
171
+ margin-top: 6px;
172
+ font-size: 11px;
173
+ color: #bfbfbf;
174
+ overflow: hidden;
175
+ text-overflow: ellipsis;
176
+ white-space: nowrap;
177
+ }
178
+ }
179
+ }
@@ -0,0 +1,10 @@
1
+ export interface BidItem {
2
+ id: string;
3
+ name: string;
4
+ bidNo__c?: string;
5
+ status__c?: string;
6
+ totalBudget__c?: number;
7
+ deadline__c?: string | number;
8
+ purchaser__c?: string;
9
+ [k: string]: any;
10
+ }
@@ -0,0 +1,140 @@
1
+ import * as React from 'react';
2
+ import { Card, Typography, Space, Button, Tag } from 'antd';
3
+ import {
4
+ SaveOutlined,
5
+ ReloadOutlined,
6
+ WarningOutlined,
7
+ FileTextOutlined,
8
+ BankOutlined,
9
+ ClockCircleOutlined,
10
+ } from '@ant-design/icons';
11
+ import type { BidPackageHeaderProps } from '../types';
12
+ import { calcPackageTotal, formatMoney, formatDate } from '../utils';
13
+
14
+ const { Text } = Typography;
15
+
16
+ export function BidPackageHeader({
17
+ displayTitle,
18
+ totalBudget,
19
+ propsBudget,
20
+ packages,
21
+ saving,
22
+ loading,
23
+ currentBidNo,
24
+ currentStatus,
25
+ currentPurchaser,
26
+ currentDeadline,
27
+ onReload,
28
+ onSave,
29
+ }: BidPackageHeaderProps) {
30
+ const resolvedBudget = totalBudget ?? propsBudget;
31
+
32
+ const grandTotal = packages.reduce(
33
+ (acc, pkg) => acc + calcPackageTotal(pkg.items),
34
+ 0,
35
+ );
36
+ const dirtyCount = packages.reduce(
37
+ (acc, pkg) => acc + pkg.items.filter((it) => it.isDirty__c).length,
38
+ 0,
39
+ );
40
+ const overCount = packages.filter(
41
+ (pkg) => calcPackageTotal(pkg.items) > pkg.limitPrice,
42
+ ).length;
43
+
44
+ return (
45
+ <Card className="bid-header-card" size="small">
46
+ <div className="header-row">
47
+ <div className="header-info">
48
+ <h3 className="header-title">{displayTitle}</h3>
49
+ {currentBidNo ? (
50
+ <div className="bid-detail-bar">
51
+ <span className="detail-item">
52
+ <FileTextOutlined /> {currentBidNo}
53
+ </span>
54
+ {currentStatus && (
55
+ <Tag
56
+ color={
57
+ currentStatus === '已提交'
58
+ ? 'success'
59
+ : currentStatus === '已校验'
60
+ ? 'processing'
61
+ : currentStatus === '退回'
62
+ ? 'error'
63
+ : 'default'
64
+ }
65
+ >
66
+ {currentStatus}
67
+ </Tag>
68
+ )}
69
+ {currentPurchaser && (
70
+ <span className="detail-item">
71
+ <BankOutlined /> {currentPurchaser}
72
+ </span>
73
+ )}
74
+ {currentDeadline && (
75
+ <span className="detail-item">
76
+ <ClockCircleOutlined /> 截止 {formatDate(currentDeadline)}
77
+ </span>
78
+ )}
79
+ </div>
80
+ ) : (
81
+ <Text type="secondary">
82
+ 点击左侧标书列表选择标书,或展开标包查看明细
83
+ </Text>
84
+ )}
85
+ </div>
86
+ <div className="header-stats">
87
+ {resolvedBudget != null && (
88
+ <div className="stat-item">
89
+ <span className="stat-label">预算总额</span>
90
+ <span className="stat-value budget">
91
+ {formatMoney(resolvedBudget)}
92
+ </span>
93
+ </div>
94
+ )}
95
+ <div className="stat-item">
96
+ <span className="stat-label">投标总计</span>
97
+ <span
98
+ className={`stat-value ${
99
+ resolvedBudget != null && grandTotal > resolvedBudget
100
+ ? 'over'
101
+ : 'normal'
102
+ }`}
103
+ >
104
+ {formatMoney(grandTotal)}
105
+ </span>
106
+ </div>
107
+ {overCount > 0 && (
108
+ <div className="stat-item">
109
+ <Tag color="error" icon={<WarningOutlined />}>
110
+ {overCount} 个标包超支
111
+ </Tag>
112
+ </div>
113
+ )}
114
+ </div>
115
+ </div>
116
+ <div className="header-actions">
117
+ <Space>
118
+ <Button
119
+ icon={<ReloadOutlined />}
120
+ onClick={onReload}
121
+ loading={loading}
122
+ size="small"
123
+ >
124
+ 刷新
125
+ </Button>
126
+ <Button
127
+ type="primary"
128
+ icon={<SaveOutlined />}
129
+ onClick={onSave}
130
+ loading={saving}
131
+ disabled={dirtyCount === 0}
132
+ size="small"
133
+ >
134
+ 保存报价{dirtyCount > 0 ? ` (${dirtyCount})` : ''}
135
+ </Button>
136
+ </Space>
137
+ </div>
138
+ </Card>
139
+ );
140
+ }