@spacecorexdev/core 0.0.4 → 0.0.5

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/package.json +2 -36
  2. package/src/api/_base.ts +243 -0
  3. package/src/api/index.ts +17 -0
  4. package/src/api/project.ts +1345 -0
  5. package/src/api/user.ts +1174 -0
  6. package/src/contract.ts +50 -0
  7. package/src/hooks/index.ts +2 -0
  8. package/{dist/hooks/index.js → src/hooks/useLongPress.ts} +53 -49
  9. package/src/hooks/useOnlineStatus.ts +22 -0
  10. package/src/index.ts +14 -0
  11. package/src/types/id.ts +2 -0
  12. package/src/types/index.ts +5 -0
  13. package/src/types/project/base.ts +63 -0
  14. package/src/types/project/contract.ts +79 -0
  15. package/src/types/project/contractStatus.tsx +15 -0
  16. package/src/types/project/index.ts +5 -0
  17. package/src/types/project/member.ts +46 -0
  18. package/src/types/project/progress.ts +43 -0
  19. package/src/types/projectRole.ts +17 -0
  20. package/src/types/theme.ts +1 -0
  21. package/src/types/user/index.ts +1 -0
  22. package/src/types/user/role.ts +7 -0
  23. package/src/ui/CommentTimeline/index.tsx +330 -0
  24. package/src/ui/FileManager/FileContextMenu.tsx +628 -0
  25. package/src/ui/FileManager/FileGridView.tsx +529 -0
  26. package/src/ui/FileManager/FileTableView.tsx +405 -0
  27. package/src/ui/FileManager/FileToolbar.tsx +119 -0
  28. package/src/ui/FileManager/FileVersionHistoryModal.tsx +175 -0
  29. package/src/ui/FileManager/MoveCopyToProjectModal.tsx +119 -0
  30. package/src/ui/FileManager/ShareToWechatModal.tsx +419 -0
  31. package/src/ui/FileManager/hooks/useFileManagerActions.ts +2532 -0
  32. package/src/ui/FileManager/hooks/useFileManagerState.ts +419 -0
  33. package/src/ui/FileManager/index.tsx +580 -0
  34. package/src/ui/FileManager/projectFileManagerApi.ts +57 -0
  35. package/src/ui/FileManager/types.ts +184 -0
  36. package/src/ui/FileManager/utils/fileDeltaWorker.ts +193 -0
  37. package/src/ui/FileManager/utils/fileTree.ts +178 -0
  38. package/src/ui/FileManager/utils/fileUpload.ts +714 -0
  39. package/src/ui/FileManager/utils/fileUtils.ts +65 -0
  40. package/src/ui/InvoiceRecordsList/index.tsx +813 -0
  41. package/src/ui/MyFileSelectorModal.tsx +261 -0
  42. package/src/ui/ProjectSelector/index.tsx +472 -0
  43. package/src/ui/ProjectSelector/projectCache.ts +40 -0
  44. package/src/ui/RoleSelector/index.tsx +473 -0
  45. package/src/ui/RoleSelector/roleCache.ts +40 -0
  46. package/src/ui/UIAlert.tsx +399 -0
  47. package/src/ui/UIAlertExample.tsx +129 -0
  48. package/src/ui/UIConfirm.tsx +335 -0
  49. package/src/ui/UIConfirmExample.tsx +165 -0
  50. package/src/ui/UIDatePicker.tsx +146 -0
  51. package/src/ui/UIDateRangePicker.tsx +38 -0
  52. package/src/ui/UIFilePreview/ExcelEditor/index.tsx +617 -0
  53. package/src/ui/UIFilePreview/ExcelEditor/types.ts +24 -0
  54. package/src/ui/UIFilePreview/ExportDropdown.css +85 -0
  55. package/src/ui/UIFilePreview/ExportDropdown.tsx +109 -0
  56. package/src/ui/UIFilePreview/IndexedDBUtils.ts +564 -0
  57. package/src/ui/UIFilePreview/MarkdownEditor/exportMarkdownPdf.ts +576 -0
  58. package/src/ui/UIFilePreview/MarkdownEditor/index.tsx +677 -0
  59. package/src/ui/UIFilePreview/MarkdownEditor/markdownEditor.css +1005 -0
  60. package/src/ui/UIFilePreview/MarkdownEditor/types.ts +15 -0
  61. package/src/ui/UIFilePreview/PPTXEditor/index.tsx +602 -0
  62. package/src/ui/UIFilePreview/RichDocEditor/exportRDocMarkdown.ts +77 -0
  63. package/src/ui/UIFilePreview/RichDocEditor/exportRDocPdf.ts +374 -0
  64. package/src/ui/UIFilePreview/RichDocEditor/index.tsx +730 -0
  65. package/src/ui/UIFilePreview/RichDocEditor/richdoc-editor.css +59 -0
  66. package/src/ui/UIFilePreview/UIFilePreview.tsx +611 -0
  67. package/src/ui/UIFilePreview/WordEditor/index.tsx +3933 -0
  68. package/src/ui/UIFilePreview/WordEditor/style.ts +1213 -0
  69. package/src/ui/UIFilePreview/WordEditor/word-editor.css +999 -0
  70. package/src/ui/UIFilePreview/filePreview.css +193 -0
  71. package/src/ui/UIFilePreview/filetypes/archive.tsx +66 -0
  72. package/src/ui/UIFilePreview/filetypes/cad.tsx +287 -0
  73. package/src/ui/UIFilePreview/filetypes/excel.tsx +355 -0
  74. package/src/ui/UIFilePreview/filetypes/image.tsx +20 -0
  75. package/src/ui/UIFilePreview/filetypes/imageLoader.ts +63 -0
  76. package/src/ui/UIFilePreview/filetypes/pdf.tsx +156 -0
  77. package/src/ui/UIFilePreview/filetypes/ppt.tsx +535 -0
  78. package/src/ui/UIFilePreview/filetypes/pptExportPdf.ts +523 -0
  79. package/src/ui/UIFilePreview/filetypes/video.tsx +482 -0
  80. package/src/ui/UIFilePreview/filetypes/word.tsx +245 -0
  81. package/src/ui/UIFilePreview/filetypes/wordExportMarkdown.ts +86 -0
  82. package/src/ui/UIFilePreview/filetypes/wordExportPdf.tsx +427 -0
  83. package/src/ui/UIFilePreview/index.ts +35 -0
  84. package/src/ui/UIFilePreview/pdfPagination.ts +143 -0
  85. package/src/ui/UIFilePreview/previewUtils.tsx +531 -0
  86. package/src/ui/UIFileUpload.tsx +382 -0
  87. package/src/ui/UIImageUpload.tsx +195 -0
  88. package/src/ui/UILoading.tsx +255 -0
  89. package/src/ui/UILoadingExample.tsx +139 -0
  90. package/src/ui/UISelect.tsx +105 -0
  91. package/src/ui/UIToast.tsx +381 -0
  92. package/src/ui/UIToastExample.tsx +69 -0
  93. package/src/ui/UIToastSingle.tsx +279 -0
  94. package/src/ui/UIViewToggle.tsx +64 -0
  95. package/src/ui/UserSelector/index.tsx +583 -0
  96. package/src/ui/index.ts +84 -0
  97. package/src/ui/upload/image.ts +135 -0
  98. package/src/ui/upload/index.ts +73 -0
  99. package/src/ui/upload/submitFile.ts +106 -0
  100. package/src/ui/upload/submitForm.ts +124 -0
  101. package/src/ui/upload/upload.err.ts +15 -0
  102. package/src/ui/upload/upload.ts +250 -0
  103. package/src/utils/CacheDepartmentInfo.ts +372 -0
  104. package/src/utils/CacheFileContent.ts +315 -0
  105. package/src/utils/CachePermissionInfo.ts +235 -0
  106. package/src/utils/CacheRoleInfo.ts +303 -0
  107. package/src/utils/CacheUserInfo.ts +818 -0
  108. package/src/utils/CacheViewToggleInfo.ts +182 -0
  109. package/src/utils/MessageContentUtils.ts +268 -0
  110. package/src/utils/clipboard.ts +70 -0
  111. package/src/utils/companyEmail.ts +19 -0
  112. package/src/utils/forbidDebugger.ts +59 -0
  113. package/src/utils/formatters.ts +94 -0
  114. package/src/utils/htmlUtils.tsx +59 -0
  115. package/src/utils/index.ts +18 -0
  116. package/src/utils/keyboard.ts +114 -0
  117. package/src/utils/mammothApi.ts +16 -0
  118. package/src/utils/polyfills.ts +928 -0
  119. package/src/utils/regex.ts +14 -0
  120. package/src/utils/storage.ts +95 -0
  121. package/src/utils/workerBootstrap.ts +87 -0
  122. package/dist/api/index.js +0 -1553
  123. package/dist/contract.js +0 -5
  124. package/dist/index.js +0 -4492
  125. package/dist/types/index.js +0 -49
  126. package/dist/ui/index.css +0 -1876
  127. package/dist/ui/index.js +0 -22245
  128. package/dist/utils/index.js +0 -4296
  129. /package/{dist → src}/styles/ant-modal.css +0 -0
  130. /package/{dist → src}/styles/ant-spin.css +0 -0
  131. /package/{dist → src}/styles/ant-table.css +0 -0
  132. /package/{dist → src}/styles/index.css +0 -0
@@ -0,0 +1,381 @@
1
+ /* eslint-disable react-refresh/only-export-components */
2
+ /**
3
+ * UIToast - 全局消息提示组件
4
+ *
5
+ * 使用示例:
6
+ *
7
+ * 1. 直接调用 API(推荐):
8
+ * import uiToast from './UIToast';
9
+ *
10
+ * // 简单消息
11
+ * uiToast.success('操作成功');
12
+ * uiToast.error('操作失败');
13
+ * uiToast.info('提示信息');
14
+ * uiToast.warning('警告信息');
15
+ *
16
+ * // 完整配置
17
+ * uiToast.success({
18
+ * message: '操作成功',
19
+ * descs: '这是一个详细描述',
20
+ * duration: 5, // 秒
21
+ * placement: 'topRight',
22
+ * onClose: () => console.log('Toast已关闭')
23
+ * });
24
+ *
25
+ * 2. 使用组件形式(较少使用):
26
+ * import { UIToast } from './UIToast';
27
+ *
28
+ * <UIToast type="success" message="操作成功" />
29
+ */
30
+
31
+ import React, { useEffect, useState, useRef } from 'react';
32
+ import { notification } from 'antd';
33
+ import type { NotificationInstance } from 'antd/es/notification/interface';
34
+ import { CheckCircleOutlined, CloseCircleOutlined, InfoCircleOutlined, WarningOutlined } from '@ant-design/icons';
35
+ import type { NotificationArgsProps } from 'antd';
36
+
37
+ // Toast类型定义
38
+ export type UIToastType = 'success' | 'error' | 'info' | 'warning';
39
+
40
+ // Toast组件属性接口
41
+ export interface UIToastProps {
42
+ type: UIToastType;
43
+ message: string;
44
+ descs?: string;
45
+ duration?: number;
46
+ placement?: NotificationArgsProps['placement'];
47
+ onClose?: () => void;
48
+ }
49
+
50
+ // 图标映射
51
+ const iconMap = {
52
+ success: <CheckCircleOutlined style={{ color: '#52c41a' }} />,
53
+ error: <CloseCircleOutlined style={{ color: '#ff4d4f' }} />,
54
+ info: <InfoCircleOutlined style={{ color: '#1677ff' }} />,
55
+ warning: <WarningOutlined style={{ color: '#faad14' }} />
56
+ };
57
+
58
+ // Toast组件
59
+ export const UIToast: React.FC<UIToastProps> = ({
60
+ type,
61
+ message,
62
+ descs = '',
63
+ duration = 3,
64
+ placement = 'topRight',
65
+ onClose
66
+ }) => {
67
+ const [api, contextHolder] = notification.useNotification();
68
+ const [isVisible, setIsVisible] = useState(true);
69
+
70
+ useEffect(() => {
71
+ const notificationConfig = {
72
+ message,
73
+ descs,
74
+ placement,
75
+ duration,
76
+ icon: iconMap[type],
77
+ onClose: () => {
78
+ setIsVisible(false);
79
+ onClose?.();
80
+ }
81
+ };
82
+
83
+ // 根据类型显示不同的通知
84
+ if (isVisible) {
85
+ switch (type) {
86
+ case 'success':
87
+ api.success(notificationConfig);
88
+ break;
89
+ case 'error':
90
+ api.error(notificationConfig);
91
+ break;
92
+ case 'info':
93
+ api.info(notificationConfig);
94
+ break;
95
+ case 'warning':
96
+ api.warning(notificationConfig);
97
+ break;
98
+ default:
99
+ api.info(notificationConfig);
100
+ }
101
+ }
102
+ }, [type, message, descs, duration, placement, isVisible, api, onClose]);
103
+
104
+ return <>{contextHolder}</>;
105
+ };
106
+
107
+ // 配置全局消息提示样式
108
+ notification.config({
109
+ placement: 'topRight',
110
+ duration: 3,
111
+ // 确保 toast 显示在全屏 Modal(z-index 1000+)之上,避免被弹窗遮挡
112
+ ...({ zIndex: 10000 } as Record<string, unknown>),
113
+ });
114
+
115
+ // Singleton Toast 全局唯一Toast管理器
116
+ interface SingletonToastConfig {
117
+ key: string;
118
+ type: UIToastType;
119
+ message: string;
120
+ descs?: string;
121
+ duration: number;
122
+ placement?: NotificationArgsProps['placement'];
123
+ onClose?: () => void;
124
+ }
125
+
126
+ interface SingletonToastState {
127
+ key: string;
128
+ type: UIToastType;
129
+ message: string;
130
+ descs?: string;
131
+ duration: number;
132
+ placement?: NotificationArgsProps['placement'];
133
+ timer: NodeJS.Timeout | null;
134
+ }
135
+
136
+ class SingletonToastManager {
137
+ private static instance: SingletonToastManager;
138
+ private currentToast: SingletonToastState | null = null;
139
+ private api: NotificationInstance | null = null;
140
+ private isInitialized = false;
141
+ private pendingToast: SingletonToastConfig | null = null;
142
+
143
+ private constructor() {}
144
+
145
+ static getInstance(): SingletonToastManager {
146
+ if (!SingletonToastManager.instance) {
147
+ SingletonToastManager.instance = new SingletonToastManager();
148
+ }
149
+ return SingletonToastManager.instance;
150
+ }
151
+
152
+ // 初始化 API
153
+ init(api: NotificationInstance) {
154
+ this.api = api;
155
+ this.isInitialized = true;
156
+
157
+ // 如果有等待中的 toast,立即显示
158
+ if (this.pendingToast) {
159
+ const config = this.pendingToast;
160
+ this.pendingToast = null;
161
+ this.show(config);
162
+ }
163
+ }
164
+
165
+ // 显示全局唯一Toast
166
+ show(config: SingletonToastConfig) {
167
+ const { key, type, message, descs, duration, placement, onClose } = config;
168
+
169
+ // 如果 API 未初始化,保存配置等待初始化
170
+ if (!this.isInitialized || !this.api) {
171
+ this.pendingToast = config;
172
+ return;
173
+ }
174
+
175
+ // 清除之前的定时器
176
+ if (this.currentToast?.timer) {
177
+ clearTimeout(this.currentToast.timer);
178
+ }
179
+
180
+ // 如果是同一个类型的 toast(相同 key),只更新内容并重置时间
181
+ if (this.currentToast && this.currentToast.key === key) {
182
+ // 销毁旧的通知
183
+ notification.destroy(key);
184
+
185
+ // 重新创建(通过重新调用来实现时间重置)
186
+ this.createNotification({ key, type, message, descs, duration, placement, onClose });
187
+ } else {
188
+ // 销毁之前的 toast(如果存在不同 key)
189
+ if (this.currentToast) {
190
+ notification.destroy(this.currentToast.key);
191
+ }
192
+
193
+ // 创建新的 toast
194
+ this.createNotification({ key, type, message, descs, duration, placement, onClose });
195
+ }
196
+ }
197
+
198
+ // 创建通知
199
+ private createNotification(config: SingletonToastConfig) {
200
+ if (!this.api) return;
201
+
202
+ const { key, type, message, descs, duration, placement, onClose } = config;
203
+
204
+ const notificationMethod = {
205
+ success: this.api.success.bind(this.api),
206
+ error: this.api.error.bind(this.api),
207
+ info: this.api.info.bind(this.api),
208
+ warning: this.api.warning.bind(this.api)
209
+ }[type];
210
+
211
+ notificationMethod({
212
+ key,
213
+ message,
214
+ description: descs,
215
+ duration,
216
+ placement: placement || 'topRight',
217
+ icon: iconMap[type],
218
+ onClose: () => {
219
+ if (this.currentToast?.key === key) {
220
+ if (this.currentToast.timer) {
221
+ clearTimeout(this.currentToast.timer);
222
+ }
223
+ this.currentToast = null;
224
+ }
225
+ onClose?.();
226
+ }
227
+ });
228
+
229
+ // 保存当前 toast 状态
230
+ this.currentToast = {
231
+ key,
232
+ type,
233
+ message,
234
+ descs,
235
+ duration,
236
+ placement,
237
+ timer: null
238
+ };
239
+ }
240
+
241
+ // 关闭当前 toast
242
+ close() {
243
+ if (this.currentToast) {
244
+ if (this.currentToast.timer) {
245
+ clearTimeout(this.currentToast.timer);
246
+ }
247
+ notification.destroy(this.currentToast.key);
248
+ this.currentToast = null;
249
+ }
250
+ }
251
+
252
+ // 销毁所有 toast
253
+ destroy() {
254
+ this.close();
255
+ notification.destroy();
256
+ }
257
+ }
258
+
259
+ // 获取 SingletonToastManager 实例
260
+ const singletonManager = SingletonToastManager.getInstance();
261
+
262
+ // 辅助函数:解析 toast 选项
263
+ function parseToastOptions(options: UIToastOptions | string): UIToastOptions {
264
+ if (typeof options === 'string') {
265
+ return { message: options, duration: 3 };
266
+ }
267
+ return options;
268
+ }
269
+
270
+ // 辅助函数:获取图标
271
+ function getIcon(type: UIToastType) {
272
+ return iconMap[type];
273
+ }
274
+
275
+ // 通用toast选项接口
276
+ interface UIToastOptions {
277
+ message: string;
278
+ descs?: string;
279
+ duration?: number;
280
+ placement?: NotificationArgsProps['placement'];
281
+ onClose?: () => void;
282
+ }
283
+
284
+ // 创建toast API
285
+ const uiToast = {
286
+ success: (options: UIToastOptions | string) => {
287
+ if (!options) return;
288
+ const config = parseToastOptions(options);
289
+
290
+ notification.success({
291
+ message: config.message,
292
+ description: config.descs,
293
+ duration: config.duration,
294
+ placement: config.placement,
295
+ icon: getIcon('success'),
296
+ onClose: config.onClose
297
+ });
298
+ },
299
+
300
+ error: (options: UIToastOptions | string) => {
301
+ if (!options) return;
302
+ const config = parseToastOptions(options);
303
+
304
+ notification.error({
305
+ message: config.message,
306
+ description: config.descs,
307
+ duration: config.duration,
308
+ placement: config.placement,
309
+ icon: getIcon('error'),
310
+ onClose: config.onClose
311
+ });
312
+ },
313
+
314
+ info: (options: UIToastOptions | string) => {
315
+ if (!options) return;
316
+ const config = parseToastOptions(options);
317
+
318
+ notification.info({
319
+ message: config.message,
320
+ description: config.descs,
321
+ duration: config.duration,
322
+ placement: config.placement,
323
+ icon: getIcon('info'),
324
+ onClose: config.onClose
325
+ });
326
+ },
327
+
328
+ warning: (options: UIToastOptions | string) => {
329
+ if (!options) return;
330
+ const config = parseToastOptions(options);
331
+
332
+ notification.warning({
333
+ message: config.message,
334
+ description: config.descs,
335
+ duration: config.duration,
336
+ placement: config.placement,
337
+ icon: getIcon('warning'),
338
+ onClose: config.onClose
339
+ });
340
+ },
341
+
342
+ // 自定义类型的toast
343
+ custom: (type: UIToastType, options: UIToastOptions) => {
344
+ const { message, descs, duration, placement, onClose } = options;
345
+
346
+ notification[type]({
347
+ message,
348
+ description: descs,
349
+ duration,
350
+ placement,
351
+ icon: getIcon(type),
352
+ onClose
353
+ });
354
+ }
355
+ };
356
+
357
+ // SingletonToast 组件 - 用于初始化 Singleton API
358
+ interface SingletonToastProviderProps {
359
+ children: React.ReactNode;
360
+ }
361
+
362
+ export const SingletonToastProvider: React.FC<SingletonToastProviderProps> = ({ children }) => {
363
+ const [api, contextHolder] = notification.useNotification();
364
+ const hasInitialized = useRef(false);
365
+
366
+ useEffect(() => {
367
+ if (!hasInitialized.current) {
368
+ singletonManager.init(api);
369
+ hasInitialized.current = true;
370
+ }
371
+ }, [api]);
372
+
373
+ return (
374
+ <>
375
+ {contextHolder}
376
+ {children}
377
+ </>
378
+ );
379
+ };
380
+
381
+ export default uiToast;
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ import { Button, Space } from 'antd';
3
+ import uiToast from './UIToast';
4
+
5
+ const ToastExample: React.FC = () => {
6
+ // 简单字符串用法
7
+ const showSimpleSuccess = () => {
8
+ uiToast.success('操作成功!');
9
+ };
10
+
11
+ // 带描述的用法
12
+ const showDetailedError = () => {
13
+ uiToast.error({
14
+ message: '操作失败',
15
+ descs: '服务器连接超时,请稍后再试。',
16
+ duration: 5
17
+ });
18
+ };
19
+
20
+ // 信息提示
21
+ const showInfo = () => {
22
+ uiToast.info({
23
+ message: '系统通知',
24
+ descs: '系统将在30分钟后进行维护。',
25
+ placement: 'top'
26
+ });
27
+ };
28
+
29
+ // 警告提示
30
+ const showWarning = () => {
31
+ uiToast.warning('请注意,您的操作可能导致数据丢失!');
32
+ };
33
+
34
+ // 自定义提示
35
+ const showCustom = () => {
36
+ uiToast.custom('info', {
37
+ message: '自定义提示',
38
+ descs: '这是使用custom方法创建的提示',
39
+ duration: 4,
40
+ placement: 'bottomRight',
41
+ onClose: () => console.log('提示已关闭')
42
+ });
43
+ };
44
+
45
+ return (
46
+ <div style={{ padding: '20px' }}>
47
+ <h2>Toast 提示示例</h2>
48
+ <Space direction="vertical" style={{ width: '100%' }}>
49
+ <Button type="primary" onClick={showSimpleSuccess}>
50
+ 显示成功提示
51
+ </Button>
52
+ <Button danger onClick={showDetailedError}>
53
+ 显示错误提示(带详情)
54
+ </Button>
55
+ <Button onClick={showInfo}>
56
+ 显示信息提示(顶部)
57
+ </Button>
58
+ <Button onClick={showWarning}>
59
+ 显示警告提示
60
+ </Button>
61
+ <Button type="dashed" onClick={showCustom}>
62
+ 显示自定义提示(右下角)
63
+ </Button>
64
+ </Space>
65
+ </div>
66
+ );
67
+ };
68
+
69
+ export default ToastExample;