@appthen/cli 1.2.10 → 1.2.12

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 (173) hide show
  1. package/.gitignore +1 -0
  2. package/bin/main.js +92 -0
  3. package/dist/index.js +7014 -14988
  4. package/package.json +8 -1
  5. package/tests/test-app/.appthen/shadow-space-100001-test-app-e99876b1.json +1862 -0
  6. package/tests/test-app/.appthen/space-config.json +8 -0
  7. package/tests/test-app/docs/AI-Workflow.flow +112 -0
  8. package/tests/test-app/docs/Logic-1.flow +16 -0
  9. package/tests/test-app/docs/Logic.flow +16 -0
  10. package/tests/test-app/docs/Project-Blueprint-1.flow +119 -0
  11. package/tests/test-app/docs/Project-Blueprint.flow +119 -0
  12. package/tests/test-app/docs/README.md +3 -0
  13. package/tests/test-app/docs/claude.md +194 -0
  14. package/tests/test-app/docs/page_requirement_analysis.md +149 -0
  15. package/tests/test-app/docs//345/267/245/345/215/225/347/256/241/347/220/206/347/263/273/347/273/237/350/257/246/347/273/206/350/256/276/350/256/241.md +377 -0
  16. package/tests/test-app/src/apis/AddTodoPost.api.ts +42 -0
  17. package/tests/test-app/src/apis/DeleteTodoPost.api.ts +32 -0
  18. package/tests/test-app/src/apis/GetListPost.api.ts +38 -0
  19. package/tests/test-app/src/apis/TicketAttachmentUploadPost.api.ts +42 -0
  20. package/tests/test-app/src/apis/UpdateTodoPost.api.ts +46 -0
  21. package/tests/test-app/src/app.css +15 -0
  22. package/tests/test-app/src/cloud_functions/ticket|attachment|upload.node.ts +86 -0
  23. package/tests/test-app/src/cloud_functions/ticket|comment|add.node.ts +65 -0
  24. package/tests/test-app/src/cloud_functions/types|entity|Ticket.node.ts +88 -0
  25. package/tests/test-app/src/cloud_functions/types|entity|TicketAttachment.node.ts +70 -0
  26. package/tests/test-app/src/cloud_functions/types|entity|TicketCategory.node.ts +56 -0
  27. package/tests/test-app/src/cloud_functions/types|entity|TicketComment.node.ts +62 -0
  28. package/tests/test-app/src/cloud_functions/types|entity|TicketHistory.node.ts +74 -0
  29. package/tests/test-app/src/cloud_functions/types|entity|TicketPriority.node.ts +68 -0
  30. package/tests/test-app/src/cloud_functions/types|entity|TicketStatus.node.ts +63 -0
  31. package/tests/test-app/src/cloud_functions/types|models|CreateTicketParams.node.ts +20 -0
  32. package/tests/test-app/src/cloud_functions/types|models|TicketListParams.node.ts +30 -0
  33. package/tests/test-app/src/cloud_functions/types|models|UpdateTicketParams.node.ts +22 -0
  34. package/tests/test-app/src/components/Button.js +11 -0
  35. package/tests/test-app/src/components/MessageCenter.tsx +506 -0
  36. package/tests/test-app/src/components/MouduleDemoNzp.tsx +40 -0
  37. package/tests/test-app/src/components/Timeline.tsx +145 -0
  38. package/tests/test-app/src/index.ts +2 -0
  39. package/tests/test-app/src/modules/work_order_module/apis/TicketCommentAddPost.api.ts +48 -0
  40. package/tests/test-app/src/modules/work_order_module/apis/TicketCreatePost.api.ts +52 -0
  41. package/tests/test-app/src/modules/work_order_module/apis/TicketDeleteDelete.api.ts +39 -0
  42. package/tests/test-app/src/modules/work_order_module/apis/TicketDetailGet.api.ts +39 -0
  43. package/tests/test-app/src/modules/work_order_module/apis/TicketListGet.api.ts +61 -0
  44. package/tests/test-app/src/modules/work_order_module/apis/TicketUpdatePut.api.ts +57 -0
  45. package/tests/test-app/src/modules/work_order_module/apis/TrainDoorFaultListGet.ts +76 -0
  46. package/tests/test-app/src/modules/work_order_module/apis/TrainDoorListGet.ts +76 -0
  47. package/tests/test-app/src/modules/work_order_module/apis/TrainDoorOperationRecordsGet.ts +284 -0
  48. package/tests/test-app/src/modules/work_order_module/apis/TrainDoorStatisticsGet.ts +96 -0
  49. package/tests/test-app/src/modules/work_order_module/cloud_function/category|list.node.ts +40 -0
  50. package/tests/test-app/src/modules/work_order_module/cloud_function/priority|list.node.ts +26 -0
  51. package/tests/test-app/src/modules/work_order_module/cloud_function/status|list.node.ts +26 -0
  52. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|create.node.ts +54 -0
  53. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|delete.node.ts +55 -0
  54. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|detail.node.ts +65 -0
  55. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|list.node.ts +85 -0
  56. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|update.node.ts +73 -0
  57. package/tests/test-app/src/modules/work_order_module/data_model/Ticket.m.ts +85 -0
  58. package/tests/test-app/src/modules/work_order_module/data_model/TicketCategory.m.ts +53 -0
  59. package/tests/test-app/src/modules/work_order_module/data_model/TicketStatus.m.ts +60 -0
  60. package/tests/test-app/src/modules/work_order_module//345/267/245/345/215/225/347/263/273/347/273/237/344/272/247/345/223/201/350/256/276/350/256/241/346/226/207/346/241/243.md +301 -0
  61. package/tests/test-app/src/modules/work_order_module//345/267/245/345/215/225/347/263/273/347/273/237/345/274/200/345/217/221/344/273/273/345/212/241/345/210/206/345/267/245/346/226/207/346/241/243.md +345 -0
  62. package/tests/test-app/src/pages/CustomerManagement.tsx +535 -0
  63. package/tests/test-app/src/pages/CyberpunkDashboard.tsx +348 -0
  64. package/tests/test-app/src/pages/CyberpunkProductManagement.tsx +637 -0
  65. package/tests/test-app/src/pages/CyberpunkUserList.tsx +316 -0
  66. package/tests/test-app/src/pages/DashboardV2.tsx +334 -0
  67. package/tests/test-app/src/pages/DataReport.tsx +298 -0
  68. package/tests/test-app/src/pages/DataStatistics.tsx +317 -0
  69. package/tests/test-app/src/pages/DepartmentManagement.tsx +503 -0
  70. package/tests/test-app/src/pages/FileExplorer.tsx +441 -0
  71. package/tests/test-app/src/pages/OrderDetail.tsx +393 -0
  72. package/tests/test-app/src/pages/ProductManagement.tsx +521 -0
  73. package/tests/test-app/src/pages/ProjectTimeline.tsx +395 -0
  74. package/tests/test-app/src/pages/RoleManagement.tsx +523 -0
  75. package/tests/test-app/src/pages/SLAManagement.tsx +668 -0
  76. package/tests/test-app/src/pages/StaticCyberpunkDashboard.tsx +462 -0
  77. package/tests/test-app/src/pages/StaticCyberpunkUserList.tsx +567 -0
  78. package/tests/test-app/src/pages/StudentWeaknessList.tsx +547 -0
  79. package/tests/test-app/src/pages/SystemSettings.tsx +422 -0
  80. package/tests/test-app/src/pages/TaskManagement.tsx +467 -0
  81. package/tests/test-app/src/pages/TicketCreate.tsx +27 -0
  82. package/tests/test-app/src/pages/TicketDetail.tsx +27 -0
  83. package/tests/test-app/src/pages/TicketList.tsx +27 -0
  84. package/tests/test-app/src/pages/TicketManagement.tsx +402 -0
  85. package/tests/test-app/src/pages/TicketManagementPage.tsx +1238 -0
  86. package/tests/test-app/src/pages/UserProfile.tsx +404 -0
  87. package/tests/test-app/src/pages/VisualAIIDEUpgrade.tsx +245 -0
  88. package/tests/test-app/src/pages/WorkflowDesigner.tsx +434 -0
  89. package/tests/test-app/src/pages/admin/dashboard.tsx +591 -0
  90. package/tests/test-app/src/pages/appthen_guide/ComponentTreeUnderstanding.tsx +26 -0
  91. package/tests/test-app/src/pages/appthen_guide/DataBindingLearning.tsx +26 -0
  92. package/tests/test-app/src/pages/article-list.tsx +222 -0
  93. package/tests/test-app/src/pages/babyProductRecommendationPage.tsx +168 -0
  94. package/tests/test-app/src/pages/back-end/adminRootLayout.tsx +155 -0
  95. package/tests/test-app/src/pages/back-end/adminRootLayout10.tsx +157 -0
  96. package/tests/test-app/src/pages/back-end/adminRootLayout2.tsx +156 -0
  97. package/tests/test-app/src/pages/back-end/adminRootLayout3.tsx +156 -0
  98. package/tests/test-app/src/pages/back-end/adminRootLayout4.tsx +157 -0
  99. package/tests/test-app/src/pages/back-end/adminRootLayout5.tsx +157 -0
  100. package/tests/test-app/src/pages/back-end/adminRootLayout6.tsx +157 -0
  101. package/tests/test-app/src/pages/back-end/adminRootLayout7.tsx +157 -0
  102. package/tests/test-app/src/pages/back-end/adminRootLayout8.tsx +157 -0
  103. package/tests/test-app/src/pages/back-end/adminRootLayout9.tsx +157 -0
  104. package/tests/test-app/src/pages/back-end/backgroundManagementSystem.css +5 -0
  105. package/tests/test-app/src/pages/back-end/backgroundManagementSystem.tsx +1745 -0
  106. package/tests/test-app/src/pages/category-list.tsx +179 -0
  107. package/tests/test-app/src/pages/comment-list.tsx +194 -0
  108. package/tests/test-app/src/pages/component/WorkOrderCard.tsx +140 -0
  109. package/tests/test-app/src/pages/cover.tsx +42 -0
  110. package/tests/test-app/src/pages/cyberpunk/cyberpunkCRMPage.tsx +1299 -0
  111. package/tests/test-app/src/pages/data-analytics.tsx +1872 -0
  112. package/tests/test-app/src/pages/data-overview.tsx +600 -0
  113. package/tests/test-app/src/pages/data_dashboard/blueBrightGreenTechnologyWind.css +181 -0
  114. package/tests/test-app/src/pages/data_dashboard/blueBrightGreenTechnologyWind.tsx +225 -0
  115. package/tests/test-app/src/pages/data_dashboard/blueLargeScreen.css +181 -0
  116. package/tests/test-app/src/pages/data_dashboard/blueLargeScreen.tsx +138 -0
  117. package/tests/test-app/src/pages/data_dashboard/component_library/BlueBrightGreenBorder.tsx +47 -0
  118. package/tests/test-app/src/pages/data_dashboard/component_library/FullScreenContainer.tsx +133 -0
  119. package/tests/test-app/src/pages/demo-error-page.tsx +119 -0
  120. package/tests/test-app/src/pages/department-list.tsx +183 -0
  121. package/tests/test-app/src/pages/description_of_mock_interface.md +32 -0
  122. package/tests/test-app/src/pages/digitalLargeScreen.css +181 -0
  123. package/tests/test-app/src/pages/digitalLargeScreen.tsx +1417 -0
  124. package/tests/test-app/src/pages/goods-list.tsx +233 -0
  125. package/tests/test-app/src/pages/housekeeping/adminDashboardPage.tsx +880 -0
  126. package/tests/test-app/src/pages/mobile_terminal/PersonalCenter.css +3 -0
  127. package/tests/test-app/src/pages/mobile_terminal/PersonalCenter.tsx +362 -0
  128. package/tests/test-app/src/pages/mobile_terminal/WorkOrderHomepage.tsx +337 -0
  129. package/tests/test-app/src/pages/mobile_terminal/newWorkOrder.tsx +224 -0
  130. package/tests/test-app/src/pages/mobile_terminal/tabbar.tsx +67 -0
  131. package/tests/test-app/src/pages/mobile_terminal/uiHandsOnPractice.tsx +638 -0
  132. package/tests/test-app/src/pages/mobile_terminal/workOrderDetails.tsx +346 -0
  133. package/tests/test-app/src/pages/mobile_terminal/workOrderPage.tsx +345 -0
  134. package/tests/test-app/src/pages/notice-list.tsx +217 -0
  135. package/tests/test-app/src/pages/order-detail.tsx +330 -0
  136. package/tests/test-app/src/pages/order-list.tsx +195 -0
  137. package/tests/test-app/src/pages/order-management.tsx +563 -0
  138. package/tests/test-app/src/pages/page/OrderList.tsx +230 -0
  139. package/tests/test-app/src/pages/role-list.tsx +184 -0
  140. package/tests/test-app/src/pages/simple/simplePage.tsx +92 -0
  141. package/tests/test-app/src/pages/simple-page.tsx +43 -0
  142. package/tests/test-app/src/pages/test-destructure.tsx +44 -0
  143. package/tests/test-app/src/pages/test-error-page.tsx +75 -0
  144. package/tests/test-app/src/pages/test-page-with-errors.tsx +51 -0
  145. package/tests/test-app/src/pages/test-page.tsx +101 -0
  146. package/tests/test-app/src/pages/test-render.tsx +52 -0
  147. package/tests/test-app/src/pages/test-return-type.tsx +41 -0
  148. package/tests/test-app/src/pages/test-type-assertion.tsx +37 -0
  149. package/tests/test-app/src/pages/testPage.css +3 -0
  150. package/tests/test-app/src/pages/testPage.tsx +158 -0
  151. package/tests/test-app/src/pages/ui/styleSelectorPage.tsx +1554 -0
  152. package/tests/test-app/src/pages/user-list.tsx +212 -0
  153. package/tests/test-app/src/pages/web_version/website.css +205 -0
  154. package/tests/test-app/src/pages/web_version/website.tsx +1066 -0
  155. package/tests/test-app/src/pages/wrong-page.tsx +50 -0
  156. package/tests/test-app/src/pages//345/276/205/345/212/236.apidoc.json +336 -0
  157. package/tests/test-app/src/project.json +1120 -0
  158. package/tests/test-app/src/store/global.store.ts +10 -0
  159. package/tests/test-app/src/types/CreateTicketParams.m.ts +20 -0
  160. package/tests/test-app/src/types/SLAPolicy.ts +50 -0
  161. package/tests/test-app/src/types/Ticket.ts +68 -0
  162. package/tests/test-app/src/types/TicketAttachment.m.ts +67 -0
  163. package/tests/test-app/src/types/TicketComment.m.ts +59 -0
  164. package/tests/test-app/src/types/TicketEvaluation.ts +44 -0
  165. package/tests/test-app/src/types/TicketHistory.m.ts +71 -0
  166. package/tests/test-app/src/types/TicketListParams.m.ts +30 -0
  167. package/tests/test-app/src/types/TicketPriority.m.ts +65 -0
  168. package/tests/test-app/src/types/TicketRecord.ts +47 -0
  169. package/tests/test-app/src/types/TrainDoor.ts +284 -0
  170. package/tests/test-app/src/types/UpdateTicketParams.m.ts +22 -0
  171. package/tests/test-app/src/utils/__afterRequest.util.ts +3 -0
  172. package/tests/test-app/src/utils/__beforeRequest.util.ts +10 -0
  173. package/tests/test-app/src/utils/testGlobalAction.util.ts +7 -0
@@ -0,0 +1,1299 @@
1
+ /**
2
+ * 赛博朋克风格 CRM
3
+ * @type Page
4
+ * @route /cyberpunk/crm
5
+ * @screen 1400x900 #0a0a0f
6
+ * @frames web
7
+ */
8
+ import React from 'react';
9
+ import { Button, Card, Form, Input, Menu, Modal, Progress, Select, Space, Statistic, Table, Tag } from '@appthen/antd';
10
+
11
+
12
+ class IProps {
13
+ /* 页面标题 */
14
+ title?: string;
15
+ }
16
+
17
+ /*
18
+ * 数据与接口请求定义
19
+ */
20
+ class IState {
21
+ /* 当前激活的标签页 */
22
+ activeTab?: string;
23
+ /* 客户列表 */
24
+ customers?: {
25
+ /* @example 1 */id?: number,
26
+ /* @example 未来科技 */name?: string,
27
+ /* @example 人工智能 */industry?: string,
28
+ /* @example 2500000 */revenue?: number,
29
+ /* @example active */status?: string,
30
+ /* @example 张三 */contact?: string,
31
+ /* @example zhang@future.tech */email?: string,
32
+ }[];
33
+ /* 销售数据 */
34
+ sales?: {
35
+ /* @example 12550000 */totalRevenue?: number,
36
+ /* @example 128 */newCustomers?: number,
37
+ /* @example 68 */conversionRate?: number,
38
+ /* @example 98000 */avgDealSize?: number,
39
+ };
40
+ /* 任务列表 */
41
+ tasks?: {
42
+ /* @example 1 */id?: number,
43
+ /* @example 跟进未来科技 */title?: string,
44
+ /* @example high */priority?: string,
45
+ /* @example inprogress */status?: string,
46
+ /* @example 2025-01-20 */dueDate?: string,
47
+ }[];
48
+ /* 搜索关键词 */
49
+ searchKeyword?: string;
50
+ /* 模态框显示状态 */
51
+ modalVisible?: boolean;
52
+ /* 当前编辑项 */
53
+ currentItem?: any;
54
+ /* 模态框类型 */
55
+ modalType?: string;
56
+ }
57
+
58
+ class Document extends React.Component<IProps, IState> {
59
+ state = {
60
+ activeTab: 'dashboard',
61
+ customers: [
62
+ {
63
+ id: 1,
64
+ name: '未来科技',
65
+ industry: '人工智能',
66
+ revenue: 2500000,
67
+ status: 'active',
68
+ contact: '张三',
69
+ email: 'zhang@future.tech',
70
+ },
71
+ {
72
+ id: 2,
73
+ name: '星际网络',
74
+ industry: '云计算',
75
+ revenue: 1800000,
76
+ status: 'active',
77
+ contact: '李四',
78
+ email: 'li@star.net',
79
+ },
80
+ {
81
+ id: 3,
82
+ name: '量子动力',
83
+ industry: '新能源',
84
+ revenue: 3200000,
85
+ status: 'pending',
86
+ contact: '王五',
87
+ email: 'wang@quantum.power',
88
+ },
89
+ {
90
+ id: 4,
91
+ name: '虚拟现实',
92
+ industry: 'VR/AR',
93
+ revenue: 950000,
94
+ status: 'active',
95
+ contact: '赵六',
96
+ email: 'zhao@vr.real',
97
+ },
98
+ {
99
+ id: 5,
100
+ name: '生物科技',
101
+ industry: '生物医药',
102
+ revenue: 4100000,
103
+ status: 'inactive',
104
+ contact: '孙七',
105
+ email: 'sun@bio.tech',
106
+ },
107
+ ],
108
+ sales: {
109
+ totalRevenue: 12550000,
110
+ newCustomers: 128,
111
+ conversionRate: 68,
112
+ avgDealSize: 98000,
113
+ },
114
+ tasks: [
115
+ {
116
+ id: 1,
117
+ title: '跟进未来科技',
118
+ priority: 'high',
119
+ status: 'inprogress',
120
+ dueDate: '2025-01-20',
121
+ },
122
+ {
123
+ id: 2,
124
+ title: '准备量子动力提案',
125
+ priority: 'high',
126
+ status: 'pending',
127
+ dueDate: '2025-01-22',
128
+ },
129
+ {
130
+ id: 3,
131
+ title: '客户满意度调研',
132
+ priority: 'medium',
133
+ status: 'completed',
134
+ dueDate: '2025-01-18',
135
+ },
136
+ {
137
+ id: 4,
138
+ title: '更新销售数据',
139
+ priority: 'low',
140
+ status: 'pending',
141
+ dueDate: '2025-01-25',
142
+ },
143
+ {
144
+ id: 5,
145
+ title: '团队周会',
146
+ priority: 'medium',
147
+ status: 'inprogress',
148
+ dueDate: '2025-01-19',
149
+ },
150
+ ],
151
+ searchKeyword: '',
152
+ modalVisible: false,
153
+ currentItem: null,
154
+ modalType: '',
155
+ };
156
+
157
+ handleTabChange(tab) {
158
+ this.setState({
159
+ activeTab: tab,
160
+ });
161
+ }
162
+
163
+ handleSearch(keyword) {
164
+ this.setState({
165
+ searchKeyword: keyword,
166
+ });
167
+ }
168
+
169
+ handleAddCustomer() {
170
+ this.setState({
171
+ modalVisible: true,
172
+ modalType: 'customer',
173
+ currentItem: null,
174
+ });
175
+ }
176
+
177
+ handleEditCustomer(item) {
178
+ this.setState({
179
+ modalVisible: true,
180
+ modalType: 'customer',
181
+ currentItem: item,
182
+ });
183
+ }
184
+
185
+ handleDeleteCustomer(item) {
186
+ this.utils.confirm('确认删除该客户吗?', () => {
187
+ const customers = this.state.customers.filter(c => c.id !== item.id);
188
+ this.setState({
189
+ customers,
190
+ });
191
+ this.utils.toast('删除成功');
192
+ });
193
+ }
194
+
195
+ handleAddTask() {
196
+ this.setState({
197
+ modalVisible: true,
198
+ modalType: 'task',
199
+ currentItem: null,
200
+ });
201
+ }
202
+
203
+ handleEditTask(item) {
204
+ this.setState({
205
+ modalVisible: true,
206
+ modalType: 'task',
207
+ currentItem: item,
208
+ });
209
+ }
210
+
211
+ handleDeleteTask(item) {
212
+ this.utils.confirm('确认删除该任务吗?', () => {
213
+ const tasks = this.state.tasks.filter(t => t.id !== item.id);
214
+ this.setState({
215
+ tasks,
216
+ });
217
+ this.utils.toast('删除成功');
218
+ });
219
+ }
220
+
221
+ handleModalClose() {
222
+ this.setState({
223
+ modalVisible: false,
224
+ });
225
+ }
226
+
227
+ handleSubmit(values) {
228
+ if (this.state.modalType === 'customer') {
229
+ if (this.state.currentItem) {
230
+ const customers = this.state.customers.map(item =>
231
+ item.id === this.state.currentItem.id
232
+ ? {
233
+ ...item,
234
+ ...values,
235
+ }
236
+ : item
237
+ );
238
+ this.setState({
239
+ customers,
240
+ });
241
+ } else {
242
+ const customers = [
243
+ ...this.state.customers,
244
+ {
245
+ id: Date.now(),
246
+ ...values,
247
+ revenue: 0,
248
+ status: 'pending',
249
+ },
250
+ ];
251
+ this.setState({
252
+ customers,
253
+ });
254
+ }
255
+ } else if (this.state.modalType === 'task') {
256
+ if (this.state.currentItem) {
257
+ const tasks = this.state.tasks.map(item =>
258
+ item.id === this.state.currentItem.id
259
+ ? {
260
+ ...item,
261
+ ...values,
262
+ }
263
+ : item
264
+ );
265
+ this.setState({
266
+ tasks,
267
+ });
268
+ } else {
269
+ const tasks = [
270
+ ...this.state.tasks,
271
+ {
272
+ id: Date.now(),
273
+ ...values,
274
+ status: 'pending',
275
+ },
276
+ ];
277
+ this.setState({
278
+ tasks,
279
+ });
280
+ }
281
+ }
282
+ this.setState({
283
+ modalVisible: false,
284
+ });
285
+ this.utils.toast('保存成功');
286
+ }
287
+
288
+ getFilteredCustomers() {
289
+ const keyword = this.state.searchKeyword?.toLowerCase();
290
+ if (!keyword) return this.state.customers;
291
+ return this.state.customers.filter(
292
+ c =>
293
+ c.name?.toLowerCase().includes(keyword) ||
294
+ c.industry?.toLowerCase().includes(keyword) ||
295
+ c.contact?.toLowerCase().includes(keyword)
296
+ );
297
+ }
298
+
299
+ getFilteredTasks() {
300
+ const keyword = this.state.searchKeyword?.toLowerCase();
301
+ if (!keyword) return this.state.tasks;
302
+ return this.state.tasks.filter(t =>
303
+ t.title?.toLowerCase().includes(keyword)
304
+ );
305
+ }
306
+
307
+ render() {
308
+ return (
309
+ <Page className="min-h-screen bg-[#0a0a0f] text-[#ffffff] relative overflow-hidden">
310
+ <View className="inset-0 pointer-events-none absolute bg-[repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0, 255, 255, 0.03) 2px, rgba(0, 255, 255, 0.03) 4px)] bg-[length:100% 4px]" />
311
+ <View className="inset-0 pointer-events-none absolute bg-gradient-to-r bg-[linear-gradient(rgba(0, 255, 255, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 255, 255, 0.05) 1px, transparent 1px)] bg-[length:50px 50px]" />
312
+ <View className="relative z-10 flex">
313
+ <View className="border-cyan-500/30 w-[288px] bg-[#0f0f23] border-r border-r-solid shadow-[0 25px 50px -12px rgb(0 0 0 / 0.25)]">
314
+ <View className="border-cyan-500/30 p-[24px] border-b-[1px] border-b-solid">
315
+ <View className="space-x-3 flex items-center">
316
+ <View className="shadow-cyan-500/50 bg-gradient-to-br from-[var(--cyan-400)] to-purple-500 w-[48px] h-[48px] rounded-lg flex items-center justify-center shadow-[0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)]">
317
+ <Text className="text-2xl">⚡</Text>
318
+ </View>
319
+ <View>
320
+ <h1 className="bg-gradient-to-r from-[var(--cyan-400)] to-purple-500 [WebkitBackgroundClip:text] [WebkitTextFillColor:transparent] [backgroundClip:text] [backgroundClip:text] [WebkitBackgroundClip:text] text-[transparent] text-xl font-bold">
321
+ CYBER CRM
322
+ </h1>
323
+ <p className="text-cyan-500/60 text-xs">v2.0.77</p>
324
+ </View>
325
+ </View>
326
+ </View>
327
+ <nav className="p-[16px]">
328
+ <Menu
329
+ selectedKeys={[this.state.activeTab]}
330
+ mode="inline"
331
+ theme="dark"
332
+ className="border-none cyberpunk-menu bg-[var(--transparent)]"
333
+ items={[
334
+ {
335
+ key: 'dashboard',
336
+ icon: <Text className="text-[var(--cyan-400)]">📊</Text>,
337
+ label: (
338
+ <Text className="text-[var(--cyan-100)]">仪表盘</Text>
339
+ ),
340
+ onClick: function () {
341
+ return this.handleTabChange('dashboard');
342
+ },
343
+ },
344
+ {
345
+ key: 'customers',
346
+ icon: <Text className="text-[var(--purple-400)]">👥</Text>,
347
+ label: (
348
+ <Text className="text-[var(--cyan-100)]">客户管理</Text>
349
+ ),
350
+ onClick: function () {
351
+ return this.handleTabChange('customers');
352
+ },
353
+ },
354
+ {
355
+ key: 'tasks',
356
+ icon: <Text className="text-[var(--pink-400)]">📋</Text>,
357
+ label: (
358
+ <Text className="text-[var(--cyan-100)]">任务管理</Text>
359
+ ),
360
+ onClick: function () {
361
+ return this.handleTabChange('tasks');
362
+ },
363
+ },
364
+ ]}
365
+ />
366
+ </nav>
367
+ <View className="border-cyan-500/30 bg-[#0a0a0f]/80 absolute bottom-[0px] left-[0px] right-[0px] p-[16px] border-t border-t-solid">
368
+ <View className="flex items-center justify-between text-xs">
369
+ <Text className="text-cyan-500/60">系统状态</Text>
370
+ <View className="space-x-2 flex items-center">
371
+ <Text className="animate-pulse w-[8px] h-[8px] bg-[var(--green-400)] rounded-full" />
372
+ <Text className="text-[var(--green-400)]">在线</Text>
373
+ </View>
374
+ </View>
375
+ </View>
376
+ </View>
377
+ <View className="flex-1 p-[32px]">
378
+ {!!(this.state.activeTab === 'dashboard') && (
379
+ <View>
380
+ <h2 className="bg-gradient-to-r from-[var(--cyan-400)] via-purple-500 to-[#ec4899] [WebkitBackgroundClip:text] [WebkitTextFillColor:transparent] [backgroundClip:text] [backgroundClip:text] [WebkitBackgroundClip:text] text-[transparent] text-3xl font-bold mb-[32px]">
381
+ 仪表盘
382
+ </h2>
383
+ <View className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-[32px]">
384
+ <Card className="cyberpunk-card">
385
+ <Statistic
386
+ title={
387
+ <Text className="text-[var(--cyan-400)]">总收入</Text>
388
+ }
389
+ value={this.state.sales?.totalRevenue}
390
+ prefix="¥"
391
+ valueStyle={{
392
+ color: '#00ffff',
393
+ textShadow: '0 0 10px rgba(0, 255, 255, 0.5)',
394
+ }}
395
+ />
396
+ <View className="mt-[16px]">
397
+ <Progress
398
+ percent={75}
399
+ strokeColor="#00ffff"
400
+ trailColor="rgba(0, 255, 255, 0.1)"
401
+ showInfo={false}
402
+ />
403
+ </View>
404
+ </Card>
405
+ <Card className="cyberpunk-card">
406
+ <Statistic
407
+ title={
408
+ <Text className="text-[var(--purple-400)]">新客户</Text>
409
+ }
410
+ value={this.state.sales?.newCustomers}
411
+ valueStyle={{
412
+ color: '#bf00ff',
413
+ textShadow: '0 0 10px rgba(191, 0, 255, 0.5)',
414
+ }}
415
+ />
416
+ <View className="mt-[16px]">
417
+ <Progress
418
+ percent={68}
419
+ strokeColor="#bf00ff"
420
+ trailColor="rgba(191, 0, 255, 0.1)"
421
+ showInfo={false}
422
+ />
423
+ </View>
424
+ </Card>
425
+ <Card className="cyberpunk-card">
426
+ <Statistic
427
+ title={
428
+ <Text className="text-[var(--pink-400)]">转化率</Text>
429
+ }
430
+ value={this.state.sales?.conversionRate}
431
+ suffix="%"
432
+ valueStyle={{
433
+ color: '#ff00ff',
434
+ textShadow: '0 0 10px rgba(255, 0, 255, 0.5)',
435
+ }}
436
+ />
437
+ <View className="mt-[16px]">
438
+ <Progress
439
+ percent={68}
440
+ strokeColor="#ff00ff"
441
+ trailColor="rgba(255, 0, 255, 0.1)"
442
+ showInfo={false}
443
+ />
444
+ </View>
445
+ </Card>
446
+ <Card className="cyberpunk-card">
447
+ <Statistic
448
+ title={
449
+ <Text className="text-[var(--green-400)]">
450
+ 平均成交
451
+ </Text>
452
+ }
453
+ value={this.state.sales?.avgDealSize}
454
+ prefix="¥"
455
+ valueStyle={{
456
+ color: '#00ff88',
457
+ textShadow: '0 0 10px rgba(0, 255, 136, 0.5)',
458
+ }}
459
+ />
460
+ <View className="mt-[16px]">
461
+ <Progress
462
+ percent={85}
463
+ strokeColor="#00ff88"
464
+ trailColor="rgba(0, 255, 136, 0.1)"
465
+ showInfo={false}
466
+ />
467
+ </View>
468
+ </Card>
469
+ </View>
470
+ <Card
471
+ className="cyberpunk-card mb-[32px]"
472
+ title={
473
+ <Text className="text-[var(--cyan-400)]">客户概览</Text>
474
+ }
475
+ >
476
+ <Table
477
+ dataSource={this.state.customers}
478
+ rowKey="id"
479
+ pagination={false}
480
+ className="cyberpunk-table"
481
+ columns={[
482
+ {
483
+ title: (
484
+ <Text className="text-[var(--cyan-400)]">
485
+ 客户名称
486
+ </Text>
487
+ ),
488
+ dataIndex: 'name',
489
+ key: 'name',
490
+ render: name => (
491
+ <Text className="text-[var(--cyan-100)] font-semibold">
492
+ {name}
493
+ </Text>
494
+ ),
495
+ },
496
+ {
497
+ title: (
498
+ <Text className="text-[var(--cyan-400)]">行业</Text>
499
+ ),
500
+ dataIndex: 'industry',
501
+ key: 'industry',
502
+ render: industry => (
503
+ <Tag color="cyan">
504
+ <Text>{industry}</Text>
505
+ </Tag>
506
+ ),
507
+ },
508
+ {
509
+ title: (
510
+ <Text className="text-[var(--cyan-400)]">收入</Text>
511
+ ),
512
+ dataIndex: 'revenue',
513
+ key: 'revenue',
514
+ render: revenue => (
515
+ <Text className="text-[var(--purple-400)] font-bold">
516
+ ¥{revenue?.toLocaleString()}
517
+ </Text>
518
+ ),
519
+ },
520
+ {
521
+ title: (
522
+ <Text className="text-[var(--cyan-400)]">状态</Text>
523
+ ),
524
+ dataIndex: 'status',
525
+ key: 'status',
526
+ render: status =>
527
+ (() => {
528
+ const statusConfig = {
529
+ active: {
530
+ color: 'success',
531
+ text: '活跃',
532
+ },
533
+ pending: {
534
+ color: 'warning',
535
+ text: '待定',
536
+ },
537
+ inactive: {
538
+ color: 'default',
539
+ text: '非活跃',
540
+ },
541
+ };
542
+ const config =
543
+ statusConfig[status] || statusConfig.inactive;
544
+ return (
545
+ <Tag color={config.color}>
546
+ <Text>{config.text}</Text>
547
+ </Tag>
548
+ );
549
+ })(),
550
+ },
551
+ ]}
552
+ />
553
+ </Card>
554
+ <Card
555
+ className="cyberpunk-card"
556
+ title={
557
+ <Text className="text-[var(--pink-400)]">任务概览</Text>
558
+ }
559
+ >
560
+ <Table
561
+ dataSource={this.state.tasks}
562
+ rowKey="id"
563
+ pagination={false}
564
+ className="cyberpunk-table"
565
+ columns={[
566
+ {
567
+ title: (
568
+ <Text className="text-[var(--pink-400)]">任务</Text>
569
+ ),
570
+ dataIndex: 'title',
571
+ key: 'title',
572
+ render: title => (
573
+ <Text className="text-[var(--cyan-100)]">
574
+ {title}
575
+ </Text>
576
+ ),
577
+ },
578
+ {
579
+ title: (
580
+ <Text className="text-[var(--pink-400)]">优先级</Text>
581
+ ),
582
+ dataIndex: 'priority',
583
+ key: 'priority',
584
+ render: priority =>
585
+ (() => {
586
+ const priorityConfig = {
587
+ high: {
588
+ color: 'error',
589
+ text: '高',
590
+ },
591
+ medium: {
592
+ color: 'warning',
593
+ text: '中',
594
+ },
595
+ low: {
596
+ color: 'default',
597
+ text: '低',
598
+ },
599
+ };
600
+ const config =
601
+ priorityConfig[priority] || priorityConfig.low;
602
+ return (
603
+ <Tag color={config.color}>
604
+ <Text>{config.text}</Text>
605
+ </Tag>
606
+ );
607
+ })(),
608
+ },
609
+ {
610
+ title: (
611
+ <Text className="text-[var(--pink-400)]">状态</Text>
612
+ ),
613
+ dataIndex: 'status',
614
+ key: 'status',
615
+ render: status =>
616
+ (() => {
617
+ const statusConfig = {
618
+ completed: {
619
+ color: 'success',
620
+ text: '已完成',
621
+ },
622
+ inprogress: {
623
+ color: 'processing',
624
+ text: '进行中',
625
+ },
626
+ pending: {
627
+ color: 'default',
628
+ text: '待处理',
629
+ },
630
+ };
631
+ const config =
632
+ statusConfig[status] || statusConfig.pending;
633
+ return (
634
+ <Tag color={config.color}>
635
+ <Text>{config.text}</Text>
636
+ </Tag>
637
+ );
638
+ })(),
639
+ },
640
+ {
641
+ title: (
642
+ <Text className="text-[var(--pink-400)]">
643
+ 截止日期
644
+ </Text>
645
+ ),
646
+ dataIndex: 'dueDate',
647
+ key: 'dueDate',
648
+ render: date => (
649
+ <Text className="text-[var(--cyan-100)]">{date}</Text>
650
+ ),
651
+ },
652
+ ]}
653
+ />
654
+ </Card>
655
+ </View>
656
+ )}
657
+ {!!(this.state.activeTab === 'customers') && (
658
+ <View>
659
+ <View className="flex items-center justify-between mb-[32px]">
660
+ <h2 className="bg-gradient-to-r from-[var(--cyan-400)] to-purple-500 [WebkitBackgroundClip:text] [WebkitTextFillColor:transparent] [backgroundClip:text] [backgroundClip:text] [WebkitBackgroundClip:text] text-[transparent] text-3xl font-bold">
661
+ 客户管理
662
+ </h2>
663
+ <Button
664
+ type="primary"
665
+ size="large"
666
+ onClick={() => this.handleAddCustomer()}
667
+ className="cyberpunk-button"
668
+ >
669
+ <Text>⚡ 新增客户</Text>
670
+ </Button>
671
+ </View>
672
+ <View className="mb-[24px]">
673
+ <Input
674
+ placeholder="搜索客户名称、行业或联系人..."
675
+ prefix={<Text>🔍</Text>}
676
+ value={this.state.searchKeyword}
677
+ onChange={e => this.handleSearch(e.target.value)}
678
+ size="large"
679
+ className="cyberpunk-input "
680
+ allowClear={true}
681
+ />
682
+ </View>
683
+ <Card className="cyberpunk-card">
684
+ <Table
685
+ dataSource={this.getFilteredCustomers()}
686
+ rowKey="id"
687
+ pagination={{ pageSize: 10 }}
688
+ className="cyberpunk-table"
689
+ columns={[
690
+ {
691
+ title: (
692
+ <Text className="text-[var(--cyan-400)]">
693
+ 客户名称
694
+ </Text>
695
+ ),
696
+ dataIndex: 'name',
697
+ key: 'name',
698
+ render: name => (
699
+ <Space>
700
+ <View className="bg-gradient-to-br from-[var(--cyan-400)] to-purple-500 w-[40px] h-[40px] rounded-lg flex items-center justify-center text-[#ffffff] font-bold">
701
+ <Text>{name?.charAt(0)}</Text>
702
+ </View>
703
+ <Text className="text-[var(--cyan-100)] font-bold text-lg">
704
+ {name}
705
+ </Text>
706
+ </Space>
707
+ ),
708
+ },
709
+ {
710
+ title: (
711
+ <Text className="text-[var(--cyan-400)]">行业</Text>
712
+ ),
713
+ dataIndex: 'industry',
714
+ key: 'industry',
715
+ render: industry => (
716
+ <Tag color="cyan">
717
+ <Text>{industry}</Text>
718
+ </Tag>
719
+ ),
720
+ },
721
+ {
722
+ title: (
723
+ <Text className="text-[var(--cyan-400)]">联系人</Text>
724
+ ),
725
+ dataIndex: 'contact',
726
+ key: 'contact',
727
+ render: contact => (
728
+ <Text className="text-[var(--cyan-100)]">
729
+ {contact}
730
+ </Text>
731
+ ),
732
+ },
733
+ {
734
+ title: (
735
+ <Text className="text-[var(--cyan-400)]">邮箱</Text>
736
+ ),
737
+ dataIndex: 'email',
738
+ key: 'email',
739
+ render: email => (
740
+ <Text className="text-cyan-100/70">{email}</Text>
741
+ ),
742
+ },
743
+ {
744
+ title: (
745
+ <Text className="text-[var(--cyan-400)]">收入</Text>
746
+ ),
747
+ dataIndex: 'revenue',
748
+ key: 'revenue',
749
+ render: revenue => (
750
+ <Text className="text-[var(--purple-400)] font-bold text-lg">
751
+ ¥{revenue?.toLocaleString()}
752
+ </Text>
753
+ ),
754
+ },
755
+ {
756
+ title: (
757
+ <Text className="text-[var(--cyan-400)]">状态</Text>
758
+ ),
759
+ dataIndex: 'status',
760
+ key: 'status',
761
+ render: status =>
762
+ (() => {
763
+ const statusConfig = {
764
+ active: {
765
+ color: 'success',
766
+ text: '活跃',
767
+ },
768
+ pending: {
769
+ color: 'warning',
770
+ text: '待定',
771
+ },
772
+ inactive: {
773
+ color: 'default',
774
+ text: '非活跃',
775
+ },
776
+ };
777
+ const config =
778
+ statusConfig[status] || statusConfig.inactive;
779
+ return (
780
+ <Tag color={config.color}>
781
+ <Text>{config.text}</Text>
782
+ </Tag>
783
+ );
784
+ })(),
785
+ },
786
+ {
787
+ title: (
788
+ <Text className="text-[var(--cyan-400)]">操作</Text>
789
+ ),
790
+ key: 'action',
791
+ render: (_, record) => (
792
+ <Space>
793
+ <Button
794
+ type="link"
795
+ size="small"
796
+ onClick={() => this.handleEditCustomer(record)}
797
+ className="text-cyan-400 hover:text-cyan-300"
798
+ >
799
+ <Text>✏️ 编辑</Text>
800
+ </Button>
801
+ <Button
802
+ type="link"
803
+ danger={true}
804
+ size="small"
805
+ onClick={() => this.handleDeleteCustomer(record)}
806
+ >
807
+ <Text>🗑️ 删除</Text>
808
+ </Button>
809
+ </Space>
810
+ ),
811
+ },
812
+ ]}
813
+ />
814
+ </Card>
815
+ </View>
816
+ )}
817
+ {!!(this.state.activeTab === 'tasks') && (
818
+ <View>
819
+ <View className="flex items-center justify-between mb-[32px]">
820
+ <h2 className="bg-gradient-to-r from-[#f472b6] to-purple-500 [WebkitBackgroundClip:text] [WebkitTextFillColor:transparent] [backgroundClip:text] [backgroundClip:text] [WebkitBackgroundClip:text] text-[transparent] text-3xl font-bold">
821
+ 任务管理
822
+ </h2>
823
+ <Button
824
+ type="primary"
825
+ size="large"
826
+ onClick={() => this.handleAddTask()}
827
+ className="cyberpunk-button"
828
+ >
829
+ <Text>⚡ 新增任务</Text>
830
+ </Button>
831
+ </View>
832
+ <View className="mb-[24px]">
833
+ <Input
834
+ placeholder="搜索任务..."
835
+ prefix={<Text>🔍</Text>}
836
+ value={this.state.searchKeyword}
837
+ onChange={e => this.handleSearch(e.target.value)}
838
+ size="large"
839
+ className="cyberpunk-input "
840
+ allowClear={true}
841
+ />
842
+ </View>
843
+ <Card className="cyberpunk-card">
844
+ <Table
845
+ dataSource={this.getFilteredTasks()}
846
+ rowKey="id"
847
+ pagination={{ pageSize: 10 }}
848
+ className="cyberpunk-table"
849
+ columns={[
850
+ {
851
+ title: (
852
+ <Text className="text-[var(--pink-400)]">任务</Text>
853
+ ),
854
+ dataIndex: 'title',
855
+ key: 'title',
856
+ render: title => (
857
+ <Text className="text-[var(--cyan-100)] font-semibold">
858
+ {title}
859
+ </Text>
860
+ ),
861
+ },
862
+ {
863
+ title: (
864
+ <Text className="text-[var(--pink-400)]">优先级</Text>
865
+ ),
866
+ dataIndex: 'priority',
867
+ key: 'priority',
868
+ render: priority =>
869
+ (() => {
870
+ const priorityConfig = {
871
+ high: {
872
+ color: 'error',
873
+ text: '高',
874
+ },
875
+ medium: {
876
+ color: 'warning',
877
+ text: '中',
878
+ },
879
+ low: {
880
+ color: 'default',
881
+ text: '低',
882
+ },
883
+ };
884
+ const config =
885
+ priorityConfig[priority] || priorityConfig.low;
886
+ return (
887
+ <Tag color={config.color}>
888
+ <Text>{config.text}</Text>
889
+ </Tag>
890
+ );
891
+ })(),
892
+ },
893
+ {
894
+ title: (
895
+ <Text className="text-[var(--pink-400)]">状态</Text>
896
+ ),
897
+ dataIndex: 'status',
898
+ key: 'status',
899
+ render: status =>
900
+ (() => {
901
+ const statusConfig = {
902
+ completed: {
903
+ color: 'success',
904
+ text: '已完成',
905
+ },
906
+ inprogress: {
907
+ color: 'processing',
908
+ text: '进行中',
909
+ },
910
+ pending: {
911
+ color: 'default',
912
+ text: '待处理',
913
+ },
914
+ };
915
+ const config =
916
+ statusConfig[status] || statusConfig.pending;
917
+ return (
918
+ <Tag color={config.color}>
919
+ <Text>{config.text}</Text>
920
+ </Tag>
921
+ );
922
+ })(),
923
+ },
924
+ {
925
+ title: (
926
+ <Text className="text-[var(--pink-400)]">
927
+ 截止日期
928
+ </Text>
929
+ ),
930
+ dataIndex: 'dueDate',
931
+ key: 'dueDate',
932
+ render: date => (
933
+ <Text className="text-[var(--cyan-100)]">{date}</Text>
934
+ ),
935
+ },
936
+ {
937
+ title: (
938
+ <Text className="text-[var(--pink-400)]">操作</Text>
939
+ ),
940
+ key: 'action',
941
+ render: (_, record) => (
942
+ <Space>
943
+ <Button
944
+ type="link"
945
+ size="small"
946
+ onClick={() => this.handleEditTask(record)}
947
+ className="text-pink-400 hover:text-pink-300"
948
+ >
949
+ <Text>✏️ 编辑</Text>
950
+ </Button>
951
+ <Button
952
+ type="link"
953
+ danger={true}
954
+ size="small"
955
+ onClick={() => this.handleDeleteTask(record)}
956
+ >
957
+ <Text>🗑️ 删除</Text>
958
+ </Button>
959
+ </Space>
960
+ ),
961
+ },
962
+ ]}
963
+ />
964
+ </Card>
965
+ </View>
966
+ )}
967
+ </View>
968
+ </View>
969
+ <Modal
970
+ title={
971
+ <Text className="text-[var(--cyan-400)]">
972
+ {this.state.currentItem ? '✏️ 编辑客户' : '⚡ 新增客户'}
973
+ </Text>
974
+ }
975
+ open={this.state.modalVisible && this.state.modalType === 'customer'}
976
+ onCancel={() => this.handleModalClose()}
977
+ footer={null}
978
+ width={500}
979
+ className="cyberpunk-modal"
980
+ >
981
+ <Form
982
+ initialValues={
983
+ this.state.currentItem || {
984
+ status: 'pending',
985
+ }
986
+ }
987
+ onFinish={values => this.handleSubmit(values)}
988
+ layout="vertical"
989
+ >
990
+ <Form.Item
991
+ label={
992
+ <Text className="text-[var(--cyan-400)]">🏢 客户名称</Text>
993
+ }
994
+ name="name"
995
+ rules={[{ required: true, message: '请输入客户名称' }]}
996
+ >
997
+ <Input
998
+ placeholder="请输入客户名称"
999
+ size="large"
1000
+ className="cyberpunk-input"
1001
+ />
1002
+ </Form.Item>
1003
+ <Form.Item
1004
+ label={<Text className="text-[var(--cyan-400)]">🏭 行业</Text>}
1005
+ name="industry"
1006
+ rules={[{ required: true, message: '请输入行业' }]}
1007
+ >
1008
+ <Input
1009
+ placeholder="例如:人工智能、云计算"
1010
+ size="large"
1011
+ className="cyberpunk-input"
1012
+ />
1013
+ </Form.Item>
1014
+ <Form.Item
1015
+ label={<Text className="text-[var(--cyan-400)]">👤 联系人</Text>}
1016
+ name="contact"
1017
+ rules={[{ required: true, message: '请输入联系人' }]}
1018
+ >
1019
+ <Input
1020
+ placeholder="请输入联系人姓名"
1021
+ size="large"
1022
+ className="cyberpunk-input"
1023
+ />
1024
+ </Form.Item>
1025
+ <Form.Item
1026
+ label={<Text className="text-[var(--cyan-400)]">📧 邮箱</Text>}
1027
+ name="email"
1028
+ rules={[{ required: true, message: '请输入邮箱' }]}
1029
+ >
1030
+ <Input
1031
+ placeholder="请输入邮箱地址"
1032
+ size="large"
1033
+ className="cyberpunk-input"
1034
+ />
1035
+ </Form.Item>
1036
+ <Form.Item
1037
+ label={<Text className="text-[var(--cyan-400)]">📊 状态</Text>}
1038
+ name="status"
1039
+ rules={[{ required: true, message: '请选择状态' }]}
1040
+ >
1041
+ <Select size="large" className="cyberpunk-select">
1042
+ <Select.Option value="active">✓ 活跃</Select.Option>
1043
+ <Select.Option value="pending">⏳ 待定</Select.Option>
1044
+ <Select.Option value="inactive">💤 非活跃</Select.Option>
1045
+ </Select>
1046
+ </Form.Item>
1047
+ <Form.Item className="mb-0">
1048
+ <Space className="w-full justify-end">
1049
+ <Button
1050
+ onClick={() => this.handleModalClose()}
1051
+ className="cyberpunk-button-secondary"
1052
+ >
1053
+ <Text>取消</Text>
1054
+ </Button>
1055
+ <Button
1056
+ type="primary"
1057
+ htmlType="submit"
1058
+ className="cyberpunk-button"
1059
+ >
1060
+ <Text>⚡ 保存</Text>
1061
+ </Button>
1062
+ </Space>
1063
+ </Form.Item>
1064
+ </Form>
1065
+ </Modal>
1066
+ <Modal
1067
+ title={
1068
+ <Text className="text-[var(--pink-400)]">
1069
+ {this.state.currentItem ? '✏️ 编辑任务' : '⚡ 新增任务'}
1070
+ </Text>
1071
+ }
1072
+ open={this.state.modalVisible && this.state.modalType === 'task'}
1073
+ onCancel={() => this.handleModalClose()}
1074
+ footer={null}
1075
+ width={500}
1076
+ className="cyberpunk-modal"
1077
+ >
1078
+ <Form
1079
+ initialValues={
1080
+ this.state.currentItem || {
1081
+ priority: 'medium',
1082
+ status: 'pending',
1083
+ }
1084
+ }
1085
+ onFinish={values => this.handleSubmit(values)}
1086
+ layout="vertical"
1087
+ >
1088
+ <Form.Item
1089
+ label={
1090
+ <Text className="text-[var(--pink-400)]">📝 任务标题</Text>
1091
+ }
1092
+ name="title"
1093
+ rules={[{ required: true, message: '请输入任务标题' }]}
1094
+ >
1095
+ <Input
1096
+ placeholder="请输入任务标题"
1097
+ size="large"
1098
+ className="cyberpunk-input"
1099
+ />
1100
+ </Form.Item>
1101
+ <Form.Item
1102
+ label={<Text className="text-[var(--pink-400)]">⚡ 优先级</Text>}
1103
+ name="priority"
1104
+ rules={[{ required: true, message: '请选择优先级' }]}
1105
+ >
1106
+ <Select size="large" className="cyberpunk-select">
1107
+ <Select.Option value="high">🔴 高</Select.Option>
1108
+ <Select.Option value="medium">🟡 中</Select.Option>
1109
+ <Select.Option value="low">🟢 低</Select.Option>
1110
+ </Select>
1111
+ </Form.Item>
1112
+ <Form.Item
1113
+ label={<Text className="text-[var(--pink-400)]">📊 状态</Text>}
1114
+ name="status"
1115
+ rules={[{ required: true, message: '请选择状态' }]}
1116
+ >
1117
+ <Select size="large" className="cyberpunk-select">
1118
+ <Select.Option value="pending">⏳ 待处理</Select.Option>
1119
+ <Select.Option value="inprogress">🔄 进行中</Select.Option>
1120
+ <Select.Option value="completed">✓ 已完成</Select.Option>
1121
+ </Select>
1122
+ </Form.Item>
1123
+ <Form.Item
1124
+ label={
1125
+ <Text className="text-[var(--pink-400)]">📅 截止日期</Text>
1126
+ }
1127
+ name="dueDate"
1128
+ rules={[{ required: true, message: '请选择截止日期' }]}
1129
+ >
1130
+ <Input type="date" size="large" className="cyberpunk-input" />
1131
+ </Form.Item>
1132
+ <Form.Item className="mb-0">
1133
+ <Space className="w-full justify-end">
1134
+ <Button
1135
+ onClick={() => this.handleModalClose()}
1136
+ className="cyberpunk-button-secondary"
1137
+ >
1138
+ <Text>取消</Text>
1139
+ </Button>
1140
+ <Button
1141
+ type="primary"
1142
+ htmlType="submit"
1143
+ className="cyberpunk-button"
1144
+ >
1145
+ <Text>⚡ 保存</Text>
1146
+ </Button>
1147
+ </Space>
1148
+ </Form.Item>
1149
+ </Form>
1150
+ </Modal>
1151
+ <style jsx={true} global={true}>
1152
+ <Text>{`
1153
+ .cyberpunk-card {
1154
+ background: rgba(15, 15, 35, 0.8) !important;
1155
+ border: 1px solid rgba(0, 255, 255, 0.3) !important;
1156
+ box-shadow: 0 0 20px rgba(0, 255, 255, 0.1), inset 0 0 20px rgba(0, 255, 255, 0.05) !important;
1157
+ backdrop-filter: blur(10px);
1158
+ }
1159
+
1160
+ .cyberpunk-card .ant-card-head {
1161
+ border-bottom: 1px solid rgba(0, 255, 255, 0.3) !important;
1162
+ background: rgba(0, 255, 255, 0.05) !important;
1163
+ }
1164
+
1165
+ .cyberpunk-card .ant-card-body {
1166
+ color: #00ffff !important;
1167
+ }
1168
+
1169
+ .cyberpunk-table .ant-table {
1170
+ background: transparent !important;
1171
+ color: #00ffff !important;
1172
+ }
1173
+
1174
+ .cyberpunk-table .ant-table-thead > tr > th {
1175
+ background: rgba(0, 255, 255, 0.1) !important;
1176
+ border-bottom: 1px solid rgba(0, 255, 255, 0.3) !important;
1177
+ color: #00ffff !important;
1178
+ }
1179
+
1180
+ .cyberpunk-table .ant-table-tbody > tr > td {
1181
+ border-bottom: 1px solid rgba(0, 255, 255, 0.1) !important;
1182
+ color: #00ffff !important;
1183
+ }
1184
+
1185
+ .cyberpunk-table .ant-table-tbody > tr:hover > td {
1186
+ background: rgba(0, 255, 255, 0.1) !important;
1187
+ }
1188
+
1189
+ .cyberpunk-input {
1190
+ background: rgba(15, 15, 35, 0.8) !important;
1191
+ border: 1px solid rgba(0, 255, 255, 0.3) !important;
1192
+ color: #00ffff !important;
1193
+ box-shadow: 0 0 10px rgba(0, 255, 255, 0.1) !important;
1194
+ }
1195
+
1196
+ .cyberpunk-input::placeholder {
1197
+ color: rgba(0, 255, 255, 0.5) !important;
1198
+ }
1199
+
1200
+ .cyberpunk-input:hover,
1201
+ .cyberpunk-input:focus {
1202
+ border-color: #00ffff !important;
1203
+ box-shadow: 0 0 20px rgba(0, 255, 255, 0.3) !important;
1204
+ }
1205
+
1206
+ .cyberpunk-select {
1207
+ background: rgba(15, 15, 35, 0.8) !important;
1208
+ border: 1px solid rgba(0, 255, 255, 0.3) !important;
1209
+ color: #00ffff !important;
1210
+ }
1211
+
1212
+ .cyberpunk-select:hover,
1213
+ .cyberpunk-select:focus {
1214
+ border-color: #00ffff !important;
1215
+ box-shadow: 0 0 20px rgba(0, 255, 255, 0.3) !important;
1216
+ }
1217
+
1218
+ .cyberpunk-button {
1219
+ background: linear-gradient(135deg, #00ffff 0%, #bf00ff 100%) !important;
1220
+ border: none !important;
1221
+ color: #ffffff !important;
1222
+ box-shadow: 0 0 20px rgba(0, 255, 255, 0.5), 0 0 40px rgba(191, 0, 255, 0.3) !important;
1223
+ text-shadow: 0 0 10px rgba(255, 255, 255, 0.5) !important;
1224
+ }
1225
+
1226
+ .cyberpunk-button:hover {
1227
+ box-shadow: 0 0 30px rgba(0, 255, 255, 0.7), 0 0 60px rgba(191, 0, 255, 0.5) !important;
1228
+ transform: scale(1.05);
1229
+ }
1230
+
1231
+ .cyberpunk-button-secondary {
1232
+ background: rgba(15, 15, 35, 0.8) !important;
1233
+ border: 1px solid rgba(0, 255, 255, 0.3) !important;
1234
+ color: #00ffff !important;
1235
+ box-shadow: 0 0 10px rgba(0, 255, 255, 0.1) !important;
1236
+ }
1237
+
1238
+ .cyberpunk-button-secondary:hover {
1239
+ border-color: #00ffff !important;
1240
+ box-shadow: 0 0 20px rgba(0, 255, 255, 0.3) !important;
1241
+ }
1242
+
1243
+ .cyberpunk-modal .ant-modal-content {
1244
+ background: rgba(10, 10, 15, 0.95) !important;
1245
+ border: 1px solid rgba(0, 255, 255, 0.3) !important;
1246
+ box-shadow: 0 0 50px rgba(0, 255, 255, 0.2) !important;
1247
+ backdrop-filter: blur(20px);
1248
+ }
1249
+
1250
+ .cyberpunk-modal .ant-modal-header {
1251
+ border-bottom: 1px solid rgba(0, 255, 255, 0.3) !important;
1252
+ background: rgba(0, 255, 255, 0.05) !important;
1253
+ }
1254
+
1255
+ .cyberpunk-modal .ant-modal-close-x {
1256
+ color: #00ffff !important;
1257
+ }
1258
+
1259
+ .cyberpunk-modal .ant-modal-close-x:hover {
1260
+ color: #ff00ff !important;
1261
+ }
1262
+
1263
+ .cyberpunk-modal .ant-form-item-label > label {
1264
+ color: #00ffff !important;
1265
+ }
1266
+
1267
+ .ant-menu-dark.cyberpunk-menu {
1268
+ background: transparent !important;
1269
+ }
1270
+
1271
+ .ant-menu-dark.cyberpunk-menu .ant-menu-item-selected {
1272
+ background: linear-gradient(90deg, rgba(0, 255, 255, 0.2) 0%, transparent 100%) !important;
1273
+ border-left: 3px solid #00ffff !important;
1274
+ }
1275
+
1276
+ .ant-menu-dark.cyberpunk-menu .ant-menu-item:hover {
1277
+ background: rgba(0, 255, 255, 0.1) !important;
1278
+ }
1279
+
1280
+ .ant-progress-bg {
1281
+ box-shadow: 0 0 10px currentColor !important;
1282
+ }
1283
+
1284
+ .ant-statistic-title {
1285
+ color: rgba(0, 255, 255, 0.7) !important;
1286
+ }
1287
+
1288
+ .ant-tag {
1289
+ border: 1px solid rgba(0, 255, 255, 0.3) !important;
1290
+ background: rgba(0, 255, 255, 0.1) !important;
1291
+ }
1292
+ `}</Text>
1293
+ </style>
1294
+ </Page>
1295
+ );
1296
+ }
1297
+ }
1298
+
1299
+ export default Document;