feat(entry): 复刻四大主页面与底部导航
This commit is contained in:
184
entry/src/main/ets/pages/ProfilePage.ets
Normal file
184
entry/src/main/ets/pages/ProfilePage.ets
Normal file
@@ -0,0 +1,184 @@
|
||||
import { AppColor, AppSpacing, AppFontSize, AppRadius, LoadingView, ErrorState, Avatar, LabeledRow } from 'uikit';
|
||||
import { SessionManager, SessionStore } from 'common';
|
||||
import { ProfileViewModel } from '../viewmodel/ProfileViewModel';
|
||||
import { ClassGroup } from '../model/ProfileModels';
|
||||
|
||||
/**
|
||||
* 我的页:资料展示 + 模拟登录 / 退出登录。
|
||||
*/
|
||||
@ComponentV2
|
||||
export struct ProfilePage {
|
||||
@Local viewModel: ProfileViewModel = ProfileViewModel.create();
|
||||
@Local session: SessionStore = SessionManager.get();
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.viewModel.load();
|
||||
}
|
||||
|
||||
@Monitor('session.token')
|
||||
onSessionChange(): void {
|
||||
this.viewModel.load();
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
if (!this.viewModel.loggedIn) {
|
||||
this.loginCard()
|
||||
} else if (this.viewModel.loading) {
|
||||
Column() {
|
||||
LoadingView({ text: '加载中...' })
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
} else if (this.viewModel.error.length > 0) {
|
||||
ErrorState({ message: this.viewModel.error, onRetry: () => { this.viewModel.load(); } })
|
||||
} else {
|
||||
Scroll() {
|
||||
Column({ space: AppSpacing.md }) {
|
||||
this.profileHeader()
|
||||
this.infoCard()
|
||||
if (this.viewModel.profile.classGroups.length > 0) {
|
||||
this.classGroupCard()
|
||||
}
|
||||
this.logoutButton()
|
||||
}
|
||||
.width('100%')
|
||||
.padding(AppSpacing.lg)
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.scrollBar(BarState.Off)
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor(AppColor.background)
|
||||
}
|
||||
|
||||
@Builder
|
||||
loginCard() {
|
||||
Column({ space: AppSpacing.md }) {
|
||||
Text('👤')
|
||||
.fontSize(40)
|
||||
Text('未登录')
|
||||
.fontSize(AppFontSize.title)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontColor(AppColor.textPrimary)
|
||||
Text('登录后即可查看个人信息')
|
||||
.fontSize(AppFontSize.body)
|
||||
.fontColor(AppColor.textMuted)
|
||||
Text('模拟登录')
|
||||
.fontSize(AppFontSize.body)
|
||||
.fontColor(AppColor.white)
|
||||
.padding({ left: 32, right: 32, top: 10, bottom: 10 })
|
||||
.backgroundColor(AppColor.gold)
|
||||
.borderRadius(AppRadius.pill)
|
||||
.onClick(() => {
|
||||
this.viewModel.login();
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
|
||||
@Builder
|
||||
profileHeader() {
|
||||
Row({ space: AppSpacing.md }) {
|
||||
Avatar({ name: this.viewModel.profile.displayName, diameter: 56 })
|
||||
Column({ space: 4 }) {
|
||||
Row({ space: 8 }) {
|
||||
Text(this.viewModel.profile.displayName)
|
||||
.fontSize(AppFontSize.headline)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontColor(AppColor.textPrimary)
|
||||
Text(this.viewModel.profile.role)
|
||||
.fontSize(AppFontSize.caption)
|
||||
.fontColor(AppColor.gold)
|
||||
.padding({ left: 10, right: 10, top: 4, bottom: 4 })
|
||||
.backgroundColor(AppColor.neutralChip)
|
||||
.borderRadius(AppRadius.pill)
|
||||
}
|
||||
Text(this.viewModel.profile.studentId)
|
||||
.fontSize(AppFontSize.caption)
|
||||
.fontColor(AppColor.textMuted)
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
.width('100%')
|
||||
.padding(AppSpacing.md)
|
||||
.backgroundColor(AppColor.white)
|
||||
.borderRadius(AppRadius.lg)
|
||||
}
|
||||
|
||||
@Builder
|
||||
infoCard() {
|
||||
Column({ space: 0 }) {
|
||||
Text('个人信息')
|
||||
.fontSize(AppFontSize.title)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontColor(AppColor.textPrimary)
|
||||
.width('100%')
|
||||
.margin({ bottom: 4 })
|
||||
|
||||
LabeledRow({ label: '姓名', value: this.viewModel.profile.name })
|
||||
LabeledRow({ label: '学号', value: this.viewModel.profile.studentId })
|
||||
LabeledRow({ label: '手机号', value: this.viewModel.profile.phone })
|
||||
LabeledRow({ label: '角色', value: this.viewModel.profile.role })
|
||||
LabeledRow({ label: '小组', value: this.viewModel.profile.group })
|
||||
LabeledRow({ label: '登录方式', value: this.viewModel.profile.loginType })
|
||||
}
|
||||
.width('100%')
|
||||
.padding(AppSpacing.md)
|
||||
.backgroundColor(AppColor.white)
|
||||
.borderRadius(AppRadius.lg)
|
||||
}
|
||||
|
||||
@Builder
|
||||
classGroupCard() {
|
||||
Column({ space: 0 }) {
|
||||
Text('小组分组')
|
||||
.fontSize(AppFontSize.title)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontColor(AppColor.textPrimary)
|
||||
.width('100%')
|
||||
.margin({ bottom: 4 })
|
||||
|
||||
ForEach(this.viewModel.profile.classGroups, (cg: ClassGroup) => {
|
||||
Row() {
|
||||
Text(cg.period)
|
||||
.fontSize(AppFontSize.body)
|
||||
.fontColor(AppColor.textMuted)
|
||||
Blank()
|
||||
Text(cg.group + ' · ' + cg.role)
|
||||
.fontSize(AppFontSize.body)
|
||||
.fontColor(AppColor.textPrimary)
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ top: 12, bottom: 12 })
|
||||
}, (cg: ClassGroup) => cg.period + cg.group)
|
||||
}
|
||||
.width('100%')
|
||||
.padding(AppSpacing.md)
|
||||
.backgroundColor(AppColor.white)
|
||||
.borderRadius(AppRadius.lg)
|
||||
}
|
||||
|
||||
@Builder
|
||||
logoutButton() {
|
||||
Text('退出登录')
|
||||
.fontSize(AppFontSize.body)
|
||||
.fontColor(AppColor.danger)
|
||||
.width('100%')
|
||||
.height(48)
|
||||
.textAlign(TextAlign.Center)
|
||||
.backgroundColor(AppColor.white)
|
||||
.borderRadius(AppRadius.md)
|
||||
.border({ width: 1, color: AppColor.danger })
|
||||
.onClick(() => {
|
||||
this.viewModel.logout();
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user