@appthen/cli 1.2.11 → 1.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/main.js +47 -0
- package/dist/index.js +6185 -15001
- package/package.json +8 -4
- package/tests/test-app/.appthen/shadow-space-100001-test-app-e99876b1.json +1197 -741
- package/tests/test-app/.appthen/space-config.json +2 -2
- package/tests/test-app/src/components/MessageCenter.tsx +506 -0
- package/tests/test-app/src/pages/CustomerManagement.tsx +535 -0
- package/tests/test-app/src/pages/CyberpunkDashboard.tsx +348 -0
- package/tests/test-app/src/pages/CyberpunkProductManagement.tsx +637 -0
- package/tests/test-app/src/pages/CyberpunkUserList.tsx +316 -0
- package/tests/test-app/src/pages/DashboardV2.tsx +334 -0
- package/tests/test-app/src/pages/DataReport.tsx +298 -0
- package/tests/test-app/src/pages/DataStatistics.tsx +317 -0
- package/tests/test-app/src/pages/DepartmentManagement.tsx +503 -0
- package/tests/test-app/src/pages/FileExplorer.tsx +441 -0
- package/tests/test-app/src/pages/OrderDetail.tsx +393 -0
- package/tests/test-app/src/pages/ProductManagement.tsx +521 -0
- package/tests/test-app/src/pages/ProjectTimeline.tsx +395 -0
- package/tests/test-app/src/pages/RoleManagement.tsx +523 -0
- package/tests/test-app/src/pages/StaticCyberpunkDashboard.tsx +462 -0
- package/tests/test-app/src/pages/StaticCyberpunkUserList.tsx +567 -0
- package/tests/test-app/src/pages/StudentWeaknessList.tsx +547 -0
- package/tests/test-app/src/pages/SystemSettings.tsx +422 -0
- package/tests/test-app/src/pages/TaskManagement.tsx +467 -0
- package/tests/test-app/src/pages/TicketManagement.tsx +402 -0
- package/tests/test-app/src/pages/UserProfile.tsx +404 -0
- package/tests/test-app/src/pages/WorkflowDesigner.tsx +434 -0
- package/tests/test-app/src/pages/admin/dashboard.tsx +591 -0
- package/tests/test-app/src/pages/article-list.tsx +222 -0
- package/tests/test-app/src/pages/babyProductRecommendationPage.tsx +168 -0
- package/tests/test-app/src/pages/category-list.tsx +179 -0
- package/tests/test-app/src/pages/comment-list.tsx +194 -0
- package/tests/test-app/src/pages/cyberpunk/cyberpunkCRMPage.tsx +1299 -0
- package/tests/test-app/src/pages/data-analytics.tsx +1872 -0
- package/tests/test-app/src/pages/data-overview.tsx +600 -0
- package/tests/test-app/src/pages/demo-error-page.tsx +119 -0
- package/tests/test-app/src/pages/department-list.tsx +183 -0
- package/tests/test-app/src/pages/goods-list.tsx +233 -0
- package/tests/test-app/src/pages/housekeeping/adminDashboardPage.tsx +880 -0
- package/tests/test-app/src/pages/mobile_terminal/uiHandsOnPractice.tsx +1 -1
- package/tests/test-app/src/pages/notice-list.tsx +217 -0
- package/tests/test-app/src/pages/order-detail.tsx +330 -0
- package/tests/test-app/src/pages/order-list.tsx +195 -0
- package/tests/test-app/src/pages/order-management.tsx +563 -0
- package/tests/test-app/src/pages/page/OrderList.tsx +230 -0
- package/tests/test-app/src/pages/role-list.tsx +184 -0
- package/tests/test-app/src/pages/simple/simplePage.tsx +92 -0
- package/tests/test-app/src/pages/simple-page.tsx +43 -0
- package/tests/test-app/src/pages/test-destructure.tsx +44 -0
- package/tests/test-app/src/pages/test-error-page.tsx +75 -0
- package/tests/test-app/src/pages/test-page-with-errors.tsx +51 -0
- package/tests/test-app/src/pages/test-page.tsx +101 -0
- package/tests/test-app/src/pages/test-render.tsx +52 -0
- package/tests/test-app/src/pages/test-return-type.tsx +41 -0
- package/tests/test-app/src/pages/test-type-assertion.tsx +37 -0
- package/tests/test-app/src/pages/ui/styleSelectorPage.tsx +1554 -0
- package/tests/test-app/src/pages/user-list.tsx +212 -0
- package/tests/test-app/src/pages/wrong-page.tsx +50 -0
- package/tests/test-app/.appthen/shadow-space-unknown-user-test-app-e99876b1.json +0 -1060
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 用户资料
|
|
3
|
+
* 用户个人信息管理
|
|
4
|
+
*
|
|
5
|
+
* @type Page
|
|
6
|
+
* @route /profile
|
|
7
|
+
* @screen 1920w
|
|
8
|
+
* @frames web
|
|
9
|
+
*/
|
|
10
|
+
import React from 'react';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class IProps {
|
|
15
|
+
userId?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* 数据与接口请求定义
|
|
20
|
+
*/
|
|
21
|
+
class IState {
|
|
22
|
+
userInfo?: {
|
|
23
|
+
/* @example 1 */id?: number,
|
|
24
|
+
/* @example zhangsan */username?: string,
|
|
25
|
+
/* @example 张三 */realName?: string,
|
|
26
|
+
/* @example zhangsan@example.com */email?: string,
|
|
27
|
+
/* @example 13800138000 */phone?: string,
|
|
28
|
+
/* @example male */gender?: string,
|
|
29
|
+
/* @example 1990-01-01 */birthday?: string,
|
|
30
|
+
/* @example https://via.placeholder.com/150 */avatar?: string,
|
|
31
|
+
/* @example 全栈开发工程师 */bio?: string,
|
|
32
|
+
/* @example 北京市海淀区 */location?: string,
|
|
33
|
+
/* @example https://example.com */website?: string,
|
|
34
|
+
/* @example active */status?: string,
|
|
35
|
+
/* @example 2024-01-01 */createTime?: string,
|
|
36
|
+
};
|
|
37
|
+
loading?: boolean;
|
|
38
|
+
editing?: boolean;
|
|
39
|
+
activeTab?: string;
|
|
40
|
+
formData?: any;
|
|
41
|
+
uploadProgress?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
class Document extends React.Component<IProps, IState> {
|
|
45
|
+
state = {
|
|
46
|
+
userInfo: {
|
|
47
|
+
id: 1,
|
|
48
|
+
username: 'zhangsan',
|
|
49
|
+
realName: '张三',
|
|
50
|
+
email: 'zhangsan@example.com',
|
|
51
|
+
phone: '13800138000',
|
|
52
|
+
gender: 'male',
|
|
53
|
+
birthday: '1990-01-01',
|
|
54
|
+
avatar: 'https://via.placeholder.com/150',
|
|
55
|
+
bio: '全栈开发工程师',
|
|
56
|
+
location: '北京市海淀区',
|
|
57
|
+
website: 'https://example.com',
|
|
58
|
+
status: 'active',
|
|
59
|
+
createTime: '2024-01-01',
|
|
60
|
+
},
|
|
61
|
+
loading: false,
|
|
62
|
+
editing: false,
|
|
63
|
+
activeTab: 'basic',
|
|
64
|
+
formData: {},
|
|
65
|
+
uploadProgress: 0,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
handleTabChange(key) {
|
|
69
|
+
this.setState({
|
|
70
|
+
activeTab: key,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
toggleEdit() {
|
|
75
|
+
this.setState({
|
|
76
|
+
editing: !this.state.editing,
|
|
77
|
+
formData: this.state.editing
|
|
78
|
+
? {}
|
|
79
|
+
: {
|
|
80
|
+
...this.state.userInfo,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
handleSave() {
|
|
86
|
+
this.setState({
|
|
87
|
+
userInfo: {
|
|
88
|
+
...this.state.userInfo,
|
|
89
|
+
...this.state.formData,
|
|
90
|
+
},
|
|
91
|
+
editing: false,
|
|
92
|
+
loading: true,
|
|
93
|
+
});
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
this.setState({
|
|
96
|
+
loading: false,
|
|
97
|
+
});
|
|
98
|
+
}, 1000);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
handleFieldChange(field, value) {
|
|
102
|
+
this.setState({
|
|
103
|
+
formData: {
|
|
104
|
+
...this.state.formData,
|
|
105
|
+
[field]: value,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
handleAvatarUpload(file) {
|
|
111
|
+
this.setState({
|
|
112
|
+
uploadProgress: 0,
|
|
113
|
+
});
|
|
114
|
+
const interval = setInterval(() => {
|
|
115
|
+
const progress = this.state.uploadProgress + 10;
|
|
116
|
+
if (progress >= 100) {
|
|
117
|
+
clearInterval(interval);
|
|
118
|
+
this.setState({
|
|
119
|
+
uploadProgress: 100,
|
|
120
|
+
});
|
|
121
|
+
} else {
|
|
122
|
+
this.setState({
|
|
123
|
+
uploadProgress: progress,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}, 200);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
resetPassword() {
|
|
130
|
+
console.log('重置密码');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
logout() {
|
|
134
|
+
console.log('退出登录');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
render() {
|
|
138
|
+
// 💀 死亡:变量声明 - 解构赋值
|
|
139
|
+
const { userInfo, loading, editing, activeTab, formData, uploadProgress } =
|
|
140
|
+
this.state;
|
|
141
|
+
|
|
142
|
+
// 💀 死亡:变量声明 - 计算属性
|
|
143
|
+
// 💀 死亡:变量声明 - 计算属性
|
|
144
|
+
const age =
|
|
145
|
+
new Date().getFullYear() - new Date(userInfo.birthday).getFullYear();
|
|
146
|
+
const isEmailVerified = true;
|
|
147
|
+
const accountStatus = userInfo.status === 'active' ? '正常' : '已禁用';
|
|
148
|
+
|
|
149
|
+
// 💀 死亡:变量声明 - 配置对象
|
|
150
|
+
// 💀 死亡:变量声明 - 配置对象
|
|
151
|
+
const genderOptions = [
|
|
152
|
+
{
|
|
153
|
+
label: '男',
|
|
154
|
+
value: 'male',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
label: '女',
|
|
158
|
+
value: 'female',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
label: '保密',
|
|
162
|
+
value: 'secret',
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
// 💀 死亡:变量声明 - 标签页配置
|
|
167
|
+
// 💀 死亡:变量声明 - 标签页配置
|
|
168
|
+
const tabItems = [
|
|
169
|
+
{
|
|
170
|
+
key: 'basic',
|
|
171
|
+
label: '基本信息',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
key: 'contact',
|
|
175
|
+
label: '联系方式',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
key: 'security',
|
|
179
|
+
label: '安全设置',
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
key: 'privacy',
|
|
183
|
+
label: '隐私设置',
|
|
184
|
+
},
|
|
185
|
+
];
|
|
186
|
+
|
|
187
|
+
// 💀 死亡:if 语句 - 条件渲染
|
|
188
|
+
// 💀 死亡:if 语句 - 条件渲染
|
|
189
|
+
if (loading) {
|
|
190
|
+
return <View className="p-6">加载中...</View>;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// 💀 死亡:变量声明 - JSX 片段函数
|
|
194
|
+
// 💀 死亡:变量声明 - JSX 片段函数
|
|
195
|
+
const basicInfoForm = () => (
|
|
196
|
+
<View className="space-y-4">
|
|
197
|
+
<View className="flex items-center gap-4 mb-6">
|
|
198
|
+
<Avatar size={80} src={userInfo.avatar} />
|
|
199
|
+
<View>
|
|
200
|
+
<Text className="text-xl font-bold">{userInfo.realName}</Text>
|
|
201
|
+
<Text className="text-gray-500">@{userInfo.username}</Text>
|
|
202
|
+
</View>
|
|
203
|
+
{!editing && (
|
|
204
|
+
<Button onClick={() => this.handleAvatarUpload(null)}>
|
|
205
|
+
更换头像
|
|
206
|
+
</Button>
|
|
207
|
+
)}
|
|
208
|
+
</View>
|
|
209
|
+
{uploadProgress > 0 && uploadProgress < 100 && (
|
|
210
|
+
<View className="mb-4">
|
|
211
|
+
<Text>上传进度: {uploadProgress}%</Text>
|
|
212
|
+
</View>
|
|
213
|
+
)}
|
|
214
|
+
</View>
|
|
215
|
+
);
|
|
216
|
+
return (
|
|
217
|
+
<Page className="p-[24px] bg-[var(--gray-50)] min-h-screen">
|
|
218
|
+
<View className="mb-[24px]">
|
|
219
|
+
<Text className="text-2xl font-bold text-[#1f2937]">用户资料</Text>
|
|
220
|
+
<Text className="text-[#6b7280] text-sm mt-[4px]">
|
|
221
|
+
用户个人信息管理
|
|
222
|
+
</Text>
|
|
223
|
+
</View>
|
|
224
|
+
<Card className="mb-[24px]">
|
|
225
|
+
<View className="flex items-center justify-between">
|
|
226
|
+
<View className="gap-4 flex items-center">
|
|
227
|
+
<Avatar size={64} src={userInfo.avatar} />
|
|
228
|
+
<View>
|
|
229
|
+
<Text className="text-xl font-bold">{userInfo.realName}</Text>
|
|
230
|
+
<Text className="text-[#6b7280]">@{userInfo.username}</Text>
|
|
231
|
+
<View className="gap-2 flex items-center mt-[4px]">
|
|
232
|
+
<Tag color="blue">
|
|
233
|
+
<Text>{accountStatus}</Text>
|
|
234
|
+
</Tag>
|
|
235
|
+
{!!isEmailVerified && <Tag color="green">已验证</Tag>}
|
|
236
|
+
</View>
|
|
237
|
+
</View>
|
|
238
|
+
</View>
|
|
239
|
+
<View className="gap-2 flex">
|
|
240
|
+
<Button onClick={() => this.toggleEdit()}>
|
|
241
|
+
{editing ? '取消' : '编辑'}
|
|
242
|
+
</Button>
|
|
243
|
+
{!!editing && (
|
|
244
|
+
<Button type="primary" onClick={() => this.handleSave()}>
|
|
245
|
+
保存
|
|
246
|
+
</Button>
|
|
247
|
+
)}
|
|
248
|
+
</View>
|
|
249
|
+
</View>
|
|
250
|
+
</Card>
|
|
251
|
+
<Card>
|
|
252
|
+
<Tabs
|
|
253
|
+
activeKey={activeTab}
|
|
254
|
+
onChange={key => this.handleTabChange(key)}
|
|
255
|
+
>
|
|
256
|
+
<Tabs.TabPane tab="基本信息" key="basic">
|
|
257
|
+
<View className="gap-6 grid grid-cols-2">
|
|
258
|
+
<View>
|
|
259
|
+
<Text className="block mb-[8px]">用户名</Text>
|
|
260
|
+
<Input
|
|
261
|
+
value={editing ? formData.username : userInfo.username}
|
|
262
|
+
disabled={!editing}
|
|
263
|
+
onChange={e =>
|
|
264
|
+
this.handleFieldChange('username', e.target.value)
|
|
265
|
+
}
|
|
266
|
+
/>
|
|
267
|
+
</View>
|
|
268
|
+
<View>
|
|
269
|
+
<Text className="block mb-[8px]">真实姓名</Text>
|
|
270
|
+
<Input
|
|
271
|
+
value={editing ? formData.realName : userInfo.realName}
|
|
272
|
+
disabled={!editing}
|
|
273
|
+
onChange={e =>
|
|
274
|
+
this.handleFieldChange('realName', e.target.value)
|
|
275
|
+
}
|
|
276
|
+
/>
|
|
277
|
+
</View>
|
|
278
|
+
<View>
|
|
279
|
+
<Text className="block mb-[8px]">性别</Text>
|
|
280
|
+
<Radio.Group
|
|
281
|
+
value={editing ? formData.gender : userInfo.gender}
|
|
282
|
+
disabled={!editing}
|
|
283
|
+
onChange={e =>
|
|
284
|
+
this.handleFieldChange('gender', e.target.value)
|
|
285
|
+
}
|
|
286
|
+
>
|
|
287
|
+
{genderOptions.map((opt, index) => (
|
|
288
|
+
<Radio key={opt.value} value={opt.value}>
|
|
289
|
+
<Text>{opt.label}</Text>
|
|
290
|
+
</Radio>
|
|
291
|
+
))}
|
|
292
|
+
</Radio.Group>
|
|
293
|
+
</View>
|
|
294
|
+
<View>
|
|
295
|
+
<Text className="block mb-[8px]">生日</Text>
|
|
296
|
+
<DatePicker
|
|
297
|
+
value={editing ? formData.birthday : userInfo.birthday}
|
|
298
|
+
disabled={!editing}
|
|
299
|
+
onChange={date => this.handleFieldChange('birthday', date)}
|
|
300
|
+
/>
|
|
301
|
+
</View>
|
|
302
|
+
<View>
|
|
303
|
+
<Text className="block mb-[8px]">年龄</Text>
|
|
304
|
+
<Text>{age}岁</Text>
|
|
305
|
+
</View>
|
|
306
|
+
</View>
|
|
307
|
+
</Tabs.TabPane>
|
|
308
|
+
<Tabs.TabPane tab="联系方式" key="contact">
|
|
309
|
+
<View className="gap-6 grid grid-cols-2">
|
|
310
|
+
<View>
|
|
311
|
+
<Text className="block mb-[8px]">邮箱</Text>
|
|
312
|
+
<Input
|
|
313
|
+
value={editing ? formData.email : userInfo.email}
|
|
314
|
+
disabled={!editing}
|
|
315
|
+
onChange={e =>
|
|
316
|
+
this.handleFieldChange('email', e.target.value)
|
|
317
|
+
}
|
|
318
|
+
/>
|
|
319
|
+
</View>
|
|
320
|
+
<View>
|
|
321
|
+
<Text className="block mb-[8px]">手机号</Text>
|
|
322
|
+
<Input
|
|
323
|
+
value={editing ? formData.phone : userInfo.phone}
|
|
324
|
+
disabled={!editing}
|
|
325
|
+
onChange={e =>
|
|
326
|
+
this.handleFieldChange('phone', e.target.value)
|
|
327
|
+
}
|
|
328
|
+
/>
|
|
329
|
+
</View>
|
|
330
|
+
<View>
|
|
331
|
+
<Text className="block mb-[8px]">位置</Text>
|
|
332
|
+
<Input
|
|
333
|
+
value={editing ? formData.location : userInfo.location}
|
|
334
|
+
disabled={!editing}
|
|
335
|
+
onChange={e =>
|
|
336
|
+
this.handleFieldChange('location', e.target.value)
|
|
337
|
+
}
|
|
338
|
+
/>
|
|
339
|
+
</View>
|
|
340
|
+
<View>
|
|
341
|
+
<Text className="block mb-[8px]">个人网站</Text>
|
|
342
|
+
<Input
|
|
343
|
+
value={editing ? formData.website : userInfo.website}
|
|
344
|
+
disabled={!editing}
|
|
345
|
+
onChange={e =>
|
|
346
|
+
this.handleFieldChange('website', e.target.value)
|
|
347
|
+
}
|
|
348
|
+
/>
|
|
349
|
+
</View>
|
|
350
|
+
</View>
|
|
351
|
+
</Tabs.TabPane>
|
|
352
|
+
<Tabs.TabPane tab="安全设置" key="security">
|
|
353
|
+
<View className="space-y-4">
|
|
354
|
+
<View>
|
|
355
|
+
<Text className="block mb-[8px]">修改密码</Text>
|
|
356
|
+
<Button onClick={() => this.resetPassword()}>重置密码</Button>
|
|
357
|
+
</View>
|
|
358
|
+
<View>
|
|
359
|
+
<Text className="block mb-[8px]">两步验证</Text>
|
|
360
|
+
<Switch
|
|
361
|
+
checked={false}
|
|
362
|
+
onChange={checked => console.log('两步验证:', checked)}
|
|
363
|
+
/>
|
|
364
|
+
<Text className="text-[#6b7280] ml-[8px]">未启用</Text>
|
|
365
|
+
</View>
|
|
366
|
+
</View>
|
|
367
|
+
</Tabs.TabPane>
|
|
368
|
+
<Tabs.TabPane tab="隐私设置" key="privacy">
|
|
369
|
+
<View className="space-y-4">
|
|
370
|
+
<View>
|
|
371
|
+
<Text className="block mb-[8px]">公开个人资料</Text>
|
|
372
|
+
<Switch
|
|
373
|
+
checked={true}
|
|
374
|
+
onChange={checked =>
|
|
375
|
+
this.handleFieldChange('publicProfile', checked)
|
|
376
|
+
}
|
|
377
|
+
/>
|
|
378
|
+
</View>
|
|
379
|
+
<View>
|
|
380
|
+
<Text className="block mb-[8px]">允许私信</Text>
|
|
381
|
+
<Switch
|
|
382
|
+
checked={false}
|
|
383
|
+
onChange={checked =>
|
|
384
|
+
this.handleFieldChange('allowMessages', checked)
|
|
385
|
+
}
|
|
386
|
+
/>
|
|
387
|
+
</View>
|
|
388
|
+
</View>
|
|
389
|
+
</Tabs.TabPane>
|
|
390
|
+
</Tabs>
|
|
391
|
+
</Card>
|
|
392
|
+
<Card className="mt-[24px]">
|
|
393
|
+
<View className="gap-2 flex justify-end">
|
|
394
|
+
<Button onClick={() => this.logout()} danger={true}>
|
|
395
|
+
退出登录
|
|
396
|
+
</Button>
|
|
397
|
+
</View>
|
|
398
|
+
</Card>
|
|
399
|
+
</Page>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export default Document;
|