一、个人中心页面概览
个人中心(MineView)提供用户信息展示、登录/登出、功能入口(历史记录、反馈建议、关于我们)和版本信息展示。
@Componentexportstruct MineView{@StateprivateisLoggedIn:boolean=false;@StateprivateuserName:string='点我登录';@Stateprivateavatar:Resource|string=$r('app.media.ic_head');@StateversionName:string='V1.0.1';privatepageContext:PageContext=AppStorage.get('pageContext')asPageContext;asyncaboutToAppear():Promise<void>{this.updateLoginState()this.versionName=awaitgetAppVersion()}build(){Column(){this.buildTopBar();Column(){this.buildUserInfo();this.buildSecondRow();Blank().layoutWeight(1)this.buildVersionInfo();}.width('100%')}.width('100%').height('100%').backgroundColor($r('app.color.color_background'))}}二、华为一键登录集成
2.1 BackupManagerService 初始化
MeCharts 使用backup_air三方库集成华为云服务,包括一键登录和数据备份:
exportdefaultclassBackupManagerService{privatestaticinstance:BackupManagerService;privateisInitialized:boolean=false;privateisLoggedIn:boolean=false;publicstaticgetInstance():BackupManagerService{if(!BackupManagerService.instance){BackupManagerService.instance=newBackupManagerService();}returnBackupManagerService.instance;}publicasyncinitializeBackupManager():Promise<void>{try{constbackupManager=BackupManager.getInstance();letstore=(awaitDbUtil.getInstance(getContext().getApplicationContext())).store;if(!store){thrownewError('未初始化数据库');}backupManager.init({onCompleteBackup:()=>{console.log('自定义回调- 备份完成');},onCompleteRestore:()=>{console.log('自定义回调- 恢复完成');},updateDbVersion:(cloudDbVersion)=>{console.log("自定义回调- 更新数据库版本 云端数据库版本"+cloudDbVersion);},cloudDir:`testUser`,cloudDbName:'Partner.db',storeConfig:DbUtil.STORE_CONFIG,backupDirs:[newBackupDir("testDir","testCloud.zip")],cloudStorageType:'sdk',bucketName:"partner-xhmds",productId:'461323198430551180',client_id:'1788670196915914048',client_secret:'***',oauth_client_id:"6917585955626292994",oauth_client_secret:'***',},store);this.isInitialized=true;this.isLoggedIn=true;}catch(error){this.isInitialized=false;this.isLoggedIn=false;}}}初始化参数说明:
| 参数 | 说明 |
|---|---|
onCompleteBackup | 备份完成回调 |
onCompleteRestore | 恢复完成回调 |
updateDbVersion | 云端数据库版本变更回调 |
cloudDir | 云存储用户目录 |
cloudDbName | 云端数据库名称 |
cloudStorageType | sdk需登录,http不需登录 |
bucketName | 存储桶名称 |
productId | AGC 项目 ID |
2.2 登录流程
login(){constbackupManager=BackupManager.getInstance();if(!BackupManagerService.getInstance().isBackupManagerInitialized()){promptAction.showToast({message:'等待初始化完成'});return;}this.isLoggedIn=UserInfoManager.isLoggedIn();if(this.isLoggedIn){return// 已登录,不重复登录}try{backupManager.login();setTimeout(()=>{this.updateLoginState();if(this.isLoggedIn){// 登录成功}else{promptAction.showToast({message:'登录失败'});}},1000);}catch(error){promptAction.showToast({message:'登录失败'});}}backupManager.login()调用华为一键登录服务,无需用户输入账号密码即可完成认证。
2.3 登录状态管理
privateupdateLoginState(){this.isLoggedIn=UserInfoManager.isLoggedIn();if(this.isLoggedIn){constuserInfoData=UserInfoManager.getUserInfo();this.userInfo=`${userInfoData?.nickName||'未设置'}`;this.avatar=userInfoData?.avatarUri||$r('app.media.ic_head')}else{this.userInfo='未登录';this.avatar=$r('app.media.ic_head')}}2.4 登出功能
@BuilderbuildRightContent(){Image($r('app.media.ic_logout')).width(24).height(24).onClick(()=>{UserInfoManager.clearUserInfo()this.updateLoginState()}).visibility(this.isLoggedIn?Visibility.Visible:Visibility.None)}登出按钮只在已登录状态显示,点击后清除用户信息并刷新 UI。
三、用户信息展示
3.1 用户头像与昵称
@BuilderbuildUserInfo(){Column(){Image(this.avatar).width(60).height(60).borderRadius(40)Row(){Text(this.userInfo).fontSize(16).fontWeight(FontWeight.Bold).fontColor(this.isLoggedIn?'#333333':'#999999')}.margin({top:10})}.width('100%').padding(20).margin({top:30}).onClick(()=>{if(!this.isLoggedIn){this.login()}})}未登录时显示默认头像和灰色文字"未登录",点击触发登录;已登录时显示用户头像和昵称。
四、功能卡片入口
4.1 通用卡片组件
@BuilderbuildCard(icon:Resource,title:string,onClick:()=>void){Column(){Image(icon).width(40).height(40)Text(title).fontSize(14).margin({top:8})}.width(100).height(100).justifyContent(FlexAlign.Center).backgroundColor($r('app.color.color_card')).borderRadius(12).shadow({radius:8,color:'#1a000000',offsetX:0,offsetY:2}).onClick(onClick)}4.2 功能入口布局
@BuilderbuildSecondRow(){Row(){this.buildCard($r("app.media.ic_record"),'历史记录',()=>{this.pageContext.openPage({routerName:'RecordPage',},true);});this.buildCard($r('app.media.ic_feedback'),'反馈建议',()=>{this.pageContext.openPage({param:{title:'反馈建议',url:'https://ncn1rpfvd5vb.feishu.cn/share/base/form/shrcn0YEc3umGFsTAcZimonouTC',}asResultParams,routerName:'WebPage',},true);});this.buildCard($r('app.media.ic_praise'),'关于我们',()=>{this.pageContext.openPage({routerName:'AboutPage',},true);});}.width('100%').justifyContent(FlexAlign.SpaceEvenly).margin({top:20}).padding({left:20,right:20})}三个功能入口采用SpaceEvenly均匀排列,视觉上简洁对称。
五、版本信息获取
5.1 动态获取应用版本
asyncfunctiongetAppVersion():Promise<string>{try{constbundleInfo=awaitbundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT);returnbundleInfo.versionName}catch(err){console.error('getBundleInfoForSelf failed:',JSON.stringify(err));return'1.0.1'}}bundleManager.getBundleInfoForSelf()可获取当前应用的包信息,包括版本名、版本号等。无需声明额外权限。
5.2 版本信息展示
@BuilderbuildVersionInfo(){Text(`当前版本${this.versionName}`).fontSize(12).fontColor('#999999').width('100%').textAlign(TextAlign.Center).margin({top:60,bottom:20})}六、关于页面
6.1 AboutPage 实现
@Componentstruct AboutPage{privatepageContext:PageContext=AppStorage.get('pageContext')asPageContext;build(){NavDestination(){Column({space:10}){this.buildTopBar()Column({space:10}){Image($r('app.media.app_icon')).width(60).height(60).margin({top:20})Text('柚兔自测量表').fontSize(18).margin({top:10,bottom:40})SettingItem({name:'用户协议'}).onClick(()=>{this.pageContext.openPage({param:{title:'用户协议',url:UrlConstants.URL_USER}asResultParams,routerName:'WebPage',},true);}).width('100%')SettingItem({name:'隐私政策'}).onClick(()=>{this.pageContext.openPage({param:{title:'隐私政策',url:UrlConstants.URL_PRIVACY}asResultParams,routerName:'WebPage',},true);}).width('100%')this.buildRow('作者微信','gy09312')Blank().layoutWeight(1)Text('如果您想添加某些功能或者有什么意见建议都可以通过以上途径联系到我,感谢您的反馈!').fontSize(12).fontColor($r('app.color.color_text')).padding(15)Text('鲁ICP备2024092126号-6A').fontSize(12).fontColor($r('app.color.color_text')).padding(15)}.width('100%').layoutWeight(1)}}}}6.2 SettingItem 通用设置项组件
@Componentexportstruct SettingItem{@Propname:string@Propcontent?:stringbuild(){Row({space:7}){Text(this.name).fontWeight(FontWeight.Medium)Blank().layoutWeight(1)if(this.content){Text(this.content).fontSize(12)}Image($r('app.media.ic_enter')).width(14)}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({left:12,right:12})}}SettingItem是一个简洁的设置项组件:左侧名称、右侧可选内容+箭头,支持@Prop数据传递。
七、Web 页面容器
用户协议、隐私政策和反馈建议都通过WebPage加载网页内容:
@Componentstruct WebPage{controller:webview.WebviewController=newwebview.WebviewController();@Stateurl:string=''@Statetitle:string=''@StateisLoading:boolean=truebuild(){NavDestination(){Column(){TopBar({title:this.title,onBack:()=>{this.pageContext.popPage(true)}})Stack(){Web({src:this.url,controller:this.controller}).layoutWeight(1).onPageEnd(()=>{this.isLoading=false})LoadingProgress().width(40).height(40).visibility(this.isLoading?Visibility.Visible:Visibility.None)}.layoutWeight(1)}}.onReady((ctx:NavDestinationContext)=>{constparams=ctx.pathInfo.paramasResultParams;this.url=params.urlasstringthis.title=params.titleasstring})}}关键点:
webview.WebviewController控制 Web 组件onPageEnd回调在页面加载完成后触发,关闭 loadingStack叠加 Web 和 LoadingProgress,实现加载指示器效果
八、emitter 事件驱动的跨页面通信
AI 咨询页面检测到未登录时,通过emitter通知主页切换到"我的"Tab:
// ConsultView 中发送事件if(!UserInfoManager.isLoggedIn()){ToastUtil.showToast('请先登录...')leteventData:emitter.EventData={data:{"content":"content"}};emitter.emit(CommonConstants.EVENT_ID,eventData);}// Index 中监听事件aboutToAppear():void{letcallback:Callback<emitter.EventData>=(eventData:emitter.EventData)=>{this.tabController.changeIndex(2)// 切换到"我的"Tab};emitter.on(CommonConstants.EVENT_ID,callback);}aboutToDisappear():void{emitter.off(CommonConstants.EVENT_ID);// 移除监听}emitter是 HarmonyOS 提供的进程内事件通知机制,适合跨组件/跨页面的松耦合通信。
九、小结
本篇讲解了个人中心的完整实现,包括华为一键登录集成、用户状态管理、功能入口布局和 Web 容器页面。通过backup_air三方库,MeCharts 轻松集成了华为云服务的登录与备份能力。下一篇将深入响应式布局与断点系统。