@appthen/cli 1.2.11 → 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 (59) hide show
  1. package/bin/main.js +47 -0
  2. package/dist/index.js +6165 -14980
  3. package/package.json +8 -1
  4. package/tests/test-app/.appthen/shadow-space-100001-test-app-e99876b1.json +1197 -741
  5. package/tests/test-app/.appthen/space-config.json +2 -2
  6. package/tests/test-app/src/components/MessageCenter.tsx +506 -0
  7. package/tests/test-app/src/pages/CustomerManagement.tsx +535 -0
  8. package/tests/test-app/src/pages/CyberpunkDashboard.tsx +348 -0
  9. package/tests/test-app/src/pages/CyberpunkProductManagement.tsx +637 -0
  10. package/tests/test-app/src/pages/CyberpunkUserList.tsx +316 -0
  11. package/tests/test-app/src/pages/DashboardV2.tsx +334 -0
  12. package/tests/test-app/src/pages/DataReport.tsx +298 -0
  13. package/tests/test-app/src/pages/DataStatistics.tsx +317 -0
  14. package/tests/test-app/src/pages/DepartmentManagement.tsx +503 -0
  15. package/tests/test-app/src/pages/FileExplorer.tsx +441 -0
  16. package/tests/test-app/src/pages/OrderDetail.tsx +393 -0
  17. package/tests/test-app/src/pages/ProductManagement.tsx +521 -0
  18. package/tests/test-app/src/pages/ProjectTimeline.tsx +395 -0
  19. package/tests/test-app/src/pages/RoleManagement.tsx +523 -0
  20. package/tests/test-app/src/pages/StaticCyberpunkDashboard.tsx +462 -0
  21. package/tests/test-app/src/pages/StaticCyberpunkUserList.tsx +567 -0
  22. package/tests/test-app/src/pages/StudentWeaknessList.tsx +547 -0
  23. package/tests/test-app/src/pages/SystemSettings.tsx +422 -0
  24. package/tests/test-app/src/pages/TaskManagement.tsx +467 -0
  25. package/tests/test-app/src/pages/TicketManagement.tsx +402 -0
  26. package/tests/test-app/src/pages/UserProfile.tsx +404 -0
  27. package/tests/test-app/src/pages/WorkflowDesigner.tsx +434 -0
  28. package/tests/test-app/src/pages/admin/dashboard.tsx +591 -0
  29. package/tests/test-app/src/pages/article-list.tsx +222 -0
  30. package/tests/test-app/src/pages/babyProductRecommendationPage.tsx +168 -0
  31. package/tests/test-app/src/pages/category-list.tsx +179 -0
  32. package/tests/test-app/src/pages/comment-list.tsx +194 -0
  33. package/tests/test-app/src/pages/cyberpunk/cyberpunkCRMPage.tsx +1299 -0
  34. package/tests/test-app/src/pages/data-analytics.tsx +1872 -0
  35. package/tests/test-app/src/pages/data-overview.tsx +600 -0
  36. package/tests/test-app/src/pages/demo-error-page.tsx +119 -0
  37. package/tests/test-app/src/pages/department-list.tsx +183 -0
  38. package/tests/test-app/src/pages/goods-list.tsx +233 -0
  39. package/tests/test-app/src/pages/housekeeping/adminDashboardPage.tsx +880 -0
  40. package/tests/test-app/src/pages/mobile_terminal/uiHandsOnPractice.tsx +1 -1
  41. package/tests/test-app/src/pages/notice-list.tsx +217 -0
  42. package/tests/test-app/src/pages/order-detail.tsx +330 -0
  43. package/tests/test-app/src/pages/order-list.tsx +195 -0
  44. package/tests/test-app/src/pages/order-management.tsx +563 -0
  45. package/tests/test-app/src/pages/page/OrderList.tsx +230 -0
  46. package/tests/test-app/src/pages/role-list.tsx +184 -0
  47. package/tests/test-app/src/pages/simple/simplePage.tsx +92 -0
  48. package/tests/test-app/src/pages/simple-page.tsx +43 -0
  49. package/tests/test-app/src/pages/test-destructure.tsx +44 -0
  50. package/tests/test-app/src/pages/test-error-page.tsx +75 -0
  51. package/tests/test-app/src/pages/test-page-with-errors.tsx +51 -0
  52. package/tests/test-app/src/pages/test-page.tsx +101 -0
  53. package/tests/test-app/src/pages/test-render.tsx +52 -0
  54. package/tests/test-app/src/pages/test-return-type.tsx +41 -0
  55. package/tests/test-app/src/pages/test-type-assertion.tsx +37 -0
  56. package/tests/test-app/src/pages/ui/styleSelectorPage.tsx +1554 -0
  57. package/tests/test-app/src/pages/user-list.tsx +212 -0
  58. package/tests/test-app/src/pages/wrong-page.tsx +50 -0
  59. package/tests/test-app/.appthen/shadow-space-unknown-user-test-app-e99876b1.json +0 -1060
@@ -0,0 +1,503 @@
1
+ /**
2
+ * 部门管理
3
+ * 管理组织架构和部门信息
4
+ *
5
+ * @type Page
6
+ * @route /departments
7
+ * @screen 1920w
8
+ * @frames web
9
+ */
10
+ import React from 'react';
11
+
12
+
13
+
14
+ class IProps {
15
+ organizationId?: number;
16
+ }
17
+
18
+ /*
19
+ * 数据与接口请求定义
20
+ */
21
+ class IState {
22
+ departments?: {
23
+ /* @example 1 */id?: number,
24
+ /* @example 技术部 */name?: string,
25
+ parentId?: any,
26
+ /* @example 张三 */manager?: string,
27
+ /* @example 负责技术研发 */description?: string,
28
+ /* @example 15 */userCount?: number,
29
+ /* @example 1 */level?: number,
30
+ }[];
31
+ users?: {
32
+ /* @example 1 */id?: number,
33
+ /* @example 张三 */name?: string,
34
+ /* @example 1 */departmentId?: number,
35
+ }[];
36
+ loading?: boolean;
37
+ searchKeyword?: string;
38
+ selectedDepartment?: any;
39
+ showAddModal?: boolean;
40
+ showEditModal?: boolean;
41
+ formData?: {
42
+ name?: string,
43
+ parentId?: number,
44
+ manager?: string,
45
+ description?: string,
46
+ };
47
+ }
48
+
49
+ class Document extends React.Component<IProps, IState> {
50
+ state = {
51
+ departments: [
52
+ {
53
+ id: 1,
54
+ name: '技术部',
55
+ parentId: null,
56
+ manager: '张三',
57
+ description: '负责技术研发',
58
+ userCount: 15,
59
+ level: 1,
60
+ },
61
+ {
62
+ id: 2,
63
+ name: '产品部',
64
+ parentId: null,
65
+ manager: '李四',
66
+ description: '负责产品规划',
67
+ userCount: 8,
68
+ level: 1,
69
+ },
70
+ {
71
+ id: 3,
72
+ name: '前端组',
73
+ parentId: 1,
74
+ manager: '王五',
75
+ description: '前端开发团队',
76
+ userCount: 5,
77
+ level: 2,
78
+ },
79
+ {
80
+ id: 4,
81
+ name: '后端组',
82
+ parentId: 1,
83
+ manager: '赵六',
84
+ description: '后端开发团队',
85
+ userCount: 8,
86
+ level: 2,
87
+ },
88
+ {
89
+ id: 5,
90
+ name: '设计组',
91
+ parentId: 2,
92
+ manager: '钱七',
93
+ description: '产品设计团队',
94
+ userCount: 4,
95
+ level: 2,
96
+ },
97
+ ],
98
+ users: [
99
+ { id: 1, name: '张三', departmentId: 1 },
100
+ { id: 2, name: '李四', departmentId: 2 },
101
+ { id: 3, name: '王五', departmentId: 3 },
102
+ { id: 4, name: '赵六', departmentId: 4 },
103
+ { id: 5, name: '钱七', departmentId: 5 },
104
+ ],
105
+ loading: false,
106
+ searchKeyword: '',
107
+ selectedDepartment: null,
108
+ showAddModal: false,
109
+ showEditModal: false,
110
+ formData: { name: '', parentId: null, manager: '', description: '' },
111
+ };
112
+
113
+ handleSearch(keyword) {
114
+ this.setState({
115
+ searchKeyword: keyword,
116
+ });
117
+ }
118
+
119
+ getDepartmentById(id) {
120
+ return this.state.departments.find(dept => dept.id === id);
121
+ }
122
+
123
+ getDepartmentUsers(departmentId) {
124
+ return this.state.users.filter(user => user.departmentId === departmentId);
125
+ }
126
+
127
+ handleAddDepartment() {
128
+ this.setState({
129
+ showAddModal: true,
130
+ formData: {
131
+ name: '',
132
+ parentId: null,
133
+ manager: '',
134
+ description: '',
135
+ },
136
+ });
137
+ }
138
+
139
+ buildTreeData(departments) {
140
+ const map = {};
141
+ const roots = [];
142
+ departments.forEach(dept => {
143
+ map[dept.id] = {
144
+ ...dept,
145
+ children: [],
146
+ };
147
+ });
148
+ departments.forEach(dept => {
149
+ if (dept.parentId && map[dept.parentId]) {
150
+ map[dept.parentId].children.push(map[dept.id]);
151
+ } else {
152
+ roots.push(map[dept.id]);
153
+ }
154
+ });
155
+ return roots;
156
+ }
157
+
158
+ async handleSubmit(type) {
159
+ await new Promise(resolve => setTimeout(resolve, 500));
160
+ if (type === 'add') {
161
+ console.log('添加部门:', this.state.formData);
162
+ } else {
163
+ console.log('编辑部门:', this.state.formData);
164
+ }
165
+ this.setState({
166
+ showAddModal: false,
167
+ showEditModal: false,
168
+ });
169
+ }
170
+
171
+ handleEditDepartment(department) {
172
+ this.setState({
173
+ selectedDepartment: department,
174
+ formData: {
175
+ ...department,
176
+ },
177
+ showEditModal: true,
178
+ });
179
+ }
180
+
181
+ handleDeleteDepartment(id, record) {
182
+ console.log('删除部门:', id, record);
183
+ }
184
+
185
+ render() {
186
+ return (
187
+ <Page className="p-[24px] bg-[var(--gray-50)] min-h-screen">
188
+ <View className="mb-[24px]">
189
+ <Text className="text-2xl font-bold text-[#1f2937]">部门管理</Text>
190
+ <Text className="text-[#6b7280] text-sm mt-[4px]">
191
+ 管理组织架构和部门信息
192
+ </Text>
193
+ </View>
194
+ <View className="mb-[24px] flex items-center justify-between">
195
+ <View className="gap-4 flex items-center">
196
+ <Input
197
+ placeholder="搜索部门名称/描述"
198
+ value={this.state.searchKeyword}
199
+ onChange={e => this.handleSearch(e.target.value)}
200
+ prefix="🔍"
201
+ className=""
202
+ />
203
+ </View>
204
+ <Button type="primary" onClick={() => this.handleAddDepartment()}>
205
+ + 新增部门
206
+ </Button>
207
+ </View>
208
+ <View className="gap-6 flex">
209
+ <View className="w-[33.33333333333333%]">
210
+ <View className="bg-[#ffffff] rounded-lg p-[16px] shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)]">
211
+ <Text className="block font-bold mb-[16px]">组织架构</Text>
212
+ <Tree
213
+ treeData={this.buildTreeData(this.state.departments)}
214
+ defaultExpandAll={true}
215
+ onSelect={(keys, info) => console.log('选中:', keys, info)}
216
+ />
217
+ </View>
218
+ </View>
219
+ <View className="w-[66.66666666666666%]">
220
+ <Table
221
+ loading={this.state.loading}
222
+ columns={[
223
+ { title: 'ID', dataIndex: 'id', key: 'id', width: 60 },
224
+ { title: '部门名称', dataIndex: 'name', key: 'name' },
225
+ {
226
+ title: '上级部门',
227
+ dataIndex: 'parentId',
228
+ key: 'parentId',
229
+ render: parentId =>
230
+ (() => {
231
+ if (!parentId) return <Text>-</Text>;
232
+ const parent = this.state.departments.find(
233
+ d => d.id === parentId
234
+ );
235
+ return <Text>{parent?.name}</Text>;
236
+ })(),
237
+ },
238
+ { title: '负责人', dataIndex: 'manager', key: 'manager' },
239
+ {
240
+ title: '人数',
241
+ dataIndex: 'userCount',
242
+ key: 'userCount',
243
+ render: count => <Text>{count}人</Text>,
244
+ },
245
+ {
246
+ title: '层级',
247
+ dataIndex: 'level',
248
+ key: 'level',
249
+ render: level => (
250
+ <Tag color="blue">
251
+ L<Text>{level}</Text>
252
+ </Tag>
253
+ ),
254
+ },
255
+ { title: '描述', dataIndex: 'description', key: 'description' },
256
+ {
257
+ title: '操作',
258
+ key: 'action',
259
+ render: (text, record) => (
260
+ <Space>
261
+ <Button
262
+ type="link"
263
+ onClick={() => this.handleEditDepartment(record)}
264
+ >
265
+ 编辑
266
+ </Button>
267
+ <Popconfirm
268
+ title="确定要删除这个部门吗?"
269
+ description="删除后无法恢复"
270
+ onConfirm={() =>
271
+ this.handleDeleteDepartment(record.id, record)
272
+ }
273
+ okText="确定"
274
+ cancelText="取消"
275
+ >
276
+ <Button type="link" danger={true}>
277
+ 删除
278
+ </Button>
279
+ </Popconfirm>
280
+ </Space>
281
+ ),
282
+ },
283
+ ]}
284
+ dataSource={this.state.departments?.filter(function (dept) {
285
+ return (
286
+ dept?.name?.includes(this.state.searchKeyword) ||
287
+ dept?.description?.includes(this.state.searchKeyword)
288
+ );
289
+ })}
290
+ rowKey="id"
291
+ pagination={{
292
+ pageSize: 10,
293
+ showTotal: function (total) {
294
+ return `共 ${total} 条`;
295
+ },
296
+ }}
297
+ />
298
+ </View>
299
+ </View>
300
+ <Modal
301
+ animate="pop"
302
+ visible={this.state.showAddModal}
303
+ renderView={() => (
304
+ <View className="bg-[#ffffff] w-[600px] h-[500px] p-[24px]">
305
+ <Text className="text-xl font-bold mb-[16px]">新增部门</Text>
306
+ <View className="space-y-4">
307
+ <View>
308
+ <Text className="block mb-[8px]">部门名称</Text>
309
+ <Input
310
+ value={this.state.formData.name}
311
+ onChange={e =>
312
+ this.setState({
313
+ formData: {
314
+ ...this.state.formData,
315
+ name: e.target.value,
316
+ },
317
+ })
318
+ }
319
+ placeholder="请输入部门名称"
320
+ />
321
+ </View>
322
+ <View>
323
+ <Text className="block mb-[8px]">上级部门</Text>
324
+ <Select
325
+ value={this.state.formData.parentId}
326
+ onChange={value =>
327
+ this.setState({
328
+ formData: {
329
+ ...this.state.formData,
330
+ parentId: value,
331
+ },
332
+ })
333
+ }
334
+ placeholder="请选择上级部门(留空为顶级部门)"
335
+ className="w-full"
336
+ >
337
+ <Select.Option value={null}>无(顶级部门)</Select.Option>
338
+ {this.state.departments.map((dept, index) => (
339
+ <Select.Option key={dept.id} value={dept.id}>
340
+ <Text>{dept.name}</Text>
341
+ </Select.Option>
342
+ ))}
343
+ </Select>
344
+ </View>
345
+ <View>
346
+ <Text className="block mb-[8px]">负责人</Text>
347
+ <Input
348
+ value={this.state.formData.manager}
349
+ onChange={e =>
350
+ this.setState({
351
+ formData: {
352
+ ...this.state.formData,
353
+ manager: e.target.value,
354
+ },
355
+ })
356
+ }
357
+ placeholder="请输入负责人姓名"
358
+ />
359
+ </View>
360
+ <View>
361
+ <Text className="block mb-[8px]">描述</Text>
362
+ <Input.TextArea
363
+ value={this.state.formData.description}
364
+ onChange={e =>
365
+ this.setState({
366
+ formData: {
367
+ ...this.state.formData,
368
+ description: e.target.value,
369
+ },
370
+ })
371
+ }
372
+ placeholder="请输入部门描述"
373
+ rows={4}
374
+ />
375
+ </View>
376
+ <View className="gap-2 flex justify-end mt-[24px]">
377
+ <Button
378
+ onClick={() =>
379
+ this.setState({
380
+ showAddModal: false,
381
+ })
382
+ }
383
+ >
384
+ 取消
385
+ </Button>
386
+ <Button
387
+ type="primary"
388
+ onClick={() => this.handleSubmit('add')}
389
+ >
390
+ 确认
391
+ </Button>
392
+ </View>
393
+ </View>
394
+ </View>
395
+ )}
396
+ maskClosable={true}
397
+ />
398
+ <Modal
399
+ animate="pop"
400
+ visible={this.state.showEditModal}
401
+ renderView={() => (
402
+ <View className="bg-[#ffffff] w-[600px] h-[500px] p-[24px]">
403
+ <Text className="text-xl font-bold mb-[16px]">
404
+ 编辑部门:{this.state.selectedDepartment?.name}
405
+ </Text>
406
+ <View className="space-y-4">
407
+ <View>
408
+ <Text className="block mb-[8px]">部门名称</Text>
409
+ <Input
410
+ value={this.state.formData.name}
411
+ onChange={e =>
412
+ this.setState({
413
+ formData: {
414
+ ...this.state.formData,
415
+ name: e.target.value,
416
+ },
417
+ })
418
+ }
419
+ placeholder="请输入部门名称"
420
+ />
421
+ </View>
422
+ <View>
423
+ <Text className="block mb-[8px]">上级部门</Text>
424
+ <Select
425
+ value={this.state.formData.parentId}
426
+ onChange={value =>
427
+ this.setState({
428
+ formData: {
429
+ ...this.state.formData,
430
+ parentId: value,
431
+ },
432
+ })
433
+ }
434
+ placeholder="请选择上级部门(留空为顶级部门)"
435
+ className="w-full"
436
+ >
437
+ <Select.Option value={null}>无(顶级部门)</Select.Option>
438
+ {this.state.departments.map((dept, index) => (
439
+ <Select.Option key={dept.id} value={dept.id}>
440
+ <Text>{dept.name}</Text>
441
+ </Select.Option>
442
+ ))}
443
+ </Select>
444
+ </View>
445
+ <View>
446
+ <Text className="block mb-[8px]">负责人</Text>
447
+ <Input
448
+ value={this.state.formData.manager}
449
+ onChange={e =>
450
+ this.setState({
451
+ formData: {
452
+ ...this.state.formData,
453
+ manager: e.target.value,
454
+ },
455
+ })
456
+ }
457
+ placeholder="请输入负责人姓名"
458
+ />
459
+ </View>
460
+ <View>
461
+ <Text className="block mb-[8px]">描述</Text>
462
+ <Input.TextArea
463
+ value={this.state.formData.description}
464
+ onChange={e =>
465
+ this.setState({
466
+ formData: {
467
+ ...this.state.formData,
468
+ description: e.target.value,
469
+ },
470
+ })
471
+ }
472
+ placeholder="请输入部门描述"
473
+ rows={4}
474
+ />
475
+ </View>
476
+ <View className="gap-2 flex justify-end mt-[24px]">
477
+ <Button
478
+ onClick={() =>
479
+ this.setState({
480
+ showEditModal: false,
481
+ })
482
+ }
483
+ >
484
+ 取消
485
+ </Button>
486
+ <Button
487
+ type="primary"
488
+ onClick={() => this.handleSubmit('edit')}
489
+ >
490
+ 确认
491
+ </Button>
492
+ </View>
493
+ </View>
494
+ </View>
495
+ )}
496
+ maskClosable={true}
497
+ />
498
+ </Page>
499
+ );
500
+ }
501
+ }
502
+
503
+ export default Document;