├── .gitignore ├── AppScope ├── app.json5 └── resources │ ├── base │ ├── element │ │ └── string.json │ └── media │ │ └── app_icon.png │ └── rawfile │ └── agconnect-services.json ├── README.md ├── base ├── README.md ├── fast_ui │ ├── .gitignore │ ├── BuildProfile.ets │ ├── Index.ets │ ├── build-profile.json5 │ ├── consumer-rules.txt │ ├── hvigorfile.ts │ ├── obfuscation-rules.txt │ ├── oh-package.json5 │ └── src │ │ └── main │ │ ├── ets │ │ ├── components │ │ │ ├── FastLoading.ets │ │ │ ├── FastToast.ets │ │ │ └── FoldStatusContainer.ets │ │ └── styles │ │ │ ├── CommonButtonStyle.ets │ │ │ └── CommonTextStyle.ets │ │ ├── module.json5 │ │ └── resources │ │ ├── base │ │ └── element │ │ │ ├── color.json │ │ │ ├── float.json │ │ │ └── string.json │ │ ├── en_US │ │ └── element │ │ │ └── string.json │ │ └── zh_CN │ │ └── element │ │ └── string.json ├── fast_util │ ├── .gitignore │ ├── BuildProfile.ets │ ├── Index.ets │ ├── build-profile.json5 │ ├── consumer-rules.txt │ ├── hvigorfile.ts │ ├── obfuscation-rules.txt │ ├── oh-package.json5 │ └── src │ │ └── main │ │ ├── ets │ │ ├── EventBus.ets │ │ ├── FastLog.ts │ │ ├── FastNavRouter.ets │ │ ├── FastPermisttion.ts │ │ ├── FastRouter.ets │ │ ├── FastTool.ets │ │ ├── ObjectUtil.ts │ │ ├── PreferencesUtil.ets │ │ └── ThrottleTool.ts │ │ ├── module.json5 │ │ └── resources │ │ ├── base │ │ └── element │ │ │ └── string.json │ │ ├── en_US │ │ └── element │ │ │ └── string.json │ │ └── zh_CN │ │ └── element │ │ └── string.json └── global_constant │ ├── .gitignore │ ├── BuildProfile.ets │ ├── Index.ets │ ├── build-profile.json5 │ ├── consumer-rules.txt │ ├── hvigorfile.ts │ ├── obfuscation-rules.txt │ ├── oh-package.json5 │ └── src │ └── main │ ├── ets │ └── PagePathConstants.ets │ ├── module.json5 │ └── resources │ ├── base │ └── element │ │ └── string.json │ ├── en_US │ └── element │ │ └── string.json │ └── zh_CN │ └── element │ └── string.json ├── build-profile.json5 ├── business ├── feature_home │ ├── .gitignore │ ├── BuildProfile.ets │ ├── Index.ets │ ├── build-profile.json5 │ ├── consumer-rules.txt │ ├── hvigorfile.ts │ ├── obfuscation-rules.txt │ ├── oh-package-lock.json5 │ ├── oh-package.json5 │ └── src │ │ └── main │ │ ├── ets │ │ ├── HomePage.ets │ │ ├── cloudDb │ │ │ └── LogReport.ets │ │ ├── config │ │ │ └── HomeCategoricalData.ets │ │ ├── dialog │ │ │ ├── CustomDialogContainer.ets │ │ │ └── MyCustomDialog.ets │ │ └── pages │ │ │ ├── AttributeModifierExample.ets │ │ │ ├── BuilderNodeExample.ets │ │ │ ├── CloudDatabaseExample.ets │ │ │ ├── CloudFuncExample.ets │ │ │ ├── ComponentFactoryExample.ets │ │ │ ├── CustomDialogExample.ets │ │ │ ├── EventBusExample.ets │ │ │ ├── FixFoldUiExample.ets │ │ │ ├── HttpRequestExample.ets │ │ │ ├── PermissionExample.ets │ │ │ ├── RouterCallbackExample.ets │ │ │ ├── TestNavPathJumpPage.ets │ │ │ └── ThrottleExample.ets │ │ ├── module.json5 │ │ └── resources │ │ ├── base │ │ └── element │ │ │ ├── color.json │ │ │ └── string.json │ │ ├── en_US │ │ └── element │ │ │ └── string.json │ │ └── zh_CN │ │ └── element │ │ └── string.json └── feature_setting │ ├── .gitignore │ ├── BuildProfile.ets │ ├── Index.ets │ ├── build-profile.json5 │ ├── consumer-rules.txt │ ├── hvigorfile.ts │ ├── obfuscation-rules.txt │ ├── oh-package-lock.json5 │ ├── oh-package.json5 │ └── src │ └── main │ ├── ets │ ├── pages │ │ ├── SettingPage.ets │ │ └── TestDynamicNavPage.ets │ ├── utils │ │ └── LoginUtils.ets │ └── widget │ │ ├── AccountQuickLoginButton.ets │ │ └── QuickVerifyPhoneButton.ets │ ├── module.json5 │ └── resources │ ├── base │ └── element │ │ └── string.json │ ├── en_US │ └── element │ │ └── string.json │ └── zh_CN │ └── element │ └── string.json ├── certificate └── debug │ ├── codeLab-Debug.cer │ ├── codeLab-DebugDebug.p7b │ ├── codeLab.csr │ ├── code_lab.p12 │ ├── material │ ├── ac │ │ └── 98d170fbd9c64931ae1251a4ef7ad9b9 │ ├── ce │ │ └── d02c2145e7a044529b5c2afc8c34e4b8 │ └── fd │ │ ├── 0 │ │ └── 0bf6a1d2cc754daab6e81da1adc21ac4 │ │ ├── 1 │ │ └── 011c3f245f584ee38b45718d70fc6d72 │ │ └── 2 │ │ └── 7cf2883100094a19a63fea5ec47172ff │ ├── rex_code_lab_debug.cer │ ├── rex_code_lab_debug.csr │ ├── rex_code_lab_debug.p12 │ └── rex_code_lab_debugDebug.p7b ├── entry ├── .gitignore ├── build-profile.json5 ├── hvigorfile.ts ├── obfuscation-rules.txt ├── oh-package-lock.json5 ├── oh-package.json5 └── src │ └── main │ ├── ets │ ├── entryability │ │ ├── EntryAbility.ets │ │ └── FoldStatusObserver.ets │ └── pages │ │ └── MainPage.ets │ ├── module.json5 │ └── resources │ ├── base │ ├── element │ │ ├── color.json │ │ └── string.json │ ├── media │ │ ├── ic_home_normal.png │ │ ├── ic_home_select.png │ │ ├── ic_mine_normal.png │ │ ├── ic_mine_select.png │ │ ├── labelIcon.png │ │ └── startIcon.png │ └── profile │ │ └── main_pages.json │ ├── rawfile │ └── schema.json │ └── zh_CN │ └── element │ └── string.json ├── features └── feature_hsp_page │ ├── .gitignore │ ├── Index.ets │ ├── build-profile.json5 │ ├── hvigorfile.ts │ ├── obfuscation-rules.txt │ ├── oh-package-lock.json5 │ ├── oh-package.json5 │ └── src │ └── main │ ├── ets │ └── pages │ │ ├── TestHspNavPathPage.ets │ │ └── TestHspRoutePage.ets │ ├── module.json5 │ └── resources │ └── base │ ├── element │ ├── color.json │ └── string.json │ └── profile │ ├── main_pages.json │ └── route_map.json ├── hvigor └── hvigor-config.json5 ├── hvigorfile.ts ├── oh-package-lock.json5 ├── oh-package.json5 └── screenshots ├── cloud_db_demo.png ├── cloud_func_demo.png └── sh_1.png /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /local.properties 4 | /.idea 5 | **/build 6 | /.hvigor 7 | .cxx 8 | /.clangd 9 | /.clang-format 10 | /.clang-tidy 11 | **/.test -------------------------------------------------------------------------------- /AppScope/app.json5: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "bundleName": "com.atomicservice.5765880207855149405", 4 | "bundleType": "atomicService", 5 | "vendor": "example", 6 | "versionCode": 1000000, 7 | "versionName": "1.0.0", 8 | "icon": "$media:app_icon", 9 | "label": "$string:app_name" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /AppScope/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "app_name", 5 | "value": "HarmonyAtomicService" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /AppScope/resources/base/media/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/AppScope/resources/base/media/app_icon.png -------------------------------------------------------------------------------- /AppScope/resources/rawfile/agconnect-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "agcgw":{ 3 | "backurl":"connect-drcn.hispace.hicloud.com", 4 | "url":"connect-drcn.dbankcloud.cn", 5 | "websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com", 6 | "websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn" 7 | }, 8 | "agcgw_all":{ 9 | "CN":"connect-drcn.dbankcloud.cn", 10 | "CN_back":"connect-drcn.hispace.hicloud.com", 11 | "DE":"connect-dre.dbankcloud.cn", 12 | "DE_back":"connect-dre.hispace.hicloud.com", 13 | "RU":"connect-drru.hispace.dbankcloud.ru", 14 | "RU_back":"connect-drru.hispace.dbankcloud.cn", 15 | "SG":"connect-dra.dbankcloud.cn", 16 | "SG_back":"connect-dra.hispace.hicloud.com" 17 | }, 18 | "websocketgw_all":{ 19 | "CN":"connect-ws-drcn.hispace.dbankcloud.cn", 20 | "CN_back":"connect-ws-drcn.hispace.dbankcloud.com", 21 | "DE":"connect-ws-dre.hispace.dbankcloud.cn", 22 | "DE_back":"connect-ws-dre.hispace.dbankcloud.com", 23 | "RU":"connect-ws-drru.hispace.dbankcloud.ru", 24 | "RU_back":"connect-ws-drru.hispace.dbankcloud.cn", 25 | "SG":"connect-ws-dra.hispace.dbankcloud.cn", 26 | "SG_back":"connect-ws-dra.hispace.dbankcloud.com" 27 | }, 28 | "client":{ 29 | "cp_id":"80086000309322325", 30 | "product_id":"388421841222390963", 31 | "client_id":"1487780195799663360", 32 | "client_secret":"[!00A7EA2F13A2C8A607EA96551329C20F0B5FAA4232FC6F4D2779547FEC3BAFE77A3FF364A036123A9CFE02662C6BB3DB6BC9566CF05BCACDE8E5440ECBD7660AD61F6D22B7D15778C690208B85A0723A6A020EB9A7CB89D670636D597E23230F97]", 33 | "project_id":"388421841222390963", 34 | "app_id":"111763805", 35 | "api_key":"[!00B0B168064C01754237F459E0319EEF4D7C9591A3D422A2A86A4534EC0F0CFEFD866E81E09037C510221011E69B682A15A4262CA1A399FFEC0BC515867599446088E0D3F250A7690CAF4A60EF3C8D87C8A3B8B0387FCC56B104252D485ADA1C8962C876693EA568DD77BF4AE7E87D711550629613092E92BAEE8EE663FB5D6E6C]", 36 | "package_name":"com.atomicservice.5765880207855149405" 37 | }, 38 | "oauth_client":{ 39 | "client_id":"111763805", 40 | "client_type":30 41 | }, 42 | "app_info":{ 43 | "app_id":"5765880207855149405", 44 | "package_name":"com.atomicservice.5765880207855149405" 45 | }, 46 | "code":{ 47 | "code1":"1D01A8E64ECEE62089AF7384AF84865D", 48 | "code2":"255224E32E231466019D3E61A510F41F", 49 | "code3":"27A0408730DF6FD4CDC58EACAC7DCF4D", 50 | "code4":"D891458E6E722B9130B7CD9420530701" 51 | }, 52 | "service":{ 53 | "analytics":{ 54 | "collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn", 55 | "collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com", 56 | "collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn", 57 | "collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn", 58 | "collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn", 59 | "resource_id":"p1", 60 | "channel_id":"" 61 | }, 62 | "edukit":{ 63 | "edu_url":"edukit.cloud.huawei.com.cn", 64 | "dh_url":"edukit.cloud.huawei.com.cn" 65 | }, 66 | "search":{ 67 | "url":"https://search-drcn.cloud.huawei.com" 68 | }, 69 | "cloudstorage":{ 70 | "storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia", 71 | "storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru", 72 | "storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru", 73 | "storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu", 74 | "storage_url_de":"https://ops-dre.agcstorage.link", 75 | "storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn", 76 | "storage_url_sg":"https://ops-dra.agcstorage.link", 77 | "storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn", 78 | "storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn" 79 | }, 80 | "ml":{ 81 | "mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn" 82 | } 83 | }, 84 | "region":"CN", 85 | "configuration_version":"3.0", 86 | "appInfos":[ 87 | { 88 | "package_name":"com.atomicservice.5765880207855149405", 89 | "client":{ 90 | "client_secret":"[!000F1F5B045C2BDCE2DA9EBBEA750C3826473994885B1FD08556AC2A11BC4791AB74D919D95E6AF94892A3B884460F354BB2E715D75F790824FD56FE9D6986DF1A9232C6CC2642A122371A8F31B523BAEAD5FF74761EA95FE6FE39CEBBEF561DC9]", 91 | "app_id":"5765880207855149405", 92 | "api_key":"[!0085E354C30D98A3788625B774D27296FB548D2F7F2B697FB2C003EEDACE530E859C55E44522BDFD9558407CF32459C8F62954EFF5FB0AFAF85DF6247E555591B1D328706C284ED8DE413B5681A540FCBB292DA1AE42437B3F8C06075FA7FA9E32CE3634A0596F1771CDD5075202B97A2A957229C89C31ECFD5B47F10411746902]" 93 | }, 94 | "code":{ 95 | "code1":"AFF26D1BC98CC684D7E0BB8A0DF91E5D0D40582C4F02A7B3AB3378F0C2C39A61", 96 | "code2":"C544698B71827FAE2513B7C95E9480BEA0748BCEDDC5BFF9E1D4017F318943AE", 97 | "code3":"3A2FDB99DAD35B6F7DC02AB9DA155AE4F00BCC48FF29BC475B489896D2FAF398", 98 | "code4":"5C777F269B2AACC7C3B48F91FDCEEE36" 99 | } 100 | } 101 | ] 102 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## HarmonyOS NEXT 元服务设计示例 2 | 3 | 基于 API11,开发的程序示例,适用于 NEXT 及以上版本运行。 4 | 5 | 项目包含如下: 6 | 7 | + 静态库+动态包+多模块设计 8 | + 状态管理 9 | + 统一路由管理(router+navPathStack) 10 | + 网络请求、Loading、Toast、数据持久化 等工具库封装 11 | + 自定义组件、自定义弹窗(解耦) 12 | + EventBus 事件通知 13 | + 扩展修饰器,实现 节流、防抖、权限申请 14 | + 动态路由 (navPathStack + 动态import + WrappedBuilder) 15 | + UI动态节点操作 (BuilderNode + NodeController) 16 | + 折叠屏适配示例 17 | + 组件工厂示例 18 | + 组件动态属性设置示例 19 | + 云函数、云数据库使用示例 20 | + 华为账号服务示例(快速登陆、快速验证手机号) 21 | 22 | 项目结构描述 23 | 24 | #### 基础库 25 | 26 | | 模块名称 | 描述 | 备注 | 27 | |---------------------|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 28 | | **fast_util** | 工具类 | FastLog(日志打印)
EventBus(消息通知)
FastRouter(基于Route封装的路由管理)
FastNavRouter(动态路由)
ThrottleTool (节流、防抖)
FastPermission (修饰器实现权限申请)
PreferencesUtil (数据持久化封装) | 29 | | **fast_ui** | 提供 UI 封装、样式、toast 等 | CommonText(统一文本)
CommonButton(统一按键)
FastToast
FastLoading | 30 | | **global_constant** | 记录全局常量配置 | PagePathConstants (路由路径管理) | 31 | 32 | #### 业务库 33 | | 模块名称 | 描述 | 备注 | 34 | |----------------------|------------|--| 35 | | **feature_home** | 主要存放代码示例 | 静态包(har) | 36 | | **feature_setting** | 存放华为账号服务示例 | 静态包(har) | 37 | | **feature_hsp_page** | 存放动态包交互示例 | 动态包(hsp/share) | 38 | 39 | #### 工程目录 40 | ```ts 41 | ├──entry // ets代码区 42 | │ └──src/main/ets 43 | │ ├──entryability 44 | │ │ ├──FoldStatusObserver.ets // 折叠屏幕变化监听 45 | │ │ └──EntryAbility.ets 46 | │ ├──pages 47 | │ │ └──MainPage.ets // 首页 48 | ├──business // 放置静态包的文件夹(业务模块) 49 | │ ├──feature_home // 放置首页Tab里的一些示例页面 50 | │ │ └──/src/main/ets/pages 51 | │ │ ├──HomePage.ets //首页的第一个Tab 52 | │ │ ├──BuilderNodeExample.ets //动态节点操作示例 53 | │ │ ├──CustomDialogExample.ets //自定义弹窗解耦 54 | │ │ ├──EventBusExample.ets //消息通知 55 | │ │ ├──HttpRequestExample.ets //网络请求示例 56 | │ │ ├──PermissionExample.ets //使用注解请求权限 57 | │ │ ├──RouterCallbackExample.ets //使用 NavPathStack 与 Route 两种方式实现页面跳转及回调(HSP、HAR) 58 | │ │ ├──FixFoldUiExample.ets //折叠屏适配示例 59 | │ │ ├──ComponentFactoryExample.ets //组件工厂示例 60 | │ │ ├──AttributeModifierExample.ets //组件动态属性设置示例 61 | │ │ ├──CloudFuncExample.ets //云函数调用示例 62 | │ │ ├──CloudDatabaseExample.ets //云数据库使用示例(增删改查) 63 | │ │ └──ThrottleExample.ets //使用注解防抖 64 | │ ├──feature_setting 65 | │ │ └──/src/main/ets 66 | │ │ ├──pages 67 | │ │ │ ├──SettingPages.ets //首页的第二个Tab(包含了华为账号服务示例) 68 | │ │ │ └──TestDynamicNavPage.ets //测试动态路由示例 69 | │ │ ├──widget 70 | │ │ │ ├──AccountQuickLoginButton.ets //华为账号快速登陆按钮 71 | │ │ │ └──QuickVerifyPhoneButton.ets //快速验证手机号按钮 72 | │ │ └──utils 73 | │ │ └──LoginUtils.ets //Account-Kit 获取 UnionID 能力封装 74 | ├──features //放置动态包的文件夹 75 | │ ├──feature_has_page 76 | │ │ └──/src/main/ets/pages 77 | │ │ ├──TestHspNavPathPage.ets //测试 NavPath 跳转 HSP 内页面 78 | │ │ └──TestHspRouterPage.ets //测试 Route 跳转 HSP 内页面 79 | ├──base 80 | │ ├──fast_ui //封装公共UI 81 | │ │ ├──/src/main/ets/compnents 82 | │ │ │ ├──FoldStatusContainer.ets // 折叠屏变化响应组件封装 83 | │ │ │ ├──FastLoading.ets // loading工具 84 | │ │ │ └──FastToast.ets // toast工具 85 | │ │ └──/src/main/ets/styles // 公共样式 86 | │ ├──fast_util // 通用工具 87 | │ │ ├──/src/main/ets 88 | │ │ ├──EventBus.ets // 消息通知+监听 89 | │ │ ├──FastLog.ets // 日志打印 90 | │ │ ├──FastNavRouter.ets // 用于动态路由 91 | │ │ ├──FastPermission.ets // 请求权限注解器 92 | │ │ ├──FastRouter.ets // 基于 router 库封装,为了实现页面回调 93 | │ │ ├──FastTool.ets 94 | │ │ ├──PreferencesUtil.ets // 数据持久化工具 95 | │ │ └──ThrottleTool.ets // 防抖注解器 96 | │ ├──global_constant 97 | │ │ 98 | ├──entry/src/main/resources // 应用资源目录 99 | └──module.json5 // 添加卡片拓展能力 100 | ``` 101 | 102 | ![](screenshots/sh_1.png) 103 | 104 | 105 | #### 让开发更简单,部分技巧总结 106 | 107 | + [网络库使用](https://juejin.cn/post/7347851786164437002) 108 | ```ts 109 | class GetRequest extends HttpRequest> { 110 | ...省略入参 111 | } 112 | 113 | // 发送请求 114 | let request = new GetRequest() 115 | request.excute().then((data)=>{ 116 | // 这里获取的 data 类型为 CommonResponseModel 117 | }) 118 | ``` 119 | #### [路由如何选择和使用](https://juejin.cn/post/7369120920148213795) 120 | #### [自定义弹窗解耦](https://juejin.cn/post/7352100456334721034) 121 | #### [面相对象的 EventBus 封装](https://juejin.cn/post/7352075796712964122) 122 | #### [实现NFC碰一碰快捷唤起](https://juejin.cn/post/7469591708692332570) 123 | #### [扩展修饰器,实现节流、防抖、权限申请](https://juejin.cn/post/7373194499530244136) 124 | ```ts 125 | // 修饰器实现节流,示例如下,2秒内多次点击只会触发第一次 126 | 127 | @Throttle(2000) 128 | onClickTap(name: string) { 129 | // consolve.log(name) 130 | this.count++ 131 | } 132 | ``` 133 | ```ts 134 | // 修饰器实现权限申请,示例如下 135 | 136 | @Permission( 137 | getContext(this) as common.UIAbilityContext, 138 | ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'] 139 | ) 140 | onClickTap(name: string) { 141 | // 授权成功后,才会进入方法内执行 count++ 142 | this.count++ 143 | } 144 | ``` 145 | #### [动态路由]() 146 | ```ts 147 | // 示例请看 FastNavRouter,下面为关键代码 148 | 149 | // 路由管理 150 | static builderMap: Map> = new Map>(); 151 | 152 | // 注册页面组件到路由表,builderName是路由名字,builder参数是包裹了页面组件的WrappedBuilder对象 153 | public static registerBuilder( 154 | builderName: string, 155 | builder: WrappedBuilder<[object]> 156 | ): void { 157 | builderMap.set(builderName, builder); 158 | } 159 | 160 | // 动态路由对应的页面 161 | @Builder 162 | export function TestDynamicNavPageBuilder(params: object) {} 163 | 164 | // 在页面首次加载时触发执行 165 | const builderName: string = '@ohos/feature_setting*./src/main/ets/TestDynamicNavPage'; 166 | 167 | // 判断表中是否已存在路由信息,避免重复注册 168 | if (!FastNavRouter.getBuilder(builderName)) { 169 | // 通过系统提供的wrapBuilder接口封装@Builder装饰的方法 170 | let builder: WrappedBuilder<[object]> = wrapBuilder(TestDynamicNavPageBuilder); 171 | // 注册页面到全局路由表 172 | FastNavRouter.registerBuilder(builderName, builder); 173 | } 174 | 175 | // 跟页面路由管理中转 176 | @Builder 177 | PageMap(name: string, params?: RouterModel) { 178 | if (FastNavRouter.getBuilder(name) !== undefined) { 179 | // 测试动态路由 (TestDynamicNavPage) 180 | FastNavRouter.getBuilder(name).builder(params) 181 | } 182 | } 183 | ``` 184 | #### [适配折叠屏](https://juejin.cn/post/7392252402496389172) 185 | #### [UI动态节点操作(NodeController)](https://juejin.cn/post/7379423024556064803) 186 | #### [组件工厂 + 动态组件(AttributeModifier)](https://juejin.cn/post/7399478677396881443) 187 | ```ts 188 | // 声明 189 | @Builder 190 | function UI1(text: string) { 191 | Text(text).fontColor(Color.Green) 192 | } 193 | 194 | @Builder 195 | function UI2(text: string) { 196 | Text(text).fontColor(Color.Blue) 197 | } 198 | 199 | let factoryMap: Map = new Map(); 200 | 201 | factoryMap.set('UI1', wrapBuilder(UI1)) 202 | factoryMap.set('UI2', wrapBuilder(UI2)) 203 | 204 | // 使用 205 | (factoryMap.get('UI1') as WrappedBuilder<[string]>).builder('工厂组件 - 1'); 206 | ``` 207 | #### 云函数 208 | 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/cloudfoundation-call-function-V5 209 | 云函数对应配置文件: AppScope/resources/rawfile/agconnect-services.json(在AGC对应项目中导出) 210 | ```ts 211 | // 云函数依赖 212 | "@hw-agconnect/api-ohos": "^1.1.2", 213 | "@hw-agconnect/core-ohos": "^1.1.2", 214 | "@hw-agconnect/function-ohos": "^1.1.2", 215 | "@hw-agconnect/credential-ohos": "^1.1.2", 216 | "@hw-agconnect/base-ohos": "^1.1.2" 217 | 218 | 关键代码: 219 | cloudFunction.call({ 220 | name: "cloundfunction", //对应创建的云函数名称 221 | version: "$latest", //如果不传入版本号,默认为“$latest”。 222 | timeout: 10 * 1000, //单位为毫秒,默认为70*1000毫秒。 223 | data: { 224 | year: this.year, 225 | } 226 | }).then((value: cloudFunction.FunctionResult) => { 227 | // 返回结果 228 | }).catch((err: BusinessError) => { 229 | }) 230 | ``` 231 | ![](screenshots/cloud_func_demo.png) 232 | #### 云数据库 233 | 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/cloudfoundation-database-initialize-V5 234 | 云数据库对应配置文件: entry/src/main/resources/rawfile/schema.json(AGC中选中云数据库,导出的对象类型模版) 235 | ```ts 236 | 关键代码: 237 | // CodeLabDemo 是AGC开发平台上创建的存储区名称 238 | 239 | let databaseZone = cloudDatabase.zone("CodeLabDemo"); 240 | let log = new LogReport(); 241 | log.id = new Date().getMilliseconds() 242 | log.content = this.logContent; 243 | log.time = this.getCurrentTime(); 244 | await databaseZone.upsert(log); 245 | FastToast.shortToast(`写入成功`); 246 | ``` 247 | 示例中数据库对象名称为`LogReport`,包含字段如下: 248 | 249 | | 字段 | 类型 | 备注 | 250 | |---------|--------|-------| 251 | | id | int | 主键 | 252 | | content | string | 上传的内容 | 253 | | time | string | 修改的时间 | 254 | 255 | ![](screenshots/cloud_db_demo.png) 256 | #### 华为账号服务(华为账号快速登陆) 257 | 258 | 文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/account-quick-login-V5 259 | + 开发准备 260 | 1. [配置client ID](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/account-client-id-V5) 261 | 2. [配置权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/account-config-permissions-V5),需要配置敏感权限 262 | 263 | 264 | #### 持续更新中...... 265 | -------------------------------------------------------------------------------- /base/README.md: -------------------------------------------------------------------------------- 1 | ### 基础库 2 | 3 | | 模块名称 | 描述 | 备注 | 4 | |---------------------|---------------------|--------------------------------------------------------------------------| 5 | | **fast_util** | 工具类 | FastLog(日志打印)
EventBus(消息通知) | 6 | | **fast_ui** | 提供 UI 封装、样式、toast 等 | CommonText(统一文本)
CommonButton(统一按键)
FastToast
FastLoading | 7 | | **global_constant** | 记录全局常量配置 | PagePathConstants(路由路径管理) | -------------------------------------------------------------------------------- /base/fast_ui/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /base/fast_ui/BuildProfile.ets: -------------------------------------------------------------------------------- 1 | /** 2 | * Use these variables when you tailor your ArkTS code. They must be of the const type. 3 | */ 4 | export const HAR_VERSION = '1.0.0'; 5 | export const BUILD_MODE_NAME = 'debug'; 6 | export const DEBUG = true; 7 | export const TARGET_NAME = 'default'; 8 | 9 | /** 10 | * BuildProfile Class is used only for compatibility purposes. 11 | */ 12 | export default class BuildProfile { 13 | static readonly HAR_VERSION = HAR_VERSION; 14 | static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; 15 | static readonly DEBUG = DEBUG; 16 | static readonly TARGET_NAME = TARGET_NAME; 17 | } -------------------------------------------------------------------------------- /base/fast_ui/Index.ets: -------------------------------------------------------------------------------- 1 | export { CommonMainTitle, CommonSubTitle } from './src/main/ets/styles/CommonTextStyle' 2 | 3 | export { CommonFillButton, CommonLineButton } from './src/main/ets/styles/CommonButtonStyle' 4 | 5 | export { FastLoading, FastLoadingDialog } from './src/main/ets/components/FastLoading' 6 | 7 | export { FastToast } from './src/main/ets/components/FastToast' 8 | 9 | export { FoldStatusContainer } from './src/main/ets/components/FoldStatusContainer' -------------------------------------------------------------------------------- /base/fast_ui/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | }, 5 | "buildOptionSet": [ 6 | { 7 | "name": "release", 8 | "arkOptions": { 9 | "obfuscation": { 10 | "ruleOptions": { 11 | "enable": true, 12 | "files": [ 13 | "./obfuscation-rules.txt" 14 | ] 15 | }, 16 | "consumerFiles": [ 17 | "./consumer-rules.txt" 18 | ] 19 | } 20 | }, 21 | }, 22 | ], 23 | "targets": [ 24 | { 25 | "name": "default" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /base/fast_ui/consumer-rules.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/base/fast_ui/consumer-rules.txt -------------------------------------------------------------------------------- /base/fast_ui/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { harTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /base/fast_ui/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /base/fast_ui/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fast_ui", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "Index.ets", 6 | "author": "", 7 | "license": "Apache-2.0", 8 | "dependencies": {} 9 | } 10 | -------------------------------------------------------------------------------- /base/fast_ui/src/main/ets/components/FastLoading.ets: -------------------------------------------------------------------------------- 1 | @Extend(Column) 2 | function cardStyle() { 3 | .backgroundColor(0xB3000000) 4 | .alignItems(HorizontalAlign.Center) 5 | .justifyContent(FlexAlign.Center) 6 | .padding(10) 7 | .borderRadius(14) 8 | .shadow({ 9 | radius: 14, 10 | type: ShadowType.BLUR, 11 | }) 12 | } 13 | 14 | @Extend(Text) 15 | function messageStyle( 16 | fontSize: number | Resource | string, 17 | fontWeight: number | FontWeight | string 18 | ) { 19 | .fontSize(fontSize) 20 | .fontWeight(fontWeight) 21 | } 22 | 23 | @Component 24 | export struct FastLoading { 25 | loadingSize: Length = '40vp' 26 | messageFontSize: number | Resource | string = '16fp' 27 | messageFontWeight: number | FontWeight | string = FontWeight.Medium 28 | message: string | Resource | null = $r('app.string.loading') 29 | 30 | build() { 31 | Row({ space: 3 }) { 32 | Text(this.message) 33 | .messageStyle( 34 | this.messageFontSize, 35 | this.messageFontWeight 36 | ) 37 | .visibility(this.message != null ? Visibility.Visible : Visibility.None) 38 | LoadingProgress() 39 | .width(this.loadingSize) 40 | .height(this.loadingSize) 41 | .color($r('app.color.secondary')) 42 | } 43 | .padding('10vp') 44 | .justifyContent(FlexAlign.Center) 45 | } 46 | } 47 | 48 | @CustomDialog 49 | export struct FastLoadingDialog { 50 | private controller: CustomDialogController; 51 | 52 | build() { 53 | Column() { 54 | FastLoading() 55 | }.cardStyle() 56 | } 57 | } 58 | 59 | // dialog 的形式样式loading 60 | // let LoadingDialog = new CustomDialogController( 61 | // { 62 | // builder: FastLoadingDialog(), 63 | // alignment: DialogAlignment.Center, 64 | // customStyle: true, 65 | // maskColor: Color.Transparent, 66 | // } 67 | // ) 68 | // loadingDialog.open() -------------------------------------------------------------------------------- /base/fast_ui/src/main/ets/components/FastToast.ets: -------------------------------------------------------------------------------- 1 | import { promptAction } from '@kit.ArkUI'; 2 | 3 | export class FastToast { 4 | static showToast(message: ResourceStr | string, duration: number) { 5 | promptAction.showToast({ message: message, duration: duration }); 6 | } 7 | 8 | static shortToast(message: ResourceStr | string) { 9 | FastToast.showToast(message, 1000); 10 | } 11 | 12 | static longToast(message: ResourceStr | string) { 13 | FastToast.showToast(message, 3000); 14 | } 15 | } -------------------------------------------------------------------------------- /base/fast_ui/src/main/ets/components/FoldStatusContainer.ets: -------------------------------------------------------------------------------- 1 | /// 响应折叠屏变化的父容器 2 | 3 | @Component 4 | export struct FoldStatusContainer { 5 | @StorageProp('foldStatusKey') isFold: boolean = false 6 | // 非折叠状态 UI 布局 7 | @BuilderParam unFoldBodyContainer: () => void = this.defaultContainer 8 | // 折叠状态 UI 布局 9 | @BuilderParam foldBodyContainer: () => void = this.defaultContainer 10 | 11 | @Builder 12 | defaultContainer() { 13 | Column() 14 | } 15 | 16 | build() { 17 | Stack() { 18 | if (this.isFold) { 19 | this.foldBodyContainer() 20 | } else { 21 | this.unFoldBodyContainer() 22 | } 23 | } 24 | .width('100%') 25 | .height('100%') 26 | } 27 | } -------------------------------------------------------------------------------- /base/fast_ui/src/main/ets/styles/CommonButtonStyle.ets: -------------------------------------------------------------------------------- 1 | /// 统一的按钮样式 2 | interface CommonButtonOption { 3 | backGroundColor?: Resource; 4 | borderColor?: Resource; 5 | fontColor?: Resource; 6 | fontSize?: number | Resource; 7 | fontWeight?: number | FontWeight; 8 | horizontalPadding?: number | Resource | string; 9 | verticalPadding?: number | Resource | string; 10 | marginLeft?: number | Resource | string; 11 | marginTop?: number | Resource | string; 12 | marginRight?: number | Resource | string; 13 | marginBottom?: number | Resource | string; 14 | borderRadius?: number | Resource | string; 15 | text: string | Resource; 16 | event: () => void; 17 | } 18 | 19 | // 颜色填充的样式按钮 20 | @Builder 21 | function CommonFillButton( 22 | option: CommonButtonOption 23 | ) { 24 | Text(option.text) 25 | .fontSize(option.fontSize ?? $r('app.float.font_default')) 26 | .fontWeight(option.fontWeight ?? FontWeight.Normal) 27 | .fontColor(option.fontColor ?? $r('app.color.primary')) 28 | .backgroundColor(option.backGroundColor ?? $r('app.color.secondary')) 29 | .padding({ 30 | left: option.horizontalPadding ?? '11vp', 31 | top: option.verticalPadding ?? '6vp', 32 | right: option.horizontalPadding ?? '11vp', 33 | bottom: option.verticalPadding ?? '6vp', 34 | }) 35 | .margin( 36 | { 37 | left: option.marginLeft, 38 | top: option.marginTop, 39 | right: option.marginRight, 40 | bottom: option.marginBottom, 41 | } 42 | ) 43 | .borderRadius(option.borderRadius ?? '5vp') 44 | .onClick(option.event) 45 | } 46 | 47 | // 边框线样式的按钮 48 | @Builder 49 | function CommonLineButton( 50 | option: CommonButtonOption 51 | ) { 52 | Text(option.text) 53 | .fontColor(option.fontColor ?? $r('app.color.text_button_2')) 54 | .fontWeight(option.fontWeight ?? FontWeight.Normal) 55 | .fontSize(option.fontSize ?? $r('app.float.font_default')) 56 | .backgroundColor(option.backGroundColor ?? $r('app.color.primary')) 57 | .borderColor(option.borderColor ?? $r('app.color.border_color')) 58 | .borderWidth(1) 59 | .padding({ 60 | left: option.horizontalPadding ?? '11vp', 61 | top: option.verticalPadding ?? '6vp', 62 | right: option.horizontalPadding ?? '11vp', 63 | bottom: option.verticalPadding ?? '6vp', 64 | }) 65 | .borderRadius(option.borderRadius ?? '5vp') 66 | .onClick(option.event) 67 | } 68 | 69 | @Builder 70 | function FillFlexButton( 71 | option: CommonButtonOption 72 | ) { 73 | Text(option.text) 74 | .textAlign(TextAlign.Center) 75 | .fontSize(option.fontSize ?? $r('app.float.font_default')) 76 | .fontWeight(option.fontWeight ?? FontWeight.Normal) 77 | .fontColor(option.fontColor ?? $r('app.color.primary')) 78 | .backgroundColor(option.backGroundColor ?? $r('app.color.secondary')) 79 | .padding({ 80 | top: option.verticalPadding ?? '6vp', 81 | bottom: option.verticalPadding ?? '6vp', 82 | }) 83 | .margin( 84 | { 85 | left: option.marginLeft, 86 | top: option.marginTop, 87 | right: option.marginRight, 88 | bottom: option.marginBottom, 89 | } 90 | ) 91 | .borderRadius(option.borderRadius ?? '24vp') 92 | .width('100%') 93 | .layoutWeight(1) 94 | .onClick(option.event) 95 | } 96 | 97 | export { CommonFillButton, CommonLineButton, FillFlexButton } 98 | 99 | 100 | /// 使用方式预览 101 | @Entry 102 | @Component 103 | struct PreviewTest { 104 | build() { 105 | Column({ space: 20 }) { 106 | CommonFillButton({ 107 | text: "abc", 108 | event: () => { 109 | 110 | } 111 | }) 112 | CommonLineButton({ 113 | text: "abc", 114 | event: () => { 115 | 116 | } 117 | }) 118 | } 119 | .width('100%') 120 | .height('100%') 121 | .alignItems(HorizontalAlign.Center) 122 | .justifyContent(FlexAlign.Center) 123 | } 124 | } 125 | 126 | -------------------------------------------------------------------------------- /base/fast_ui/src/main/ets/styles/CommonTextStyle.ets: -------------------------------------------------------------------------------- 1 | /// 统一样式的 Text 2 | 3 | interface CommonTextOption { 4 | fontColor?: string | Resource; 5 | fontSize?: number | Resource | string; 6 | fontWeight?: number | FontWeight; 7 | lineHeight?: number | string | Resource; 8 | textAlign?: TextAlign 9 | overflow?: TextOverflow 10 | maxLines?: number 11 | text: string | Resource; 12 | } 13 | 14 | @Builder 15 | function CommonMainTitle( 16 | option: CommonTextOption 17 | ) { 18 | Text(option.text) 19 | .fontSize(option.fontSize ?? $r('app.float.font_title')) 20 | .fontColor(option.fontColor ?? $r('app.color.text_main')) 21 | .fontWeight(option.fontWeight ?? FontWeight.Medium) 22 | .lineHeight(option.lineHeight) 23 | .textAlign(option.textAlign) 24 | .maxLines(option.maxLines) 25 | .textOverflow({ overflow: option.overflow ?? TextOverflow.None }) 26 | } 27 | 28 | @Builder 29 | function CommonSubTitle( 30 | option: CommonTextOption 31 | ) { 32 | Text(option.text) 33 | .fontSize(option.fontSize ?? $r('app.float.font_sub_title')) 34 | .fontColor(option.fontColor ?? $r('app.color.text_sub')) 35 | .fontWeight(option.fontWeight ?? FontWeight.Normal) 36 | .lineHeight(option.lineHeight) 37 | .textAlign(option.textAlign) 38 | .maxLines(option.maxLines) 39 | .textOverflow({ overflow: option.overflow ?? TextOverflow.None }) 40 | } 41 | 42 | export { CommonMainTitle, CommonSubTitle } 43 | 44 | /// 使用方式预览 45 | @Entry 46 | @Component 47 | struct PreviewTest { 48 | build() { 49 | Column({ space: 20 }) { 50 | CommonMainTitle({ 51 | text: 'MainTitle', 52 | }) 53 | CommonSubTitle({ 54 | text: 'SubTitle' 55 | }) 56 | } 57 | .width('100%') 58 | .height('100%') 59 | .alignItems(HorizontalAlign.Center) 60 | .justifyContent(FlexAlign.Center) 61 | } 62 | } -------------------------------------------------------------------------------- /base/fast_ui/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "fast_ui", 4 | "type": "har", 5 | "deviceTypes": [ 6 | "default", 7 | "tablet" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /base/fast_ui/src/main/resources/base/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "primary", 5 | "value": "#F3F4F5" 6 | }, 7 | { 8 | "name": "secondary", 9 | "value": "#698D04" 10 | }, 11 | { 12 | "name": "disabled", 13 | "value": "#C4C4C4" 14 | }, 15 | { 16 | "name": "text_main", 17 | "value": "#242524" 18 | }, 19 | { 20 | "name": "text_sub", 21 | "value": "#6F7275" 22 | }, 23 | { 24 | "name": "text_button_2", 25 | "value": "#FFA0A4A7" 26 | }, 27 | { 28 | "name": "text_desc", 29 | "value": "#86888B" 30 | }, 31 | { 32 | "name": "divider", 33 | "value": "#FFE2E5E7" 34 | }, 35 | { 36 | "name": "border_color", 37 | "value": "#FFA0A4A7" 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /base/fast_ui/src/main/resources/base/element/float.json: -------------------------------------------------------------------------------- 1 | { 2 | "float": [ 3 | { 4 | "name": "font_nav_title", 5 | "value": "17fp" 6 | }, 7 | { 8 | "name": "font_title", 9 | "value": "15fp" 10 | }, 11 | { 12 | "name": "font_sub_title", 13 | "value": "11fp" 14 | }, 15 | { 16 | "name": "font_default", 17 | "value": "14fp" 18 | }, 19 | { 20 | "name": "font_small", 21 | "value": "12fp" 22 | }, 23 | { 24 | "name": "font_smaller", 25 | "value": "10fp" 26 | }, 27 | { 28 | "name": "button_default_height", 29 | "value": "40vp" 30 | }, 31 | { 32 | "name": "button_default_radius", 33 | "value": "20vp" 34 | }, 35 | { 36 | "name": "padding_default", 37 | "value": "15vp" 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /base/fast_ui/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "基础UI库" 6 | }, 7 | { 8 | "name": "loading", 9 | "value": "加载中..." 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /base/fast_ui/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /base/fast_ui/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /base/fast_util/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /base/fast_util/BuildProfile.ets: -------------------------------------------------------------------------------- 1 | /** 2 | * Use these variables when you tailor your ArkTS code. They must be of the const type. 3 | */ 4 | export const HAR_VERSION = '1.0.0'; 5 | export const BUILD_MODE_NAME = 'debug'; 6 | export const DEBUG = true; 7 | export const TARGET_NAME = 'default'; 8 | 9 | /** 10 | * BuildProfile Class is used only for compatibility purposes. 11 | */ 12 | export default class BuildProfile { 13 | static readonly HAR_VERSION = HAR_VERSION; 14 | static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; 15 | static readonly DEBUG = DEBUG; 16 | static readonly TARGET_NAME = TARGET_NAME; 17 | } -------------------------------------------------------------------------------- /base/fast_util/Index.ets: -------------------------------------------------------------------------------- 1 | export { EventBus } from './src/main/ets/EventBus' 2 | 3 | export { FastLog } from './src/main/ets/FastLog' 4 | 5 | export { FastRouter, RouterModel } from './src/main/ets/FastRouter' 6 | 7 | export { Throttle, Debounce } from './src/main/ets/ThrottleTool' 8 | 9 | export { Permission } from './src/main/ets/FastPermisttion' 10 | 11 | export { FastNavRouter, FastNavRouterModel } from './src/main/ets/FastNavRouter' 12 | 13 | export { PreferencesUtil } from './src/main/ets/PreferencesUtil' 14 | 15 | export { ObjectUtil } from './src/main/ets/ObjectUtil' -------------------------------------------------------------------------------- /base/fast_util/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | }, 5 | "buildOptionSet": [ 6 | { 7 | "name": "release", 8 | "arkOptions": { 9 | "obfuscation": { 10 | "ruleOptions": { 11 | "enable": true, 12 | "files": [ 13 | "./obfuscation-rules.txt" 14 | ] 15 | }, 16 | "consumerFiles": [ 17 | "./consumer-rules.txt" 18 | ] 19 | } 20 | }, 21 | }, 22 | ], 23 | "targets": [ 24 | { 25 | "name": "default" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /base/fast_util/consumer-rules.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/base/fast_util/consumer-rules.txt -------------------------------------------------------------------------------- /base/fast_util/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { harTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /base/fast_util/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /base/fast_util/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fast_util", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "Index.ets", 6 | "author": "", 7 | "license": "Apache-2.0", 8 | "dependencies": {} 9 | } 10 | -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/EventBus.ets: -------------------------------------------------------------------------------- 1 | import { emitter } from '@kit.BasicServicesKit'; 2 | 3 | /// 事件通知工具类 4 | export abstract class EventBus { 5 | static send( 6 | eventID: string, 7 | eventData?: Object | Record | null, 8 | ) { 9 | let data: string | undefined 10 | if (eventData !== null && eventData !== undefined) { 11 | if (typeof eventData === 'string') { 12 | data = eventData 13 | } else { 14 | data = JSON.stringify(eventData) 15 | } 16 | } 17 | 18 | emitter.emit( 19 | eventID, 20 | { 21 | priority: emitter.EventPriority.HIGH 22 | }, 23 | { 24 | data: { 25 | 'data': data 26 | } 27 | }, 28 | ); 29 | } 30 | 31 | static listen( 32 | eventID: string, 33 | callback: (data?: T) => void, 34 | ) { 35 | emitter.on( 36 | eventID, 37 | (eventData: emitter.EventData) => { 38 | let data: string | undefined = eventData.data!['data'] 39 | if (data == undefined) { 40 | callback(undefined) 41 | } else { 42 | if (data.startsWith("{") && data.endsWith("}")) { 43 | callback(JSON.parse(data) as T) 44 | } else { 45 | callback(data as T) 46 | } 47 | } 48 | }, 49 | ); 50 | } 51 | 52 | static cancel(eventID: string) { 53 | emitter.off(eventID); 54 | } 55 | } -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/FastLog.ts: -------------------------------------------------------------------------------- 1 | class FastLogOptions { 2 | tag?: string 3 | domain?: number 4 | close?: boolean 5 | isHilog?: boolean 6 | showLogLocation?: boolean 7 | logSize?: number 8 | } 9 | 10 | import hilog from '@ohos.hilog' 11 | 12 | 13 | class FastLog { 14 | private static mTag: string = "FastLog" 15 | private static mDomain: number = 0x0000 16 | private static mClose: boolean = false 17 | private static mHilog: boolean = true //默认是用hilog进行打印 18 | private static mShowLogLocation: boolean = true //展示点击的位置 19 | private static mLogSize = 800 //打印的最大长度,默认是800 20 | 21 | /* 22 | * 日志输出级别 23 | * */ 24 | static setDomain(domain: number) { 25 | FastLog.mDomain = domain 26 | } 27 | 28 | /* 29 | * 初始化tag、domain等属性 30 | * */ 31 | static init(object: FastLogOptions) { 32 | const tag: string = object.tag //日志输出Tag 33 | const domain: number = object.domain //日志输出级别 34 | const close: boolean = object.close //是否关闭日志 35 | const isHilog: boolean = object.isHilog //是否是hilog打印 36 | const showLogLocation: boolean = object.showLogLocation //是否展示日志位置 37 | const logSize: number = object.logSize //日志输出大小 38 | if (tag != undefined) { 39 | this.mTag = tag 40 | } 41 | if (domain != undefined) { 42 | this.mDomain = domain 43 | } 44 | if (close != undefined) { 45 | this.mClose = close 46 | } 47 | if (isHilog != undefined) { 48 | this.mHilog = isHilog 49 | } 50 | if (showLogLocation != undefined) { 51 | this.mShowLogLocation = showLogLocation 52 | } 53 | if (logSize != undefined) { 54 | this.mLogSize = logSize 55 | } 56 | 57 | } 58 | 59 | //需要先调用isLoggable确认某个domain、tag和日志级别是否被禁止打印日志 60 | static isLoggable(level: hilog.LogLevel): boolean { 61 | return hilog.isLoggable(this.mDomain, this.mTag, level) 62 | } 63 | 64 | /* 65 | * console形式打印log日志,只支持console 66 | * */ 67 | static log(message: any, tag?: string) { 68 | console.log(this.getMessage(hilog.LogLevel.INFO, tag == undefined ? this.mTag : tag, message)) 69 | } 70 | 71 | /* 72 | * info日志 73 | * */ 74 | static info(message: any, tag?: string) { 75 | this.logLevel(hilog.LogLevel.INFO, tag, message) 76 | } 77 | 78 | /* 79 | * debug日志 80 | * */ 81 | static debug(message: any, tag?: string) { 82 | this.logLevel(hilog.LogLevel.DEBUG, tag, message) 83 | } 84 | 85 | 86 | /* 87 | * error日志,不带标签 88 | * */ 89 | static error(message: any, tag?: string) { 90 | this.logLevel(hilog.LogLevel.ERROR, tag, message) 91 | } 92 | 93 | 94 | /* 95 | * warn日志 96 | * */ 97 | static warn(message: any, tag?: string) { 98 | this.logLevel(hilog.LogLevel.WARN, tag, message) 99 | } 100 | 101 | /* 102 | * fatal日志 103 | * */ 104 | static fatal(message: any, tag?: string) { 105 | this.logLevel(hilog.LogLevel.FATAL, tag, message) 106 | } 107 | 108 | /* 109 | *统一输出日志 110 | * */ 111 | private static logLevel(level: hilog.LogLevel, tag: string, message: any) { 112 | //如果关闭状态,则不打印日志 113 | if (this.mClose) { 114 | return 115 | } 116 | 117 | //未传递时 118 | if (tag == undefined) { 119 | tag = this.mTag 120 | } 121 | 122 | const content = this.getMessage(level, tag, message) //最终的内容展示 123 | 124 | const len = content.length / this.mLogSize 125 | for (var i = 0; i < len; i++) { 126 | var con = content.substring(i * this.mLogSize, (i + 1) * this.mLogSize) 127 | if (i != 0) { 128 | con = "|" + con 129 | } 130 | //打印日志 131 | if (this.mHilog) { 132 | //使用hilog 133 | switch (level) { 134 | case hilog.LogLevel.INFO: //info 135 | hilog.info(this.mDomain, tag, con) 136 | break 137 | case hilog.LogLevel.WARN: //WARN 138 | hilog.warn(this.mDomain, tag, con) 139 | break 140 | case hilog.LogLevel.DEBUG: //DEBUG 141 | hilog.debug(this.mDomain, tag, con) 142 | break 143 | case hilog.LogLevel.ERROR: //ERROR 144 | hilog.error(this.mDomain, tag, con) 145 | break 146 | case hilog.LogLevel.FATAL: //FATAL 147 | hilog.fatal(this.mDomain, tag, con) 148 | break 149 | } 150 | } else { 151 | //使用console 152 | switch (level) { 153 | case hilog.LogLevel.INFO: //info 154 | console.info(con) 155 | break 156 | case hilog.LogLevel.WARN: //WARN 157 | console.warn(con) 158 | break 159 | case hilog.LogLevel.DEBUG: //DEBUG 160 | console.debug(con) 161 | break 162 | case hilog.LogLevel.ERROR: //ERROR 163 | console.error(con) 164 | break 165 | case hilog.LogLevel.FATAL: //FATAL 166 | console.log(con) 167 | break 168 | } 169 | } 170 | 171 | } 172 | 173 | } 174 | 175 | /** 176 | * 获取输出位置 177 | * */ 178 | static getMessage(level: hilog.LogLevel, tag: string, message: any): string { 179 | var log = "┌───────" + tag + "────────────────────────────────────────────────────────────────────────────────" 180 | log = log.substring(0, log.length - tag.length) + "\n" 181 | 182 | try { 183 | if (this.mShowLogLocation && level == hilog.LogLevel.ERROR) { 184 | //展示位置 185 | const stackTrace = new Error().stack 186 | const traceArray = stackTrace.split('\n') 187 | const trace = traceArray[traceArray.length-2] 188 | log = log + "|" + trace 189 | } 190 | 191 | var type = typeof message 192 | if (type == "object") { 193 | message = this.getObjectToJson(message) 194 | } else if (type == "string") { 195 | //判断是否包含大括号 196 | const content = message + "" 197 | if (content.startsWith("{") && content.endsWith("}")) { 198 | //对象 199 | const obj = JSON.parse(message) 200 | message = this.getObjectToJson(obj) 201 | } else { 202 | message = content 203 | } 204 | } 205 | log = log + "\n| " + message 206 | } catch (e) { 207 | 208 | } 209 | log = log + "\n└───────────────────────────────────────────────────────────────────────────────────────" 210 | return log 211 | } 212 | 213 | private static getObjectToJson(message: object): String { 214 | const json = JSON.stringify(message, null, 2) 215 | const endMessage = json.replace(/\n/g, "\n| ") 216 | return endMessage 217 | } 218 | } 219 | 220 | export { FastLogOptions, FastLog } -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/FastNavRouter.ets: -------------------------------------------------------------------------------- 1 | export class FastNavRouterModel { 2 | // 路由页面别名,形式为${包名}*${页面名},例如:@ohos/feature_setting*./src/main/ets/TestDynamicNavPage 3 | builderName: string = ""; 4 | // 传递的参数 5 | param?: object; 6 | } 7 | 8 | export class FastNavRouter { 9 | static builderMap: Map> = new Map>(); 10 | static navPathStack: NavPathStack = new NavPathStack(); 11 | 12 | // 注册页面组件到路由表,builderName是路由名字,builder参数是包裹了页面组件的WrappedBuilder对象 13 | public static registerBuilder( 14 | builderName: string, 15 | builder: WrappedBuilder<[object]> 16 | ): void { 17 | FastNavRouter.builderMap.set(builderName, builder); 18 | } 19 | 20 | // 获取路由表中指定的页面组件 21 | public static getBuilder(builderName: string): WrappedBuilder<[object]> { 22 | const builder = FastNavRouter.builderMap.get(builderName); 23 | if (!builder) { 24 | console.info('not found builder ' + builderName); 25 | } 26 | return builder as WrappedBuilder<[object]>; 27 | } 28 | 29 | public static async push(router: FastNavRouterModel): Promise { 30 | const harName = router.builderName.split('*')[0]; 31 | if (harName !== undefined) { 32 | // 动态导入页面所在 har 模块 33 | let ns: ESObject = await import(harName); 34 | await ns.harInit(router.builderName); 35 | } else { 36 | // 例如自己模块内的单文件 '../Calc' 37 | await import(router.builderName); 38 | } 39 | FastNavRouter.navPathStack.pushPath({ 40 | name: router.builderName, 41 | param: router.param 42 | }); 43 | } 44 | } -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/FastPermisttion.ts: -------------------------------------------------------------------------------- 1 | // 定义装饰器函数 2 | import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; 3 | import bundleManager from '@ohos.bundle.bundleManager'; 4 | import { common } from '@kit.AbilityKit'; 5 | 6 | export function Permission(context: common.UIAbilityContext, permissions: Permissions[]) { 7 | return function ( 8 | target: any, 9 | propertyKey: string, 10 | descriptor: PropertyDescriptor 11 | ) { 12 | const originalMethod = descriptor.value; 13 | descriptor.value = function (...args: any[]) { 14 | checkPermission(permissions) 15 | .then((grantStatusList: abilityAccessCtrl.GrantStatus[]) => { 16 | console.log('权限校验结果:', grantStatusList) 17 | const allPermissionsGranted = 18 | grantStatusList.every(status => status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) 19 | if (allPermissionsGranted) { 20 | return originalMethod.apply(this, args) 21 | } 22 | // 如果没有权限,请求权限 23 | requestPermission(permissions, context) 24 | .then(() => { 25 | // 获取权限成功后重新调用方法 26 | return originalMethod.apply(this, args) 27 | }) 28 | .catch(() => { 29 | // 获取权限失败,执行用户注入的处理函数或默认处理逻辑 30 | const errorHandler = target.permissionErrorHandler || defaultPermissionErrorHandler 31 | errorHandler() 32 | }) 33 | }) 34 | .catch((error) => { 35 | const errorHandler = target.permissionErrorHandler || defaultPermissionErrorHandler 36 | errorHandler() 37 | }) 38 | } 39 | return descriptor 40 | } 41 | } 42 | 43 | // 默认权限处理失败的逻辑 44 | function defaultPermissionErrorHandler() { 45 | console.log('没有权限执行该方法') 46 | } 47 | 48 | async function checkAccessToken(permission: Permissions): Promise { 49 | let atManager = abilityAccessCtrl.createAtManager() 50 | let grantStatus: abilityAccessCtrl.GrantStatus 51 | // 获取应用程序的accessTokenID 52 | let tokenId: number 53 | try { 54 | let bundleInfo: bundleManager.BundleInfo = 55 | await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION) 56 | let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo 57 | tokenId = appInfo.accessTokenId 58 | } catch (err) { 59 | console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`) 60 | } 61 | 62 | try { 63 | grantStatus = await atManager.checkAccessToken(tokenId, permission) 64 | } catch (err) { 65 | console.error(`checkAccessToken failed, code is ${err.code}, message is ${err.message}`) 66 | } 67 | 68 | return grantStatus 69 | } 70 | 71 | async function checkPermission(permissions: Permissions[]): Promise { 72 | 73 | let grantStatusList: abilityAccessCtrl.GrantStatus[] = [] 74 | for (let index = 0; index < permissions.length; index++) { 75 | let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[index]) 76 | grantStatusList.push(grantStatus) 77 | } 78 | return grantStatusList 79 | } 80 | 81 | function requestPermission(permissions: Permissions[], context: common.UIAbilityContext): Promise { 82 | let atManager = abilityAccessCtrl.createAtManager() 83 | return new Promise((resolve, reject) => { 84 | atManager.requestPermissionsFromUser(context, permissions).then((data) => { 85 | let grantStatus: Array = data.authResults 86 | const allGrant = grantStatus.every(status => status === 0) 87 | if (allGrant) { 88 | resolve() 89 | } else { 90 | reject() 91 | } 92 | }).catch((err) => { 93 | reject() 94 | console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`) 95 | }) 96 | }) 97 | } 98 | -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/FastRouter.ets: -------------------------------------------------------------------------------- 1 | import { router } from '@kit.ArkUI' 2 | 3 | /// 基于 router 库封装,为了实现页面回调 4 | export class FastRouter { 5 | public readonly routerStack: RouterModel[] = [] 6 | 7 | /// 跨 hsp 使用这种方式实现单例 8 | public static instance(): FastRouter { 9 | const storageKey = 'REX_FAST_ROUTER' 10 | if (!AppStorage.has(storageKey)) { 11 | AppStorage.setOrCreate(storageKey, new FastRouter()) 12 | } 13 | return AppStorage.get(storageKey)! 14 | } 15 | 16 | /// 获取路由传递的入参 17 | public static get getRouterCurrentParams(): RouterModel | undefined { 18 | const stack = FastRouter.instance().routerStack 19 | if (stack.length === 0) { 20 | return undefined 21 | } 22 | return stack[stack.length - 1] 23 | } 24 | 25 | /// push 页面 26 | public static async push(route: RouterModel): Promise { 27 | try { 28 | await router.pushUrl({ url: route.url, params: route.params }) 29 | FastRouter.instance().routerStack.push(route) 30 | } catch (_) { 31 | console.log('>>>>') 32 | } 33 | } 34 | 35 | /// replace 页面 36 | public static async replace(route: RouterModel): Promise { 37 | try { 38 | await router.replaceUrl({ url: route.url, params: route.params }) 39 | const instance = FastRouter.instance() 40 | const list = instance.routerStack 41 | if (list.length > 0) { 42 | instance.routerStack.splice(instance.routerStack.length - 1, 1, route) 43 | } 44 | } catch (_) { 45 | // 暂无处理 46 | } 47 | } 48 | 49 | /// 退出栈顶页面 50 | public static async pop(animated?: boolean): Promise { 51 | router.back() 52 | const routerStack = FastRouter.instance().routerStack 53 | routerStack.pop() 54 | } 55 | } 56 | 57 | export interface RouterModel { 58 | // 页面路径 59 | // 例如 : 1. 本地包内,或者直接依赖的静态包内页面 : pages/Page1 60 | // 2. 分包内的页面 :@bundle:包名/featureName/ets/pages/Page2 61 | url?: string 62 | params?: Object, // 要传递给跳转页面的参数 63 | popCallback?: (value: Object | undefined) => void // 用于页面回调 64 | } -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/FastTool.ets: -------------------------------------------------------------------------------- 1 | import { bundleManager } from '@kit.AbilityKit'; 2 | 3 | abstract class FastTool { 4 | /// 获取应用包名的方法 5 | public static get bundleName(): string { 6 | const info = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT) 7 | return info.name; 8 | } 9 | } -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/ObjectUtil.ts: -------------------------------------------------------------------------------- 1 | export type ObjectOrNull = Object | undefined | null 2 | 3 | export abstract class ObjectUtil { 4 | /** 5 | * 将对象转换成hashCode,用于对象的唯一标识 6 | * @param obj 7 | * @returns 8 | */ 9 | static hashCode(obj: object): number { 10 | let hash = 0 11 | let i = 0 12 | let chr: number = 0; 13 | let str = JSON.stringify(obj) 14 | if (str.length === 0) { 15 | return hash; 16 | } 17 | for (i = 0; i < str.length; i++) { 18 | chr = str.charCodeAt(i); 19 | hash = ((hash << 5) - hash) + chr; 20 | hash |= 0; // 将 hash 转换为 32 位整数 21 | } 22 | return hash 23 | } 24 | 25 | /** 26 | * 判断是否是对象 27 | * @param obj 28 | * @returns 29 | */ 30 | static isObject(obj: ObjectOrNull): boolean { 31 | return typeof obj === 'object' && obj !== null 32 | } 33 | 34 | /** 35 | * 判断是否为空 36 | * @param obj 37 | * @returns 38 | */ 39 | static isEmpty(obj: ObjectOrNull): boolean { 40 | let isEmpty = obj === undefined || obj === null 41 | if (typeof obj === 'string') { 42 | isEmpty = isEmpty || obj.trim().length === 0 43 | } 44 | return isEmpty 45 | } 46 | 47 | /** 48 | * 判断是否不为空 49 | * @param obj 50 | * @returns 51 | */ 52 | static isNotEmpty(obj: ObjectOrNull): boolean { 53 | return !ObjectUtil.isEmpty(obj) 54 | } 55 | 56 | /** 57 | * 判断是否存在属性 58 | * @param obj 59 | * @param propertyName 60 | * @returns 61 | */ 62 | static hasProperty(obj: ObjectOrNull, propertyName: string): boolean { 63 | if (!ObjectUtil.isObject(obj)) { 64 | return false 65 | } 66 | for (const key of Object.keys(obj!)) { 67 | if (key === propertyName) { 68 | return true 69 | } 70 | } 71 | return false 72 | } 73 | 74 | /** 75 | * 对象深拷贝 76 | * @param obj 77 | * @returns 78 | */ 79 | static deepCopy(obj: object): object { 80 | let newObj: Record | Object[] = Array.isArray(obj) ? [] : {}; 81 | for (let key of Object.keys(obj)) { 82 | if (ObjectUtil.isObject(obj[key])) { 83 | newObj[key] = ObjectUtil.deepCopy(obj[key]); 84 | } else { 85 | newObj[key] = obj[key]; 86 | } 87 | } 88 | return newObj; 89 | } 90 | 91 | /** 92 | * 对象浅拷贝 93 | * @param obj 94 | * @returns 95 | */ 96 | static shallowCopy(obj: object): object { 97 | let newObj: Record = {}; 98 | for (let key of Object.keys(obj)) { 99 | newObj[key] = obj[key]; 100 | } 101 | return newObj; 102 | } 103 | 104 | /** 105 | * 对象转map 106 | * @param obj 107 | * @returns 108 | */ 109 | static objectToMap(obj: Object): Map { 110 | let map = new Map(); 111 | if (obj instanceof Array) { 112 | for (let i = 0; i < obj.length; i++) { 113 | if (ObjectUtil.isObject(obj[i])) { 114 | map.set(i.toString(), ObjectUtil.objectToMap(obj[i])); 115 | } else { 116 | map.set(i.toString(), obj[i]); 117 | } 118 | } 119 | } else if (ObjectUtil.isObject(obj)) { 120 | for (let key in obj) { 121 | if (ObjectUtil.isObject(obj[key])) { 122 | map.set(key, ObjectUtil.objectToMap(obj[key])); 123 | } else { 124 | map.set(key, obj[key]); 125 | } 126 | } 127 | } 128 | return map; 129 | } 130 | } -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/PreferencesUtil.ets: -------------------------------------------------------------------------------- 1 | import dataPreferences from '@ohos.data.preferences'; 2 | import { FastLog } from './FastLog'; 3 | 4 | let preference: dataPreferences.Preferences; 5 | 6 | /// 数据持久化工具 7 | export class PreferencesUtil { 8 | static readonly TAG: string = "preferences_util"; 9 | static readonly KEY_PREFERENCES = "preferences" 10 | static readonly PREFERENCES_NAME: string = "fast_preferences"; 11 | 12 | // 在 Entity create 进行调用 13 | static async createPreferences(context: Context) { 14 | try { 15 | preference = await dataPreferences.getPreferences(context, PreferencesUtil.PREFERENCES_NAME); 16 | } catch (err) { 17 | FastLog.error(PreferencesUtil.TAG, `Failed to get preferences, Cause: ${err}`); 18 | } 19 | } 20 | 21 | // 外部可通过这个方法进行监听 22 | // preference.on('change',(data) => {}) 23 | static async getPreferences(context: Context): Promise { 24 | if (!preference) { 25 | await PreferencesUtil.createPreferences(context); 26 | } 27 | return preference 28 | } 29 | 30 | static async deletePreferences(context: Context): Promise { 31 | try { 32 | await dataPreferences.deletePreferences(context, PreferencesUtil.PREFERENCES_NAME); 33 | return true 34 | } catch (err) { 35 | FastLog.error(PreferencesUtil.TAG, `Failed to delete preferences, Cause: ${err}`); 36 | return false 37 | } 38 | } 39 | 40 | static async put(key: string, value: Object) { 41 | try { 42 | if (typeof value === "object") { 43 | if (Array.isArray(value)) { 44 | await preference.put(key, JSON.stringify(value)); 45 | } else { 46 | await preference.put(key, JSON.stringify(value)); 47 | } 48 | } else { 49 | await preference.put(key, value); 50 | } 51 | } catch (err) { 52 | FastLog.error(PreferencesUtil.TAG, `Failed to put value, Cause: ${err}`); 53 | } 54 | await preference.flush(); 55 | } 56 | 57 | static async get(key: string): Promise { 58 | let value: Object | undefined = undefined; 59 | try { 60 | value = await preference.get(key, undefined); 61 | } catch (err) { 62 | FastLog.error(PreferencesUtil.TAG, `Failed to get value, Cause: ${err}`); 63 | } 64 | return value; 65 | } 66 | 67 | static async getEntity(key: string): Promise { 68 | let value: string = ''; 69 | try { 70 | value = (await preference.get(key, '')).toString(); 71 | } catch (err) { 72 | FastLog.error(PreferencesUtil.TAG, `Failed to get value, Cause: ${err}`); 73 | } 74 | if (value === '') { 75 | return ''; 76 | } 77 | return JSON.parse(value); 78 | } 79 | 80 | static async getAll(): Promise { 81 | let value: Object | undefined; 82 | try { 83 | value = await preference.getAll(); 84 | } catch (err) { 85 | FastLog.error(PreferencesUtil.TAG, `Failed to get value, Cause: ${err}`); 86 | } 87 | return value; 88 | } 89 | 90 | static async has(key: string): Promise { 91 | let value: boolean = false; 92 | try { 93 | value = await preference.has(key).then(); 94 | } catch (err) { 95 | FastLog.error(PreferencesUtil.TAG, `Failed to get value, Cause: ${err}`); 96 | } 97 | return value; 98 | } 99 | 100 | static async delete(key: string): Promise { 101 | try { 102 | await preference.delete(key); 103 | return true; 104 | } catch (err) { 105 | FastLog.error(PreferencesUtil.TAG, `Failed to get value, Cause: ${err}`); 106 | return false; 107 | } 108 | } 109 | 110 | static async clear(): Promise { 111 | try { 112 | await preference.clear(); 113 | return true; 114 | } catch (err) { 115 | FastLog.error(PreferencesUtil.TAG, `Failed to get value, Cause: ${err}`); 116 | return false; 117 | } 118 | } 119 | } 120 | 121 | -------------------------------------------------------------------------------- /base/fast_util/src/main/ets/ThrottleTool.ts: -------------------------------------------------------------------------------- 1 | /// 节流 2 | export function Throttle(period: number): MethodDecorator { 3 | return function ( 4 | target: any, 5 | propertyKey: string, 6 | descriptor: PropertyDescriptor 7 | ): PropertyDescriptor { 8 | const originalMethod = descriptor.value 9 | let timeID: number = 0 10 | descriptor.value = function (...args: any[]): void { 11 | if (timeID === 0) { 12 | originalMethod.apply(this, args) 13 | timeID = setTimeout(() => { 14 | timeID = 0 15 | }, 16 | period 17 | ) 18 | } 19 | } 20 | return descriptor 21 | } 22 | } 23 | 24 | /// 防抖 25 | export function Debounce(period: number): MethodDecorator { 26 | return function ( 27 | target: any, 28 | propertyKey: string, 29 | descriptor: PropertyDescriptor 30 | ): PropertyDescriptor { 31 | const originalMethod = descriptor.value 32 | let timeID: number = 0 33 | descriptor.value = function (...args: any[]): void { 34 | if (timeID !== 0) { 35 | clearTimeout(timeID) 36 | } 37 | timeID = setTimeout(() => { 38 | originalMethod.apply(this, args) 39 | timeID = 0 40 | }, 41 | period 42 | ) 43 | } 44 | return descriptor 45 | } 46 | } -------------------------------------------------------------------------------- /base/fast_util/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "fast_util", 4 | "type": "har", 5 | "deviceTypes": [ 6 | "default", 7 | "tablet" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /base/fast_util/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /base/fast_util/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /base/fast_util/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /base/global_constant/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /base/global_constant/BuildProfile.ets: -------------------------------------------------------------------------------- 1 | /** 2 | * Use these variables when you tailor your ArkTS code. They must be of the const type. 3 | */ 4 | export const HAR_VERSION = '1.0.0'; 5 | export const BUILD_MODE_NAME = 'debug'; 6 | export const DEBUG = true; 7 | export const TARGET_NAME = 'default'; 8 | 9 | /** 10 | * BuildProfile Class is used only for compatibility purposes. 11 | */ 12 | export default class BuildProfile { 13 | static readonly HAR_VERSION = HAR_VERSION; 14 | static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; 15 | static readonly DEBUG = DEBUG; 16 | static readonly TARGET_NAME = TARGET_NAME; 17 | } -------------------------------------------------------------------------------- /base/global_constant/Index.ets: -------------------------------------------------------------------------------- 1 | export { default as PagePathConstants } from './src/main/ets/PagePathConstants' 2 | -------------------------------------------------------------------------------- /base/global_constant/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | }, 5 | "buildOptionSet": [ 6 | { 7 | "name": "release", 8 | "arkOptions": { 9 | "obfuscation": { 10 | "ruleOptions": { 11 | "enable": true, 12 | "files": [ 13 | "./obfuscation-rules.txt" 14 | ] 15 | }, 16 | "consumerFiles": [ 17 | "./consumer-rules.txt" 18 | ] 19 | } 20 | }, 21 | }, 22 | ], 23 | "targets": [ 24 | { 25 | "name": "default" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /base/global_constant/consumer-rules.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/base/global_constant/consumer-rules.txt -------------------------------------------------------------------------------- /base/global_constant/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { harTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /base/global_constant/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /base/global_constant/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "global_constant", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "Index.ets", 6 | "author": "", 7 | "license": "Apache-2.0", 8 | "dependencies": {} 9 | } 10 | -------------------------------------------------------------------------------- /base/global_constant/src/main/ets/PagePathConstants.ets: -------------------------------------------------------------------------------- 1 | /// 记录页面路径常量 2 | export default abstract class PagePathConstants { 3 | // 网络请求示例 4 | static PAGE_HTTP_REQUEST: string = '/page/HttpRequestPage' 5 | // 消息通知示例 6 | static PAGE_EVENT_BUS: string = '/page/EventBusExample' 7 | // 自定义弹窗示例 8 | static PAGE_CUSTOM_DIALOG: string = '/page/CustomPageExample' 9 | // 路由回调示例 10 | static PAGE_ROUTER_CALLBACK: string = '/page/RouterCallbackExample' 11 | // Nav路由示例页面 12 | static PAGE_NAV_ROUTER_TEST: string = '/page/NavRouterTestPage' 13 | // 节流防抖示例 14 | static PAGE_THROTTLE_TEST: string = '/page/ThrottleExample' 15 | // 简易授权示例 16 | static PAGE_PERMISSION_TEST: string = '/page/PermissionExample' 17 | // 测试动态路由 18 | static DYNAMIC_ROUTER_TEST: string = '@ohos/feature_setting*./src/main/ets/TestDynamicNavPage' 19 | // UI动态节点示例 20 | static DYNAMIC_UI_NODE_TEST: string = '/page/BuilderNodeExample' 21 | // 适配折叠屏 22 | static FIX_FOLD_UI_EXAMPLE: string = '/page/FixFoldUiExample' 23 | // 组件工厂示例 24 | static COMPONENT_FACTORY_EXAMPLE: string = '/page/ComponentFactoryExample' 25 | // 组件动态属性示例 26 | static ATTRIBUTE_MODIFIER_EXAMPLE: string = '/page/AttributeModifierExample' 27 | // 云函数调用示例 28 | static CLOUD_FUNCTION_EXAMPLE: string = '/page/CloudFuncExample' 29 | // 云数据库使用示例 30 | static CLOUD_DATA_BASE_EXAMPLE: string = '/page/CloudDatabaseExample' 31 | } -------------------------------------------------------------------------------- /base/global_constant/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "global_constant", 4 | "type": "har", 5 | "deviceTypes": [ 6 | "default", 7 | "tablet" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /base/global_constant/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /base/global_constant/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /base/global_constant/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "signingConfigs": [ 4 | { 5 | "name": "default", 6 | "type": "HarmonyOS", 7 | "material": { 8 | "storePassword": "00000019D30858742D71B8F77D1CC4F8EF7A503B2AF22983D695625440CA16155B2E2A7CC4692E4660", 9 | "certpath": "./certificate/debug/codeLab-Debug.cer", 10 | "keyAlias": "codeLab", 11 | "keyPassword": "000000196FFFFCDC47834EBEF46272885E5360BE50FFD27994799FFDDB3282638F2BF351F0C51C037E", 12 | "profile": "./certificate/debug/codeLab-DebugDebug.p7b", 13 | "signAlg": "SHA256withECDSA", 14 | "storeFile": "./certificate/debug/code_lab.p12" 15 | } 16 | } 17 | ], 18 | "products": [ 19 | { 20 | "name": "default", 21 | "signingConfig": "default", 22 | "compatibleSdkVersion": "5.0.0(12)", 23 | "runtimeOS": "HarmonyOS", 24 | } 25 | ], 26 | "buildModeSet": [ 27 | { 28 | "name": "debug", 29 | }, 30 | { 31 | "name": "release" 32 | } 33 | ] 34 | }, 35 | "modules": [ 36 | { 37 | "name": "entry", 38 | "srcPath": "./entry", 39 | "targets": [ 40 | { 41 | "name": "default", 42 | "applyToProducts": [ 43 | "default" 44 | ] 45 | } 46 | ] 47 | }, 48 | { 49 | "name": "feature_home", 50 | "srcPath": "./business/feature_home" 51 | }, 52 | { 53 | "name": "feature_setting", 54 | "srcPath": "./business/feature_setting" 55 | }, 56 | { 57 | "name": "fast_ui", 58 | "srcPath": "./base/fast_ui" 59 | }, 60 | { 61 | "name": "global_constant", 62 | "srcPath": "./base/global_constant" 63 | }, 64 | { 65 | "name": "fast_util", 66 | "srcPath": "./base/fast_util" 67 | }, 68 | { 69 | "name": "feature_hsp_page", 70 | "srcPath": "./features/feature_hsp_page", 71 | "targets": [ 72 | { 73 | "name": "default", 74 | "applyToProducts": [ 75 | "default" 76 | ] 77 | } 78 | ] 79 | } 80 | ] 81 | } -------------------------------------------------------------------------------- /business/feature_home/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /business/feature_home/BuildProfile.ets: -------------------------------------------------------------------------------- 1 | /** 2 | * Use these variables when you tailor your ArkTS code. They must be of the const type. 3 | */ 4 | export const HAR_VERSION = '1.0.0'; 5 | export const BUILD_MODE_NAME = 'debug'; 6 | export const DEBUG = true; 7 | export const TARGET_NAME = 'default'; 8 | 9 | /** 10 | * BuildProfile Class is used only for compatibility purposes. 11 | */ 12 | export default class BuildProfile { 13 | static readonly HAR_VERSION = HAR_VERSION; 14 | static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; 15 | static readonly DEBUG = DEBUG; 16 | static readonly TARGET_NAME = TARGET_NAME; 17 | } -------------------------------------------------------------------------------- /business/feature_home/Index.ets: -------------------------------------------------------------------------------- 1 | export { HomePage } from './src/main/ets/HomePage' 2 | export { HttpRequestExample } from './src/main/ets/pages/HttpRequestExample' 3 | export { EventBusExample } from './src/main/ets/pages/EventBusExample' 4 | export { CustomDialogExample } from './src/main/ets/pages/CustomDialogExample' 5 | export { RouterCallbackExample } from './src/main/ets/pages/RouterCallbackExample' 6 | export { TestNavPathJumpPage } from './src/main/ets/pages/TestNavPathJumpPage' 7 | export { ThrottleExample } from './src/main/ets/pages/ThrottleExample' 8 | export { PermissionExample } from './src/main/ets/pages/PermissionExample' 9 | export { BuilderNodeExample } from './src/main/ets/pages/BuilderNodeExample' 10 | export { FixFoldUiExample } from './src/main/ets/pages/FixFoldUiExample' 11 | export { ComponentFactoryExample } from './src/main/ets/pages/ComponentFactoryExample' 12 | export { AttributeModifierExample } from './src/main/ets/pages/AttributeModifierExample' 13 | export { CloudFuncExample } from './src/main/ets/pages/CloudFuncExample' 14 | export { CloudDatabaseExample } from './src/main/ets/pages/CloudDatabaseExample' 15 | -------------------------------------------------------------------------------- /business/feature_home/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | }, 5 | "buildOptionSet": [ 6 | { 7 | "name": "release", 8 | "arkOptions": { 9 | "obfuscation": { 10 | "ruleOptions": { 11 | "enable": true, 12 | "files": [ 13 | "./obfuscation-rules.txt" 14 | ] 15 | }, 16 | "consumerFiles": [ 17 | "./consumer-rules.txt" 18 | ] 19 | } 20 | }, 21 | }, 22 | ], 23 | "targets": [ 24 | { 25 | "name": "default" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /business/feature_home/consumer-rules.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/business/feature_home/consumer-rules.txt -------------------------------------------------------------------------------- /business/feature_home/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { harTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /business/feature_home/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /business/feature_home/oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "@ohos/fast_ui@../../base/fast_ui": "@ohos/fast_ui@../../base/fast_ui", 9 | "@ohos/fast_util@../../base/fast_util": "@ohos/fast_util@../../base/fast_util", 10 | "@ohos/global_constant@../../base/global_constant": "@ohos/global_constant@../../base/global_constant", 11 | "@rex/fast_https_request@1.0.1": "@rex/fast_https_request@1.0.1" 12 | }, 13 | "packages": { 14 | "@ohos/fast_ui@../../base/fast_ui": { 15 | "name": "fast_ui", 16 | "version": "1.0.0", 17 | "resolved": "../../base/fast_ui", 18 | "registryType": "local" 19 | }, 20 | "@ohos/fast_util@../../base/fast_util": { 21 | "name": "fast_util", 22 | "version": "1.0.0", 23 | "resolved": "../../base/fast_util", 24 | "registryType": "local" 25 | }, 26 | "@ohos/global_constant@../../base/global_constant": { 27 | "name": "global_constant", 28 | "version": "1.0.0", 29 | "resolved": "../../base/global_constant", 30 | "registryType": "local" 31 | }, 32 | "@rex/fast_https_request@1.0.1": { 33 | "name": "@rex/fast_https_request", 34 | "version": "1.0.1", 35 | "integrity": "sha512-qFj8anVCIvuK5XeEsPz0OLpOiMu/q115j3e9EKwizWcv5mIuSTJ3srXH9wh1wepA4zSmsZcOl8nyaPtyyaR34A==", 36 | "resolved": "https://repo.harmonyos.com/ohpm/@rex/fast_https_request/-/fast_https_request-1.0.1.har", 37 | "registryType": "ohpm" 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /business/feature_home/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "feature_home", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "Index.ets", 6 | "author": "", 7 | "license": "Apache-2.0", 8 | "dependencies": { 9 | "@ohos/fast_ui": "file:../../base/fast_ui", 10 | "@ohos/fast_util": "file:../../base/fast_util", 11 | "@rex/fast_https_request": "1.0.1", 12 | "@ohos/global_constant": "file:../../base/global_constant", 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/HomePage.ets: -------------------------------------------------------------------------------- 1 | /// 首页 2 | import { FastNavRouter } from '@ohos/fast_util'; 3 | import { PagePathConstants } from '@ohos/global_constant'; 4 | import { Category, SubCategory, HOME_CATEGORIES } from './config/HomeCategoricalData'; 5 | 6 | 7 | @Extend(Column) 8 | function ColumnStyle() { 9 | .width('100%') 10 | .borderRadius(24) 11 | .backgroundColor(Color.White) 12 | .padding({ 13 | left: 12, 14 | right: 12, 15 | bottom: 4, 16 | top: 4 17 | }) 18 | } 19 | 20 | @Extend(Text) 21 | function TitleStyle() { 22 | .height(48) 23 | .fontSize(14) 24 | .width('100%') 25 | .textAlign(TextAlign.Start) 26 | .fontFamily('HarmonyHeiTi-Medium') 27 | .fontColor($r('app.color.font_color_shallow')) 28 | .padding({ bottom: 4, top: 4, left: 24 }) 29 | } 30 | 31 | @Component 32 | export struct HomePage { 33 | build() { 34 | Column() { 35 | List() { 36 | ForEach(HOME_CATEGORIES, (category: Category, index: number) => { 37 | CategoryItem({ category: category }) 38 | }) 39 | } 40 | .width('100%') 41 | .layoutWeight(1) 42 | .padding({ left: 16, right: 16, top: 4 }) 43 | 44 | Blank() 45 | } 46 | .width('100%') 47 | .height('100%') 48 | .padding({ top: 12 }) 49 | } 50 | } 51 | 52 | @Component 53 | struct CategoryItem { 54 | private category: Category | null = null 55 | 56 | build() { 57 | ListItem() { 58 | Column() { 59 | Text(this.category!.title).TitleStyle() 60 | Column() { 61 | ForEach( 62 | this.category!.childNodes, 63 | (subItem: SubCategory, index: number) => { 64 | SubCategoryItem({ subItem: subItem }) 65 | } 66 | ) 67 | }.ColumnStyle() 68 | } 69 | } 70 | } 71 | } 72 | 73 | @Component 74 | struct SubCategoryItem { 75 | @Consume('navPathStack') navPathStack: NavPathStack; 76 | private subItem: SubCategory | null = null 77 | 78 | build() { 79 | Row() { 80 | if (this.subItem) { 81 | Text(this.subItem.title) 82 | .fontSize(16) 83 | .layoutWeight(1) 84 | .margin({ left: 42 }) 85 | .align(Alignment.Start) 86 | .fontFamily('HarmonyHeiTi-Medium') 87 | .fontColor(Color.Black) 88 | } 89 | Blank() 90 | } 91 | .height(48) 92 | .width('100%') 93 | .onClick(() => { 94 | if (this.subItem?.url === PagePathConstants.DYNAMIC_ROUTER_TEST) { 95 | // 测试动态路由 96 | let param = new String(this.subItem.url) 97 | FastNavRouter.push({ builderName: this.subItem.url, param: param }) 98 | } else { 99 | this.navPathStack.pushPathByName(this.subItem?.url ?? '', null) 100 | } 101 | }) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/cloudDb/LogReport.ets: -------------------------------------------------------------------------------- 1 | import { cloudDatabase } from '@kit.CloudFoundationKit'; 2 | 3 | /// 对应创建的云数据库对象类型‘LogReport’ 4 | class LogReport extends cloudDatabase.DatabaseObject { 5 | public naturalbase_ClassName(): string { 6 | return "LogReport"; 7 | } 8 | 9 | public id: number | undefined; 10 | public content: string | undefined; 11 | public time: string | undefined; 12 | } 13 | 14 | export { LogReport }; -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/config/HomeCategoricalData.ets: -------------------------------------------------------------------------------- 1 | import { PagePathConstants } from '@ohos/global_constant' 2 | 3 | export interface Category { 4 | title: Resource, 5 | childNodes: SubCategory[] 6 | } 7 | 8 | export interface SubCategory { 9 | title: Resource | string, 10 | url?: string, 11 | } 12 | 13 | export const COMMON_EXAMPLES: SubCategory[] = 14 | [ 15 | { 16 | title: $r('app.string.http_example'), 17 | url: PagePathConstants.PAGE_HTTP_REQUEST, 18 | }, 19 | { 20 | title: $r('app.string.event_bus_example'), 21 | url: PagePathConstants.PAGE_EVENT_BUS, 22 | }, 23 | { 24 | title: $r('app.string.custom_dialog_example'), 25 | url: PagePathConstants.PAGE_CUSTOM_DIALOG, 26 | }, 27 | { 28 | title: $r('app.string.router_callback_example'), 29 | url: PagePathConstants.PAGE_ROUTER_CALLBACK, 30 | }, 31 | { 32 | title: $r('app.string.throttle_example'), 33 | url: PagePathConstants.PAGE_THROTTLE_TEST, 34 | }, 35 | { 36 | title: $r('app.string.permission_example'), 37 | url: PagePathConstants.PAGE_PERMISSION_TEST, 38 | }, 39 | { 40 | title: $r('app.string.dynamic_router_example'), 41 | url: PagePathConstants.DYNAMIC_ROUTER_TEST, 42 | }, 43 | { 44 | title: $r('app.string.dynamic_ui_node_example'), 45 | url: PagePathConstants.DYNAMIC_UI_NODE_TEST, 46 | }, 47 | { 48 | title: $r('app.string.fix_fold_ui_example'), 49 | url: PagePathConstants.FIX_FOLD_UI_EXAMPLE, 50 | }, 51 | { 52 | title: $r('app.string.component_factory_example'), 53 | url: PagePathConstants.COMPONENT_FACTORY_EXAMPLE, 54 | }, 55 | { 56 | title: $r('app.string.attribute_modifier_example'), 57 | url: PagePathConstants.ATTRIBUTE_MODIFIER_EXAMPLE, 58 | }, 59 | { 60 | title: $r('app.string.cloud_function_example'), 61 | url: PagePathConstants.CLOUD_FUNCTION_EXAMPLE, 62 | }, 63 | { 64 | title: $r('app.string.cloud_data_base_example'), 65 | url: PagePathConstants.CLOUD_DATA_BASE_EXAMPLE, 66 | }, 67 | ]; 68 | 69 | export const HOME_CATEGORIES: Category[] = 70 | [ 71 | { title: $r('app.string.common_example'), childNodes: COMMON_EXAMPLES }, 72 | ]; 73 | 74 | 75 | -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/dialog/CustomDialogContainer.ets: -------------------------------------------------------------------------------- 1 | import { MyCustomDialog } from './MyCustomDialog' 2 | 3 | /// 为了将dialog的初始化与与使用dialog的页面解耦 4 | @Component 5 | export struct CustomDialogContainer { 6 | @Link @Watch('onDialogToggle') controller: DialogContainerController 7 | dialogController?: CustomDialogController | null 8 | 9 | onDialogToggle() { 10 | if (this.controller.isOpen) { 11 | this.showDialog().then((data) => { 12 | this.controller.onDialogConfirm(data) 13 | }) 14 | } else { 15 | this.dialogController?.close() 16 | } 17 | } 18 | 19 | private async showDialog(): Promise { 20 | let resolveFunc: (value: string | undefined | PromiseLike) => void = () => { 21 | } 22 | const promise = new Promise( 23 | (resolve, _) => { 24 | resolveFunc = resolve 25 | } 26 | ) 27 | this.dialogController = new CustomDialogController({ 28 | builder: MyCustomDialog( 29 | { 30 | confirmed: (info) => { 31 | resolveFunc(info) 32 | }, 33 | disappearCallback: () => { 34 | this.dialogController = null 35 | this.controller.isOpen = false 36 | } 37 | } 38 | ), 39 | alignment: DialogAlignment.Center, 40 | customStyle: true 41 | }) 42 | this.dialogController?.open() 43 | return promise 44 | } 45 | 46 | build() { 47 | Column() 48 | } 49 | } 50 | 51 | export class DialogContainerController { 52 | isOpen: boolean = false; 53 | onDialogConfirm: (value: string | undefined) => void 54 | 55 | constructor(onConfirm: (value: string | undefined) => void) { 56 | this.onDialogConfirm = onConfirm 57 | } 58 | 59 | public open() { 60 | this.isOpen = true 61 | } 62 | 63 | public close() { 64 | this.isOpen = false 65 | } 66 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/dialog/MyCustomDialog.ets: -------------------------------------------------------------------------------- 1 | //自定义弹窗的内容 2 | import { CommonFillButton } from '@ohos/fast_ui/Index' 3 | 4 | @CustomDialog 5 | @Component 6 | export struct MyCustomDialog { 7 | private controller: CustomDialogController 8 | @State randomResult: number = 0 9 | //确定按钮回调 10 | confirmed: (message: string) => void = (_) => { 11 | } 12 | //提供给 dialogContainer 通知弹窗已关闭 13 | disappearCallback: () => void = () => { 14 | } 15 | 16 | aboutToDisappear(): void { 17 | this.disappearCallback() 18 | } 19 | 20 | aboutToAppear(): void { 21 | this.randomResult = Math.random() 22 | } 23 | 24 | build() { 25 | Column() { 26 | Text(`这是一个自定义弹窗\n\n${this.randomResult}`) 27 | .margin({ 28 | bottom: '20vp', 29 | }) 30 | CommonFillButton({ 31 | text: `点击传递数据给调用方`, 32 | horizontalPadding: '90vp', 33 | verticalPadding: '12vp', 34 | event: (): void => { 35 | this.controller.close() 36 | this.confirmed(`你好,我是弹窗点击返回的内容: ${this.randomResult}`) 37 | } 38 | }) 39 | } 40 | .width("100%") 41 | .padding({ 42 | top: '30vp', 43 | bottom: '30vp', 44 | left: '10vp', 45 | right: '10vp', 46 | }) 47 | .borderRadius('12vp') 48 | .backgroundColor(Color.White) 49 | } 50 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/AttributeModifierExample.ets: -------------------------------------------------------------------------------- 1 | /// 组件动态属性示例 2 | 3 | class CusButtonModifier implements AttributeModifier { 4 | private buttonType: ButtonType = ButtonType.Normal; 5 | 6 | applyNormalAttribute(instance: ButtonAttribute): void { 7 | instance.stateEffect(true) 8 | instance.type(this.buttonType) 9 | instance.height(50) 10 | instance.fontSize(20) 11 | } 12 | 13 | toggleType(): CusButtonModifier { 14 | if (this.buttonType === ButtonType.Normal) { 15 | this.buttonType = ButtonType.Capsule 16 | } else { 17 | this.buttonType = ButtonType.Normal 18 | } 19 | return this; 20 | } 21 | } 22 | 23 | @Component 24 | export struct AttributeModifierExample { 25 | @State modifier: CusButtonModifier = new CusButtonModifier(); 26 | 27 | build() { 28 | NavDestination() { 29 | Column() { 30 | Button('Test AttributeModifier Button') 31 | .attributeModifier(this.modifier) 32 | .onClick(() => { 33 | this.modifier.toggleType() 34 | }) 35 | } 36 | .width('100%') 37 | .height('100%') 38 | .justifyContent(FlexAlign.Center) 39 | } 40 | .title('组件动态属性设置示例') 41 | } 42 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/BuilderNodeExample.ets: -------------------------------------------------------------------------------- 1 | /// UI动态节点示例 2 | import { BuilderNode, FrameNode, NodeController } from '@kit.ArkUI' 3 | 4 | // 1. 准备好需要挂载的节点及要绑定的数据模型 5 | class Params { 6 | text: string = '' 7 | 8 | constructor(text: string) { 9 | this.text = text 10 | } 11 | } 12 | 13 | @Builder 14 | function customNodeBuilder(params: Params) { 15 | Column() { 16 | Text(params.text) 17 | .fontSize(25) 18 | .margin({ bottom: 15 }) 19 | } 20 | } 21 | 22 | // 2. 封装 controller 用于实现自定义节点的创建、显示、更新等操作 23 | class CustomNodeController extends NodeController { 24 | private customNode: BuilderNode<[Params]> | null = null; 25 | private message: string = ""; 26 | 27 | constructor(message: string) { 28 | super() 29 | this.message = message 30 | } 31 | 32 | makeNode(context: UIContext): FrameNode | null { 33 | this.customNode = new BuilderNode(context); 34 | this.customNode.build(wrapBuilder<[Params]>(customNodeBuilder), new Params(this.message)) 35 | return this.customNode.getFrameNode(); 36 | } 37 | 38 | update(message: string) { 39 | if (this.customNode !== null) { 40 | this.customNode.update(new Params(message)); 41 | } 42 | } 43 | } 44 | 45 | // 3. 使用自定义节点 46 | @Component 47 | export struct BuilderNodeExample { 48 | private textNodeController: CustomNodeController = new CustomNodeController('hello'); 49 | private count = 0; 50 | 51 | build() { 52 | NavDestination() { 53 | Row() { 54 | Column() { 55 | NodeContainer(this.textNodeController) 56 | .width('100%') 57 | .height(100) 58 | .align(Alignment.Center) 59 | Button('Update') 60 | .onClick(() => { 61 | this.count += 1; 62 | this.textNodeController.update("Update " + this.count.toString()); 63 | }) 64 | } 65 | .width('100%') 66 | .height('100%') 67 | .justifyContent(FlexAlign.Center) 68 | } 69 | .height('100%') 70 | .alignItems(VerticalAlign.Center) 71 | }.title('UI动态节点示例') 72 | } 73 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/CloudDatabaseExample.ets: -------------------------------------------------------------------------------- 1 | // 云数据库 2 | // 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/cloudfoundation-database-initialize-V5 3 | // 云数据库对应配置文件: entry/src/main/resources/rawfile/schema.json 4 | import { cloudDatabase } from '@kit.CloudFoundationKit'; 5 | import { FastToast } from '@ohos/fast_ui'; 6 | import { LogReport } from '../cloudDb/LogReport'; 7 | 8 | @Component 9 | export struct CloudDatabaseExample { 10 | @State logContent: string = '' 11 | @State logData: LogReport[] = [] 12 | 13 | aboutToAppear(): void { 14 | this.queryCloudData() 15 | } 16 | 17 | getCurrentTime(): string { 18 | let date = new Date(); 19 | return `${date.getFullYear()}-${date.getMonth() + 20 | 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`; 21 | } 22 | 23 | async upsertCloudData() { 24 | try { 25 | if (this.logContent !== '') { 26 | // CodeLabDemo 是AGC开发平台上创建的存储区名称 27 | let databaseZone = cloudDatabase.zone("CodeLabDemo"); 28 | let log = new LogReport(); 29 | log.id = new Date().getMilliseconds() 30 | log.content = this.logContent; 31 | log.time = this.getCurrentTime(); 32 | await databaseZone.upsert(log); 33 | FastToast.shortToast(`写入成功`); 34 | this.logContent = ''; 35 | this.queryCloudData(); 36 | } 37 | } catch (err) { 38 | FastToast.shortToast(`写入失败: ${err.message}`); 39 | } 40 | } 41 | 42 | async queryCloudData() { 43 | try { 44 | let condition = new cloudDatabase.DatabaseQuery(LogReport); 45 | let databaseZone = cloudDatabase.zone("CodeLabDemo"); 46 | let resultArray = await databaseZone.query(condition); 47 | this.logData = resultArray; 48 | } catch (err) { 49 | FastToast.shortToast(`Failed to query Code: ${err.code}, message: ${err.message}`); 50 | } 51 | } 52 | 53 | async deleteCloudData(data: LogReport) { 54 | try { 55 | let databaseZone = cloudDatabase.zone("CodeLabDemo"); 56 | await databaseZone.delete(data); 57 | FastToast.shortToast(`删除成功`); 58 | this.queryCloudData() 59 | } catch (err) { 60 | FastToast.shortToast(`删除失败: ${err.message}`); 61 | } 62 | } 63 | 64 | build() { 65 | NavDestination() { 66 | Column() { 67 | 68 | TextInput({ placeholder: "输入任意内容", text: `${this.logContent}` }) 69 | .width('90%') 70 | .onChange((value: string) => { 71 | this.logContent = value; 72 | }) 73 | 74 | Button('写入云数据库', { type: ButtonType.Capsule, stateEffect: true }) 75 | .margin({ top: '100px', bottom: '100px' }) 76 | .width('90%') 77 | .onClick(() => { 78 | this.upsertCloudData(); 79 | }) 80 | 81 | Text('下方同步显示云端数据').fontSize(11).margin({ bottom: '35px' }) 82 | this.logDataListView() 83 | } 84 | .justifyContent(FlexAlign.Start) 85 | .margin({ 86 | top: 20 87 | }) 88 | .width('100%') 89 | .height('100%') 90 | } 91 | .title('云数据库使用示例') 92 | } 93 | 94 | @Builder 95 | logDataListView() { 96 | List() { 97 | ForEach(this.logData, (item: LogReport) => { 98 | ListItem() { 99 | Row() { 100 | Text(item.time).fontSize(12).margin({ right: 15 }) 101 | Text(item.content).fontSize(13) 102 | } 103 | .width('100%') 104 | .padding(10) 105 | }.onClick(() => { 106 | this.deleteCloudData(item) 107 | }) 108 | }) 109 | } 110 | .width('90%') 111 | .layoutWeight(1) 112 | .borderRadius(8) 113 | .backgroundColor('#FFE2E5E7') 114 | .margin({ 115 | bottom: '80px' 116 | }) 117 | .divider({ 118 | strokeWidth: 1, 119 | color: Color.White 120 | }) 121 | } 122 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/CloudFuncExample.ets: -------------------------------------------------------------------------------- 1 | // 云函数调用示例 2 | // 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/cloudfoundation-call-function-V5 3 | // 云函数对应配置文件: AppScope/resources/rawfile/agconnect-services.json 4 | import { cloudFunction } from '@kit.CloudFoundationKit'; 5 | import { BusinessError } from '@kit.BasicServicesKit'; 6 | import { ObjectUtil } from '@ohos/fast_util'; 7 | 8 | @Component 9 | export struct CloudFuncExample { 10 | @State year: string = ''; 11 | @State functionResult: string = ''; 12 | 13 | callFunction() { 14 | cloudFunction.call({ 15 | name: "cloundfunction", //对应创建的云函数名称 16 | version: "$latest", //如果不传入版本号,默认为“$latest”。 17 | timeout: 10 * 1000, //单位为毫秒,默认为70*1000毫秒。 18 | data: { 19 | year: this.year, 20 | } 21 | }).then((value: cloudFunction.FunctionResult) => { 22 | // 返回结果为 {'result':'***'} 23 | let objectMap = ObjectUtil.objectToMap(value.result!) 24 | this.functionResult = objectMap.get('result')!.toString(); 25 | }).catch((err: BusinessError) => { 26 | console.error(`Failed to call the function, Code: ${err.code}, message: ${err.message}`); 27 | }) 28 | } 29 | 30 | build() { 31 | NavDestination() { 32 | Column() { 33 | 34 | TextInput({ placeholder: "输入年份查询对应生肖" }) 35 | .width('90%') 36 | .onChange((value: string) => { 37 | this.year = value; 38 | }) 39 | 40 | Button('调用云函数查询', { type: ButtonType.Capsule, stateEffect: true }) 41 | .margin({ top: '100px', bottom: '100px' }) 42 | .width('90%') 43 | .onClick(() => { 44 | this.callFunction(); 45 | }) 46 | 47 | Text("生肖: " + this.functionResult) 48 | .textAlign(TextAlign.Center) 49 | .fontSize(20) 50 | .padding(10) 51 | .width('90%') 52 | 53 | } 54 | .justifyContent(FlexAlign.Start) 55 | .margin({ 56 | top: 20 57 | }) 58 | .width('100%') 59 | .height('100%') 60 | } 61 | .title('云函数调用示例') 62 | } 63 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/ComponentFactoryExample.ets: -------------------------------------------------------------------------------- 1 | /// 组件工厂示例 2 | @Builder 3 | function UI1(text: string) { 4 | Text(text).fontColor(Color.Green) 5 | } 6 | 7 | @Builder 8 | function UI2(text: string) { 9 | Text(text).fontColor(Color.Blue) 10 | } 11 | 12 | let factoryMap: Map = new Map(); 13 | 14 | factoryMap.set('UI1', wrapBuilder(UI1)) 15 | factoryMap.set('UI2', wrapBuilder(UI2)) 16 | 17 | @Component 18 | struct TestComponentFactory { 19 | build() { 20 | Column({ space: 10 }) { 21 | (factoryMap.get('UI1') as WrappedBuilder<[string]>).builder('工厂组件 - 1'); 22 | (factoryMap.get('UI2') as WrappedBuilder<[string]>).builder('工厂组件 - 2'); 23 | } 24 | } 25 | } 26 | 27 | @Component 28 | export struct ComponentFactoryExample { 29 | build() { 30 | NavDestination() { 31 | Row() { 32 | Column() { 33 | TestComponentFactory() 34 | } 35 | .width('100%') 36 | .height('100%') 37 | .justifyContent(FlexAlign.Center) 38 | } 39 | .height('100%') 40 | .alignItems(VerticalAlign.Center) 41 | }.title('组件工厂示例') 42 | } 43 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/CustomDialogExample.ets: -------------------------------------------------------------------------------- 1 | import { CommonFillButton } from '@ohos/fast_ui/Index' 2 | import { CustomDialogContainer, DialogContainerController } from '../dialog/CustomDialogContainer' 3 | 4 | @Component 5 | export struct CustomDialogExample { 6 | @State callbackMessage: string = '' 7 | @State dialogController: DialogContainerController = new DialogContainerController( 8 | (message: string | undefined) => { 9 | // 这里接收到弹窗内确定按钮点击返回的数据 10 | if (message != undefined) { 11 | this.callbackMessage = message 12 | } 13 | } 14 | ) 15 | 16 | // 如果有多个样式的弹窗,定义多个 dialogController 然后统一在这里管理 17 | @Builder 18 | DialogControllerBuilder() { 19 | Column() { 20 | CustomDialogContainer({ 21 | controller: this.dialogController 22 | }) 23 | } 24 | } 25 | 26 | build() { 27 | NavDestination() { 28 | Column() { 29 | Text(this.callbackMessage) 30 | .textAlign(TextAlign.Center) 31 | .fontSize('18vp') 32 | .margin({ 33 | bottom: '20vp', 34 | }) 35 | this.DialogControllerBuilder() 36 | CommonFillButton({ 37 | text: '弹窗', 38 | horizontalPadding: '40vp', 39 | verticalPadding: '10vp', 40 | event: () => { 41 | this.dialogController.open() 42 | } 43 | }) 44 | } 45 | .height('100%') 46 | .width('100%') 47 | .justifyContent(FlexAlign.Center) 48 | }.title('自定义弹窗示例') 49 | } 50 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/EventBusExample.ets: -------------------------------------------------------------------------------- 1 | // EventBus 示例 2 | import { CommonFillButton } from '@ohos/fast_ui/Index' 3 | import { EventBus } from '@ohos/fast_util/Index' 4 | 5 | @Styles 6 | function SizeStyle() { 7 | .width('100%') 8 | .height('100%') 9 | } 10 | 11 | @Component 12 | export struct EventBusExample { 13 | build() { 14 | NavDestination() { 15 | Column() { 16 | PageA().height('50%') 17 | PageB().height('50%') 18 | } 19 | .SizeStyle() 20 | } 21 | .title('事件通知示例') 22 | } 23 | } 24 | 25 | @Component 26 | struct PageA { 27 | @State receivedData: string = '' 28 | 29 | aboutToAppear(): void { 30 | EventBus.listen('TestEventID', (data) => { 31 | if (data !== undefined) { 32 | this.receivedData = JSON.stringify(data) 33 | } 34 | }) 35 | } 36 | 37 | build() { 38 | Column({space: '15vp'}) { 39 | Text('PageA') 40 | Text(this.receivedData) 41 | } 42 | .justifyContent(FlexAlign.Center) 43 | .SizeStyle() 44 | } 45 | } 46 | 47 | @Component 48 | struct PageB { 49 | build() { 50 | Column({space: '15vp'}) { 51 | Text('PageB') 52 | CommonFillButton({ 53 | text: '发送消息给注册方', 54 | event: () => { 55 | let eventData: TestEventModule = { 56 | name: '李小轰', 57 | age: 123 58 | } 59 | EventBus.send('TestEventID', eventData) 60 | } 61 | }) 62 | } 63 | .justifyContent(FlexAlign.Center) 64 | .SizeStyle() 65 | .backgroundColor(Color.Yellow) 66 | } 67 | } 68 | 69 | // test: eventBus 发送和接收的数据模型 70 | interface TestEventModule { 71 | name: string, 72 | age: number, 73 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/FixFoldUiExample.ets: -------------------------------------------------------------------------------- 1 | import { FoldStatusContainer } from '@ohos/fast_ui' 2 | 3 | // 适配折叠屏 4 | @Component 5 | export struct FixFoldUiExample { 6 | 7 | @Builder 8 | unFoldUiContainer() { 9 | Stack() { 10 | Text('我是全屏内容').fontSize(20) 11 | } 12 | .width('100%') 13 | .height('100%') 14 | .backgroundColor(Color.Orange) 15 | } 16 | 17 | @Builder 18 | foldUiContainer() { 19 | Row() { 20 | Stack() { 21 | Text('我是左边的分屏内容').fontSize(20) 22 | } 23 | .backgroundColor(Color.Grey) 24 | .height('100%') 25 | .layoutWeight(1) 26 | 27 | Stack() { 28 | Text('我是右边的分屏内容').fontSize(20) 29 | } 30 | .backgroundColor(Color.Pink) 31 | .height('100%') 32 | .layoutWeight(1) 33 | } 34 | .width('100%') 35 | .height('100%') 36 | } 37 | 38 | @Builder 39 | bodyContainer() { 40 | FoldStatusContainer({ 41 | unFoldBodyContainer: this.unFoldUiContainer, 42 | foldBodyContainer: this.foldUiContainer, 43 | }) 44 | } 45 | 46 | build() { 47 | NavDestination() { 48 | Column() { 49 | this.bodyContainer() 50 | } 51 | .height('100%') 52 | .width('100%') 53 | .justifyContent(FlexAlign.Center) 54 | }.title('适配折叠屏') 55 | } 56 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/HttpRequestExample.ets: -------------------------------------------------------------------------------- 1 | /// 网络请求示例 2 | import { http } from '@kit.NetworkKit' 3 | import { HttpRequest } from '@rex/fast_https_request/Index'; 4 | import { CommonFillButton, CommonMainTitle, CommonSubTitle, FastLoadingDialog, FastToast } from '@ohos/fast_ui/Index' 5 | 6 | @Extend(Column) 7 | function ColumnStyle() { 8 | .width('100%') 9 | .height('100%') 10 | .borderRadius(24) 11 | .backgroundColor(Color.White) 12 | .padding('15vp') 13 | } 14 | 15 | @Entry 16 | @Component 17 | export struct HttpRequestExample { 18 | // 记录显示请求的返回结果 19 | @State responseTxt: string = '' 20 | request: GetRequest = new GetRequest(); 21 | loadingDialog = new CustomDialogController( 22 | { 23 | builder: FastLoadingDialog(), 24 | alignment: DialogAlignment.Center, 25 | customStyle: true, 26 | maskColor: Color.Transparent, 27 | } 28 | ) 29 | 30 | build() { 31 | NavDestination() { 32 | Column({ space: '5vp' }) { 33 | CommonMainTitle({ 34 | text: `请求类型:${this.request.method}` 35 | }) 36 | CommonMainTitle({ 37 | text: `请求域名:${this.request.domain}` 38 | }) 39 | CommonMainTitle({ 40 | text: `请求路径:${this.request.path}` 41 | }) 42 | CommonMainTitle({ 43 | text: `GET数据:${JSON.stringify(this.request.getQuery)}` 44 | }) 45 | Blank().height('15.vp') 46 | CommonFillButton({ 47 | text: '发送请求', 48 | event: () => { 49 | this.requestMock(new GetRequest()) 50 | } 51 | }) 52 | Blank().height('30.vp') 53 | CommonMainTitle({ 54 | text: `返回的请求结果:` 55 | }) 56 | Blank().height('15.vp') 57 | CommonSubTitle({ 58 | text: this.responseTxt, 59 | }) 60 | } 61 | .alignItems(HorizontalAlign.Start) 62 | .ColumnStyle() 63 | } 64 | .title('网络示例') 65 | .padding({ left: 12, right: 12, bottom: 4, top: 4 }) 66 | .backgroundColor($r('app.color.primary')) 67 | } 68 | 69 | // 发送网络请求 70 | async requestMock(request: HttpRequest): Promise { 71 | this.loadingDialog.open() 72 | try { 73 | const response = await request.execute() 74 | this.responseTxt = JSON.stringify(response); 75 | } catch (e) { 76 | let errorMessage = JSON.stringify(e); 77 | this.responseTxt = errorMessage; 78 | FastToast.shortToast(errorMessage) 79 | } finally { 80 | this.loadingDialog.close() 81 | } 82 | } 83 | } 84 | 85 | // HttpRequest 将response的返回数据直接转成指定的泛型 86 | class GetRequest extends HttpRequest> { 87 | // 重写请求类型,默认是 POST 88 | public method: http.RequestMethod = http.RequestMethod.GET; 89 | // 重写域名domain 90 | public domain: string = 'https://api.uomg123.com'; 91 | // 重写请求路径 92 | public path: string = '/api/rand.music'; 93 | // GET 传参赋值 94 | public getQuery: Record = { 95 | 'sort': '热歌榜', 96 | 'format': 'json', 97 | } 98 | } 99 | 100 | 101 | /// 接口返回结果通用模型 102 | interface CommonResponseModel { 103 | code: number 104 | data: T 105 | } 106 | 107 | /// 接口返回结果业务模型, 用于测试返回的 response 转 业务模型 108 | class ResponseModel { 109 | artistsname: string 110 | name: string 111 | picurl: string 112 | url: string 113 | 114 | constructor(artistsname: string, name: string, picurl: string, url: string) { 115 | this.artistsname = artistsname 116 | this.name = name 117 | this.picurl = picurl 118 | this.url = url 119 | } 120 | } 121 | 122 | -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/PermissionExample.ets: -------------------------------------------------------------------------------- 1 | // 简易授权示例 2 | import { CommonFillButton, FastToast } from '@ohos/fast_ui/Index' 3 | import { Permission } from '@ohos/fast_util/Index' 4 | import { common } from '@kit.AbilityKit' 5 | 6 | @Component 7 | export struct PermissionExample { 8 | @State count: number = 0 9 | 10 | @Builder 11 | testPermissionButton() { 12 | CommonFillButton({ 13 | text: '授权成功后+1', 14 | event: () => { 15 | this.onClickTap('rex') 16 | } 17 | }) 18 | } 19 | 20 | @Permission( 21 | getContext(this) as common.UIAbilityContext, 22 | ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'] 23 | ) 24 | onClickTap(name: string) { 25 | this.count++ 26 | } 27 | 28 | permissionErrorHandler() { 29 | FastToast.shortToast('请求权限失败') 30 | } 31 | 32 | build() { 33 | NavDestination() { 34 | Column({ space: '15vp' }) { 35 | Text(this.count.toString()) 36 | .fontSize('20vp') 37 | this.testPermissionButton() 38 | } 39 | .justifyContent(FlexAlign.Center) 40 | .width('100%') 41 | .height('100%') 42 | } 43 | .title('简易授权示例') 44 | } 45 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/RouterCallbackExample.ets: -------------------------------------------------------------------------------- 1 | import { FillFlexButton } from '@ohos/fast_ui/src/main/ets/styles/CommonButtonStyle'; 2 | import { FastRouter, RouterModel } from '@ohos/fast_util/Index'; 3 | import { PagePathConstants } from '@ohos/global_constant/Index'; 4 | 5 | /// 两种路由方式跳转HSP回调示例 6 | @Component 7 | export struct RouterCallbackExample { 8 | @Consume('navPathStack') navPathStack: NavPathStack; 9 | @State receiveData: string = '' 10 | params1: string = '112233' 11 | params2: string = '223344' 12 | 13 | // navPath 方式跳转 hsp 并获取回调, 对应页面为 -> TestHspNavPathPage 14 | navPathJumpHsp() { 15 | const routerParams: RouterModel = { 16 | params: this.params1, 17 | popCallback: (callbackValue) => { 18 | if (callbackValue !== undefined) { 19 | this.receiveData = callbackValue.toString() 20 | } 21 | } 22 | } 23 | this.navPathStack.pushPathByName('TestHspNavJumpCallback', routerParams) 24 | } 25 | 26 | // navPath 方式跳转 har 并获取回调, 对应页面为 -> TestHspNavPathPage 27 | navPathJumpHar() { 28 | const routerParams: RouterModel = { 29 | params: this.params1, 30 | popCallback: (callbackValue) => { 31 | if (callbackValue !== undefined) { 32 | this.receiveData = callbackValue.toString() 33 | } 34 | } 35 | } 36 | this.navPathStack.pushPathByName(PagePathConstants.PAGE_NAV_ROUTER_TEST, routerParams) 37 | } 38 | 39 | // router 跳转 hsp 并获取回调 40 | routerJump() { 41 | const routerParams: RouterModel = { 42 | url: '@bundle:com.atomicservice.5765880207855149405/feature_hsp_page/ets/pages/TestHspRoutePage', 43 | params: this.params2, 44 | popCallback: (callbackValue) => { 45 | if (callbackValue !== undefined) { 46 | this.receiveData = callbackValue.toString() 47 | } 48 | } 49 | } 50 | FastRouter.push(routerParams) 51 | } 52 | 53 | @Builder 54 | pageCallbackResult() { 55 | Text(this.receiveData) 56 | .fontSize('17vp') 57 | .fontColor(Color.Red) 58 | .height('20%') 59 | } 60 | 61 | @Builder 62 | navPathJumpItems() { 63 | Column() { 64 | Text('1.使用 NavPathStack 方式跳转') 65 | .fontWeight(FontWeight.Medium) 66 | .fontSize('20') 67 | .margin({ 68 | bottom: 5 69 | }) 70 | 71 | Text(`传递入参:${this.params1}`) 72 | .fontSize('15vp') 73 | .margin({ 74 | bottom: '10vp' 75 | }) 76 | 77 | jumpWidget( 78 | '跳转 har 页面并回调', 79 | this.params1, 80 | () => { 81 | this.navPathJumpHar() 82 | } 83 | ) 84 | 85 | jumpWidget( 86 | '跳转 hsp 页面并回调', 87 | this.params1, 88 | () => { 89 | this.navPathJumpHsp() 90 | } 91 | ) 92 | } 93 | .height('50%') 94 | } 95 | 96 | @Builder 97 | routeJumpItems() { 98 | Column() { 99 | Text('2.使用 Route 方式跳转') 100 | .fontWeight(FontWeight.Medium) 101 | .fontSize('20') 102 | .margin({ 103 | bottom: 5 104 | }) 105 | 106 | Text(`传递入参:${this.params2}`) 107 | .fontSize('15vp') 108 | .margin({ 109 | bottom: '10vp' 110 | }) 111 | 112 | jumpWidget( 113 | '跳转 hsp 页面并回调', 114 | this.params2, 115 | () => { 116 | this.routerJump() 117 | } 118 | ) 119 | } 120 | .height('30%') 121 | } 122 | 123 | build() { 124 | NavDestination() { 125 | Column() { 126 | this.pageCallbackResult() 127 | this.navPathJumpItems() 128 | this.routeJumpItems() 129 | } 130 | .height('100%') 131 | .width('100%') 132 | .justifyContent(FlexAlign.Center) 133 | } 134 | .title('页面跳转回调示例') 135 | } 136 | } 137 | 138 | @Builder 139 | function jumpWidget( 140 | jumpTitle: string, 141 | params: Object, 142 | jumpFunc: () => void, 143 | ) { 144 | Column() { 145 | Row() { 146 | FillFlexButton({ 147 | text: jumpTitle, 148 | verticalPadding: 10, 149 | event: () => { 150 | jumpFunc() 151 | } 152 | }) 153 | } 154 | .height(60) 155 | .width('80%') 156 | } 157 | .width('100%') 158 | .alignItems(HorizontalAlign.Center) 159 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/TestNavPathJumpPage.ets: -------------------------------------------------------------------------------- 1 | import { CommonFillButton } from '@ohos/fast_ui/src/main/ets/styles/CommonButtonStyle'; 2 | import { RouterModel } from '@ohos/fast_util/src/main/ets/FastRouter'; 3 | 4 | /// 测试 NavPathStack 跳转 Har 页面 5 | @Component 6 | export struct TestNavPathJumpPage { 7 | @Consume('navPathStack') navPathStack: NavPathStack; 8 | routerParams?: RouterModel 9 | @State receiveParams: string = '' 10 | @State resultData: string = '' 11 | 12 | aboutToAppear(): void { 13 | this.receiveParams = this.routerParams!.params!.toString() 14 | this.resultData = (Math.random() * 100).toFixed(0).toString() 15 | } 16 | 17 | build() { 18 | NavDestination() { 19 | Column({ space: '30vp' }) { 20 | Text(`页面模块及路径:feature_home(har) TestNavPathJumpPage.ets`).fontSize('12vp').fontColor(Color.Red) 21 | Text(`接收到的入参:${this.receiveParams}`).fontSize('15vp') 22 | Text(`页面随机数(用于测试回传): ${this.resultData}`).fontSize('18vp') 23 | CommonFillButton({ 24 | text: '关闭并返回结果', 25 | horizontalPadding: '40vp', 26 | verticalPadding: '10vp', 27 | event: () => { 28 | if (this.routerParams?.popCallback !== undefined) { 29 | this.routerParams.popCallback(`NavPathStack 回调结果:${this.resultData}`) 30 | } 31 | this.navPathStack.pop() 32 | } 33 | }) 34 | } 35 | .height('100%') 36 | .width('100%') 37 | .justifyContent(FlexAlign.Center) 38 | } 39 | .title('NavPath跳转Har页面') 40 | } 41 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/ets/pages/ThrottleExample.ets: -------------------------------------------------------------------------------- 1 | // 节流防抖 示例 2 | import { CommonFillButton } from '@ohos/fast_ui/Index' 3 | import { FastLog, Throttle } from '@ohos/fast_util/Index' 4 | 5 | @Component 6 | export struct ThrottleExample { 7 | @State count: number = 0 8 | 9 | @Builder 10 | testThrottleButton() { 11 | CommonFillButton({ 12 | text: '点击+1', 13 | event: () => { 14 | this.onClickTap('rex') 15 | } 16 | }) 17 | } 18 | 19 | @Throttle(2000) 20 | onClickTap(name: string) { 21 | FastLog.log(name) 22 | this.count++ 23 | } 24 | 25 | build() { 26 | NavDestination() { 27 | Column({ space: '15vp' }) { 28 | Text('设置节流时间为 2 秒') 29 | Text(this.count.toString()) 30 | .fontSize('20vp') 31 | this.testThrottleButton() 32 | } 33 | .justifyContent(FlexAlign.Center) 34 | .width('100%') 35 | .height('100%') 36 | } 37 | .title('节流防抖示例') 38 | } 39 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "feature_home", 4 | "type": "har", 5 | "deviceTypes": [ 6 | "default", 7 | "tablet" 8 | ], 9 | "requestPermissions": [ 10 | { 11 | "name": "ohos.permission.INTERNET" 12 | } 13 | ] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /business/feature_home/src/main/resources/base/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "font_color_shallow", 5 | "value": "#182431" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /business/feature_home/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | }, 7 | { 8 | "name": "common_example", 9 | "value": "常用示例" 10 | }, 11 | { 12 | "name": "http_example", 13 | "value": "网络请求示例" 14 | }, 15 | { 16 | "name": "event_bus_example", 17 | "value": "EventBus 事件通知示例" 18 | }, 19 | { 20 | "name": "custom_dialog_example", 21 | "value": "自定义弹窗示例" 22 | }, 23 | { 24 | "name": "router_callback_example", 25 | "value": "页面跳转回调示例(HAR、HSP)" 26 | }, 27 | { 28 | "name": "throttle_example", 29 | "value": "节流防抖示例" 30 | }, 31 | { 32 | "name": "permission_example", 33 | "value": "简易授权示例" 34 | }, 35 | { 36 | "name": "dynamic_router_example", 37 | "value": "测试动态路由" 38 | }, 39 | { 40 | "name": "dynamic_ui_node_example", 41 | "value": "UI动态节点示例" 42 | }, 43 | { 44 | "name": "fix_fold_ui_example", 45 | "value": "折叠屏适配" 46 | }, 47 | { 48 | "name": "component_factory_example", 49 | "value": "组件工厂示例" 50 | }, 51 | { 52 | "name": "attribute_modifier_example", 53 | "value": "组件动态属性设置示例" 54 | }, 55 | { 56 | "name": "cloud_function_example", 57 | "value": "云函数调用" 58 | }, 59 | { 60 | "name": "cloud_data_base_example", 61 | "value": "云数据库示例" 62 | } 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /business/feature_home/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /business/feature_home/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /business/feature_setting/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /business/feature_setting/BuildProfile.ets: -------------------------------------------------------------------------------- 1 | /** 2 | * Use these variables when you tailor your ArkTS code. They must be of the const type. 3 | */ 4 | export const HAR_VERSION = '1.0.0'; 5 | export const BUILD_MODE_NAME = 'debug'; 6 | export const DEBUG = true; 7 | export const TARGET_NAME = 'default'; 8 | 9 | /** 10 | * BuildProfile Class is used only for compatibility purposes. 11 | */ 12 | export default class BuildProfile { 13 | static readonly HAR_VERSION = HAR_VERSION; 14 | static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; 15 | static readonly DEBUG = DEBUG; 16 | static readonly TARGET_NAME = TARGET_NAME; 17 | } -------------------------------------------------------------------------------- /business/feature_setting/Index.ets: -------------------------------------------------------------------------------- 1 | import { PagePathConstants } from '@ohos/global_constant'; 2 | 3 | export { SettingPage } from './src/main/ets/pages/SettingPage' 4 | 5 | export function harInit(name: string): void { 6 | // 根据routerModule中路由表的key值动态加载要跳转的页面的相对路径 7 | switch (name) { 8 | case PagePathConstants.DYNAMIC_ROUTER_TEST: 9 | import("./src/main/ets/pages/TestDynamicNavPage"); 10 | break; 11 | default: 12 | break; 13 | } 14 | } -------------------------------------------------------------------------------- /business/feature_setting/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | }, 5 | "buildOptionSet": [ 6 | { 7 | "name": "release", 8 | "arkOptions": { 9 | "obfuscation": { 10 | "ruleOptions": { 11 | "enable": true, 12 | "files": [ 13 | "./obfuscation-rules.txt" 14 | ] 15 | }, 16 | "consumerFiles": [ 17 | "./consumer-rules.txt" 18 | ] 19 | } 20 | }, 21 | }, 22 | ], 23 | "targets": [ 24 | { 25 | "name": "default" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /business/feature_setting/consumer-rules.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/business/feature_setting/consumer-rules.txt -------------------------------------------------------------------------------- /business/feature_setting/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { harTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /business/feature_setting/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /business/feature_setting/oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "@ohos/fast_ui@../../base/fast_ui": "@ohos/fast_ui@../../base/fast_ui", 9 | "@ohos/fast_util@../../base/fast_util": "@ohos/fast_util@../../base/fast_util", 10 | "@ohos/global_constant@../../base/global_constant": "@ohos/global_constant@../../base/global_constant" 11 | }, 12 | "packages": { 13 | "@ohos/fast_ui@../../base/fast_ui": { 14 | "name": "fast_ui", 15 | "version": "1.0.0", 16 | "resolved": "../../base/fast_ui", 17 | "registryType": "local" 18 | }, 19 | "@ohos/fast_util@../../base/fast_util": { 20 | "name": "fast_util", 21 | "version": "1.0.0", 22 | "resolved": "../../base/fast_util", 23 | "registryType": "local" 24 | }, 25 | "@ohos/global_constant@../../base/global_constant": { 26 | "name": "global_constant", 27 | "version": "1.0.0", 28 | "resolved": "../../base/global_constant", 29 | "registryType": "local" 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /business/feature_setting/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "feature_setting", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "Index.ets", 6 | "author": "", 7 | "license": "Apache-2.0", 8 | "dependencies": { 9 | "@ohos/fast_ui": "file:../../base/fast_ui", 10 | "@ohos/fast_util": "file:../../base/fast_util", 11 | "@ohos/global_constant": "file:../../base/global_constant" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /business/feature_setting/src/main/ets/pages/SettingPage.ets: -------------------------------------------------------------------------------- 1 | import { QuickVerifyPhoneButton } from '../widget/QuickVerifyPhoneButton'; 2 | import { AccountQuickLoginButton } from '../widget/AccountQuickLoginButton'; 3 | import { LoginCallbackRes } from '../utils/LoginUtils'; 4 | 5 | @Component 6 | export struct SettingPage { 7 | build() { 8 | Column() { 9 | LoginPanel() 10 | } 11 | .width('100%') 12 | .height('100%') 13 | } 14 | } 15 | 16 | @Component 17 | struct LoginPanel { 18 | @State accountQuickLoginRes: LoginCallbackRes | undefined = undefined 19 | @State quickVerifyPhoneNumber: string | undefined = undefined 20 | 21 | build() { 22 | Column({ space: 30 }) { 23 | 24 | LoginInfoPanel({ 25 | accountQuickLoginRes: this.accountQuickLoginRes 26 | }) 27 | 28 | AccountQuickLoginButton({ 29 | context: getContext(this), 30 | onLoginCallback: (data) => { 31 | this.accountQuickLoginRes = data; 32 | } 33 | }) 34 | 35 | QuickVerifyPhoneButton((value) => { 36 | this.quickVerifyPhoneNumber = value; 37 | }) 38 | 39 | } 40 | .padding({ 41 | left: 16, 42 | right: 16 43 | }) 44 | .width('100%') 45 | .height('100%') 46 | } 47 | } 48 | 49 | @Component 50 | struct LoginInfoPanel { 51 | @Prop accountQuickLoginRes: LoginCallbackRes | undefined 52 | @Prop quickVerifyPhoneNumber: string | undefined 53 | 54 | build() { 55 | Column() { 56 | if (this.accountQuickLoginRes !== undefined) { 57 | Text('华为账号快速登录').fontSize(18).fontWeight(FontWeight.Bolder) 58 | Text(`获取到的 openID :`).infoLabelStyle() 59 | Text(this.accountQuickLoginRes.openID).infoTextStyle() 60 | Text(`获取到的 unionID :`).infoLabelStyle() 61 | Text(this.accountQuickLoginRes.unionID).infoTextStyle() 62 | } 63 | if (this.accountQuickLoginRes !== undefined && this.quickVerifyPhoneNumber !== undefined) { 64 | Divider().color(Color.Transparent).height(20) 65 | } 66 | if (this.quickVerifyPhoneNumber !== undefined) { 67 | Text('快速验证手机号').fontSize(18).fontWeight(FontWeight.Bolder).fontColor($r('app.color.primary')) 68 | Text(`获取到的 authorizationCode :`).infoLabelStyle($r('app.color.primary')) 69 | Text(this.quickVerifyPhoneNumber).infoTextStyle($r('app.color.primary')) 70 | } 71 | } 72 | .padding({ 73 | left: 20, 74 | top: 40 75 | }) 76 | .height('60%') 77 | .justifyContent(FlexAlign.Start) 78 | .alignItems(HorizontalAlign.Start) 79 | } 80 | } 81 | 82 | @Extend(Text) 83 | function infoLabelStyle( 84 | fontColor: Color | Resource = Color.Black 85 | ) { 86 | .fontSize(14) 87 | .fontColor(fontColor) 88 | .fontWeight(FontWeight.Bold) 89 | .margin({ 90 | top: 20 91 | }) 92 | } 93 | 94 | @Extend(Text) 95 | function infoTextStyle( 96 | fontColor: Color | Resource = Color.Black 97 | ) { 98 | .fontSize(11) 99 | .fontColor(fontColor) 100 | .fontWeight(FontWeight.Medium) 101 | .margin({ 102 | top: 10 103 | }) 104 | } 105 | 106 | -------------------------------------------------------------------------------- /business/feature_setting/src/main/ets/pages/TestDynamicNavPage.ets: -------------------------------------------------------------------------------- 1 | // 测试动态路由 2 | import { FastNavRouter } from '@ohos/fast_util'; 3 | import { PagePathConstants } from '@ohos/global_constant'; 4 | 5 | @Component 6 | export struct TestDynamicNavPage { 7 | params?: object 8 | 9 | build() { 10 | NavDestination() { 11 | Column({ space: '30vp' }) { 12 | Text('页面路径:TestDynamicNavPage').fontSize('18vp').fontWeight(FontWeight.Bold) 13 | Text(`${this.params}`).fontSize('12vp') 14 | } 15 | .justifyContent(FlexAlign.Center) 16 | .width('100%') 17 | .height('100%') 18 | } 19 | .title('动态路由目标页') 20 | } 21 | } 22 | 23 | @Builder 24 | export function TestDynamicNavPageBuilder(params: object) { 25 | TestDynamicNavPage({ 26 | params: params 27 | }) 28 | } 29 | 30 | // 在页面首次加载时触发执行 31 | const builderName: string = PagePathConstants.DYNAMIC_ROUTER_TEST; 32 | // 判断表中是否已存在路由信息,避免重复注册 33 | if (!FastNavRouter.getBuilder(builderName)) { 34 | // 通过系统提供的wrapBuilder接口封装@Builder装饰的方法 35 | let builder: WrappedBuilder<[object]> = wrapBuilder(TestDynamicNavPageBuilder); 36 | // 注册页面到全局路由表 37 | FastNavRouter.registerBuilder(builderName, builder); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /business/feature_setting/src/main/ets/utils/LoginUtils.ets: -------------------------------------------------------------------------------- 1 | import { common } from '@kit.AbilityKit' 2 | import { authentication } from '@kit.AccountKit' 3 | import util from '@ohos.util' 4 | import { FastToast } from '@ohos/fast_ui' 5 | 6 | // 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/account-phone-unionid-login-V5 7 | export abstract class LoginUtil { 8 | public static async login(context?: common.Context): Promise { 9 | let huaweiIdProvider = new authentication.HuaweiIDProvider() 10 | let loginRequest = huaweiIdProvider.createLoginWithHuaweiIDRequest() 11 | // 当用户未登录华为账号时,是否强制拉起华为账号登录界面 12 | loginRequest.forceLogin = true 13 | // 用于防跨站点请求伪造,推荐采用如下方式给state赋值 14 | loginRequest.state = util.generateRandomUUID(); 15 | let controller = new authentication.AuthenticationController(context) 16 | try { 17 | const data = await controller.executeRequest(loginRequest) 18 | let resp = data as authentication.LoginWithHuaweiIDResponse; 19 | if (resp.data === undefined) { 20 | return undefined; 21 | } 22 | let state: string = resp.state!; 23 | if (loginRequest.state != state) { 24 | FastToast.shortToast('login false: The state is different.') 25 | return undefined; 26 | } 27 | let loginWithHuaweiIDCredential: authentication.LoginWithHuaweiIDCredential = resp.data; 28 | let code: string = loginWithHuaweiIDCredential.authorizationCode!; 29 | let openID: string = loginWithHuaweiIDCredential.openID; 30 | let unionID: string = loginWithHuaweiIDCredential.unionID; 31 | let result: LoginCallbackRes = { 32 | code: code, 33 | openID: openID, 34 | unionID: unionID, 35 | }; 36 | return result; 37 | } catch (e) { 38 | FastToast.shortToast(`login false: ${e.code} - ${e.message}`) 39 | return undefined; 40 | } 41 | } 42 | } 43 | 44 | export interface LoginCallbackRes { 45 | code: string, 46 | openID: string, 47 | unionID: string, 48 | } -------------------------------------------------------------------------------- /business/feature_setting/src/main/ets/widget/AccountQuickLoginButton.ets: -------------------------------------------------------------------------------- 1 | /// 华为账号快速登录按钮 2 | import { LoginCallbackRes, LoginUtil } from '../utils/LoginUtils'; 3 | import common from '@ohos.app.ability.common'; 4 | 5 | @Builder 6 | export function AccountQuickLoginButton(callback: AccountQuickLoginCallback) { 7 | Button() { 8 | Text('华为账号快速登录') 9 | .fontColor('#FFFFFF') 10 | .fontSize(14) 11 | .fontWeight(FontWeight.Bold) 12 | .fontStyle(FontStyle.Normal) 13 | } 14 | .backgroundColor(Color.Black) 15 | .type(ButtonType.Capsule) 16 | .width('80%') 17 | .height(44) 18 | .onClick(() => { 19 | LoginUtil.login(callback.context).then((data) => { 20 | if (data !== undefined) { 21 | // 获取成功 22 | callback.onLoginCallback(data); 23 | } 24 | }) 25 | }) 26 | } 27 | 28 | export interface AccountQuickLoginCallback { 29 | context: common.Context 30 | onLoginCallback: (data: LoginCallbackRes) => void 31 | } -------------------------------------------------------------------------------- /business/feature_setting/src/main/ets/widget/QuickVerifyPhoneButton.ets: -------------------------------------------------------------------------------- 1 | import { FunctionalButton, functionalButtonComponentManager } from '@kit.ScenarioFusionKit' 2 | import { FastToast } from '@ohos/fast_ui' 3 | 4 | export type QuickVerifyPhoneCallback = (value: string) => void 5 | 6 | /// 快速验证手机号按钮 7 | @Builder 8 | export function QuickVerifyPhoneButton(callback: QuickVerifyPhoneCallback) { 9 | FunctionalButton( 10 | { 11 | params: { 12 | openType: functionalButtonComponentManager.OpenType.GET_PHONE_NUMBER, 13 | label: '快速验证手机号', 14 | styleOption: { 15 | styleConfig: new functionalButtonComponentManager.ButtonConfig() 16 | .type(ButtonType.Normal) 17 | .backgroundColor($r('app.color.secondary')) 18 | .width('80%') 19 | .height(44) 20 | .borderRadius(22) 21 | .fontColor($r('app.color.primary')) 22 | .fontSize(14) 23 | .fontWeight(FontWeight.Bold) 24 | .padding(0) 25 | .borderWidth(0) 26 | } 27 | }, 28 | controller: new functionalButtonComponentManager.FunctionalButtonController() 29 | .onGetPhoneNumber( 30 | async (err, data) => { 31 | if (err !== undefined) { 32 | FastToast.shortToast(`login false: ${err.code} - ${err.message}`) 33 | } else { 34 | // authorizationCode 是手机号的加密字符串,后端通过调用华为服务可解析出手机号的明文 35 | // 参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/account-phone-unionid-login-V5#section286103315177 36 | let authorizationCode = data.code 37 | if (authorizationCode !== undefined) { 38 | callback(authorizationCode) 39 | } 40 | } 41 | } 42 | ) 43 | } 44 | ) 45 | } -------------------------------------------------------------------------------- /business/feature_setting/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "feature_setting", 4 | "type": "har", 5 | "deviceTypes": [ 6 | "default", 7 | "tablet" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /business/feature_setting/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /business/feature_setting/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /business/feature_setting/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "page_show", 5 | "value": "page from package" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /certificate/debug/codeLab-Debug.cer: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC 3 | Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE 4 | AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx 5 | NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE 6 | CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw 7 | EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs 8 | GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB 9 | wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T 10 | AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI 11 | zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn 12 | BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h 13 | FTjgDHctXJlC5L7+ZDY= 14 | -----END CERTIFICATE----- 15 | -----BEGIN CERTIFICATE----- 16 | MIIDATCCAoigAwIBAgIIXmuDXbWpOB8wCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC 17 | Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE 18 | AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDcwOTAyMDQyNFoXDTMwMDcw 19 | NzAyMDQyNFowYjELMAkGA1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE 20 | CwwKSHVhd2VpIENCRzEtMCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVs 21 | YXRpb25zIENBIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE65LdoIZh1hlpZ2gP 22 | bJ6gPhHsvYSRe22KETgdqeVeYnrbRHI9wsPT6RGYS+pU4mPl6wxzgDMqN6SY/BoZ 23 | luhkE1PzaHoPoNIWIq0O33hpyKyyYwAacIUEjYurkw1E9r9no4IBGDCCARQwHwYD 24 | VR0jBBgwFoAUo45a9Vq8cYwqaiVyfkiS4pLcIAAwHQYDVR0OBBYEFNtek7Ij6NDk 25 | /nF6Zumkc0dbf/NeMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEGCCsGAQUFBwIBFiVo 26 | dHRwOi8vY3BraS1jYXdlYi5odWF3ZWkuY29tL2Nwa2kvY3BzMBIGA1UdEwEB/wQI 27 | MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMGYGA1UdHwRfMF0wW6BZoFeGVWh0dHA6 28 | Ly9jcGtpLWNhd2ViLmh1YXdlaS5jb20vY3BraS9zZXJ2bGV0L2NybEZpbGVEb3du 29 | LmNybD9jZXJ0eXBlPTEwJi9yb290X2cyX2NybC5jcmwwCgYIKoZIzj0EAwMDZwAw 30 | ZAIwWO1X5q2MdfpR1Q237GpUHGbL1C13rGyFg2p3AYo44FpZ2/A9ss0wOHKM4KDl 31 | ZPqdAjBLkf8NPZy7KVog98+iCTLq35DJ2ZVxkCxknA9YhiHVyXf4HPm4JlT7rW7o 32 | Q+FzM3c= 33 | -----END CERTIFICATE----- 34 | -----BEGIN CERTIFICATE----- 35 | MIICxjCCAkugAwIBAgIOY8uBrzpieaE9RJT8c7swCgYIKoZIzj0EAwMwYjELMAkG 36 | A1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEt 37 | MCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVsYXRpb25zIENBIEcyMB4X 38 | DTI0MDgyMDAzMTU1OVoXDTI1MDgyMDAzMTU1OVowdTELMAkGA1UEBhMCQ04xEjAQ 39 | BgNVBAoMCeadjuWuh+WzsDEcMBoGA1UECwwTMTI5NjQzMzI4NzI0OTU4Mjg0OTE0 40 | MDIGA1UEAwwr5p2O5a6H5bOwKDEyOTY0MzMyODcyNDk1ODI4NDkpXCxEZXZlbG9w 41 | bWVudDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOSfQ5d80hlj+2KzwD5Ga2Wz 42 | VCNZnA5lVYQG3H/caE7HGxDqMnQwXc3EFIoio/s2MSEfmh+VP7GimN5KVwh7Z+Wj 43 | gdEwgc4wDAYDVR0TAQH/BAIwADBZBgNVHR8EUjBQME6gTKBKhkhodHRwOi8vaDVo 44 | b3N0aW5nLWRyY24uZGJhbmtjZG4uY24vY2NoNS9jcmwvaGRyY2FnMi9IdWF3ZWlD 45 | QkdIRFJHMmNybC5jcmwwHwYDVR0jBBgwFoAU216TsiPo0OT+cXpm6aRzR1t/814w 46 | HQYDVR0OBBYEFHbMfPLyMssO1S6lApwoAJbFDrRoMA4GA1UdDwEB/wQEAwIHgDAT 47 | BgNVHSUEDDAKBggrBgEFBQcDAzAKBggqhkjOPQQDAwNpADBmAjEA6cyEMtNOiiW8 48 | g2HLUZhGrt5dPqn6xgORnBe7xE1eZunJ+Gd9I4NojyWv8nehkbfpAjEAqgQ/nK9f 49 | vnVq84LvAgSce9IBciSi7TcsxmlRTnH3OEe1PHlTAq02XZaTHfhFyNG2 50 | -----END CERTIFICATE----- 51 | -------------------------------------------------------------------------------- /certificate/debug/codeLab-DebugDebug.p7b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/codeLab-DebugDebug.p7b -------------------------------------------------------------------------------- /certificate/debug/codeLab.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN NEW CERTIFICATE REQUEST----- 2 | MIIBNDCB2wIBADBJMQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkw 3 | BwYDVQQKEwAxCTAHBgNVBAsTADEQMA4GA1UEAxMHY29kZWxhYjBZMBMGByqGSM49 4 | AgEGCCqGSM49AwEHA0IABOSfQ5d80hlj+2KzwD5Ga2WzVCNZnA5lVYQG3H/caE7H 5 | GxDqMnQwXc3EFIoio/s2MSEfmh+VP7GimN5KVwh7Z+WgMDAuBgkqhkiG9w0BCQ4x 6 | ITAfMB0GA1UdDgQWBBR2zHzy8jLLDtUupQKcKACWxQ60aDAKBggqhkjOPQQDAgNI 7 | ADBFAiEA6oyFjXzTRt2ucSLaObBraFHMjTm4AylQSo0XtLn0BSoCIA6UjFUeQxPm 8 | hOLS7i8Qk7HC8A2qSBbE025yJ9ZgF42v 9 | -----END NEW CERTIFICATE REQUEST----- 10 | -------------------------------------------------------------------------------- /certificate/debug/code_lab.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/code_lab.p12 -------------------------------------------------------------------------------- /certificate/debug/material/ac/98d170fbd9c64931ae1251a4ef7ad9b9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/material/ac/98d170fbd9c64931ae1251a4ef7ad9b9 -------------------------------------------------------------------------------- /certificate/debug/material/ce/d02c2145e7a044529b5c2afc8c34e4b8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/material/ce/d02c2145e7a044529b5c2afc8c34e4b8 -------------------------------------------------------------------------------- /certificate/debug/material/fd/0/0bf6a1d2cc754daab6e81da1adc21ac4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/material/fd/0/0bf6a1d2cc754daab6e81da1adc21ac4 -------------------------------------------------------------------------------- /certificate/debug/material/fd/1/011c3f245f584ee38b45718d70fc6d72: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/material/fd/1/011c3f245f584ee38b45718d70fc6d72 -------------------------------------------------------------------------------- /certificate/debug/material/fd/2/7cf2883100094a19a63fea5ec47172ff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/material/fd/2/7cf2883100094a19a63fea5ec47172ff -------------------------------------------------------------------------------- /certificate/debug/rex_code_lab_debug.cer: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC 3 | Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE 4 | AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx 5 | NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE 6 | CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw 7 | EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs 8 | GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB 9 | wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T 10 | AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI 11 | zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn 12 | BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h 13 | FTjgDHctXJlC5L7+ZDY= 14 | -----END CERTIFICATE----- 15 | -----BEGIN CERTIFICATE----- 16 | MIIDATCCAoigAwIBAgIIXmuDXbWpOB8wCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC 17 | Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE 18 | AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDcwOTAyMDQyNFoXDTMwMDcw 19 | NzAyMDQyNFowYjELMAkGA1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE 20 | CwwKSHVhd2VpIENCRzEtMCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVs 21 | YXRpb25zIENBIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE65LdoIZh1hlpZ2gP 22 | bJ6gPhHsvYSRe22KETgdqeVeYnrbRHI9wsPT6RGYS+pU4mPl6wxzgDMqN6SY/BoZ 23 | luhkE1PzaHoPoNIWIq0O33hpyKyyYwAacIUEjYurkw1E9r9no4IBGDCCARQwHwYD 24 | VR0jBBgwFoAUo45a9Vq8cYwqaiVyfkiS4pLcIAAwHQYDVR0OBBYEFNtek7Ij6NDk 25 | /nF6Zumkc0dbf/NeMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEGCCsGAQUFBwIBFiVo 26 | dHRwOi8vY3BraS1jYXdlYi5odWF3ZWkuY29tL2Nwa2kvY3BzMBIGA1UdEwEB/wQI 27 | MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMGYGA1UdHwRfMF0wW6BZoFeGVWh0dHA6 28 | Ly9jcGtpLWNhd2ViLmh1YXdlaS5jb20vY3BraS9zZXJ2bGV0L2NybEZpbGVEb3du 29 | LmNybD9jZXJ0eXBlPTEwJi9yb290X2cyX2NybC5jcmwwCgYIKoZIzj0EAwMDZwAw 30 | ZAIwWO1X5q2MdfpR1Q237GpUHGbL1C13rGyFg2p3AYo44FpZ2/A9ss0wOHKM4KDl 31 | ZPqdAjBLkf8NPZy7KVog98+iCTLq35DJ2ZVxkCxknA9YhiHVyXf4HPm4JlT7rW7o 32 | Q+FzM3c= 33 | -----END CERTIFICATE----- 34 | -----BEGIN CERTIFICATE----- 35 | MIICxTCCAkugAwIBAgIOY8wB+0HANQa1LM0bGcEwCgYIKoZIzj0EAwMwYjELMAkG 36 | A1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEt 37 | MCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVsYXRpb25zIENBIEcyMB4X 38 | DTI0MTIxNzA5MTUwM1oXDTI1MTIxNzA5MTUwM1owdTELMAkGA1UEBhMCQ04xEjAQ 39 | BgNVBAoMCeadjuWuh+WzsDEcMBoGA1UECwwTMTI5NjQzMzI4NzI0OTU4Mjg0OTE0 40 | MDIGA1UEAwwr5p2O5a6H5bOwKDEyOTY0MzMyODcyNDk1ODI4NDkpXCxEZXZlbG9w 41 | bWVudDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENbsBeaf/l6M9T//JWHJDn/ 42 | PzFQ3RWrH10ondPTYZxa0+Jg0kQXOQQPVgA7BmFFhXs98JsEaAY5oO1jgBO2PNqj 43 | gdEwgc4wHQYDVR0OBBYEFPUfObCYG4mw3CAsOqbGcd5+UieSMAwGA1UdEwEB/wQC 44 | MAAwHwYDVR0jBBgwFoAU216TsiPo0OT+cXpm6aRzR1t/814wWQYDVR0fBFIwUDBO 45 | oEygSoZIaHR0cDovL2g1aG9zdGluZy1kcmNuLmRiYW5rY2RuLmNuL2NjaDUvY3Js 46 | L2hkcmNhZzIvSHVhd2VpQ0JHSERSRzJjcmwuY3JsMA4GA1UdDwEB/wQEAwIHgDAT 47 | BgNVHSUEDDAKBggrBgEFBQcDAzAKBggqhkjOPQQDAwNoADBlAjEAomGrjcvRl88R 48 | CpvO/jgCh9qQzgPvpkPBlwEa3wIxEj8QxX/s0fw6CBHKFidycikJAjBezXc4ctnr 49 | wy4KGXXrkeTR6fLjV0u/YixzusPm48ZIumSxqHk7i0J+eSiTkGvcY1k= 50 | -----END CERTIFICATE----- 51 | -------------------------------------------------------------------------------- /certificate/debug/rex_code_lab_debug.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN NEW CERTIFICATE REQUEST----- 2 | MIIBNDCB3AIBADBKMQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkw 3 | BwYDVQQKEwAxCTAHBgNVBAsTADERMA8GA1UEAwwIY29kZV9sYWIwWTATBgcqhkjO 4 | PQIBBggqhkjOPQMBBwNCAARDW7AXmn/5ejPU//yVhyQ5/z8xUN0Vqx9dKJ3T02Gc 5 | WtPiYNJEFzkED1YAOwZhRYV7PfCbBGgGOaDtY4ATtjzaoDAwLgYJKoZIhvcNAQkO 6 | MSEwHzAdBgNVHQ4EFgQU9R85sJgbibDcICw6psZx3n5SJ5IwCgYIKoZIzj0EAwID 7 | RwAwRAIgapgga/b2UPK1KHsxjvxtw86JUwWWZgdzvFe2abo607ECIHSHVBUWntpX 8 | ZNnxH4fBdrXQTEvdfIeF0kKHyUquayed 9 | -----END NEW CERTIFICATE REQUEST----- 10 | -------------------------------------------------------------------------------- /certificate/debug/rex_code_lab_debug.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/rex_code_lab_debug.p12 -------------------------------------------------------------------------------- /certificate/debug/rex_code_lab_debugDebug.p7b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/certificate/debug/rex_code_lab_debugDebug.p7b -------------------------------------------------------------------------------- /entry/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /entry/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | "arkOptions": { 5 | "runtimeOnly": { 6 | "packages": [ 7 | "@ohos/feature_setting" // 测试动态路由,仅用于使用变量动态import其他模块名场景,静态import或常量动态import无需配置。 8 | ] 9 | } 10 | } 11 | }, 12 | "buildOptionSet": [ 13 | { 14 | "name": "release", 15 | "arkOptions": { 16 | "obfuscation": { 17 | "ruleOptions": { 18 | "enable": true, 19 | "files": [ 20 | "./obfuscation-rules.txt" 21 | ] 22 | } 23 | } 24 | } 25 | }, 26 | ], 27 | "targets": [ 28 | { 29 | "name": "default" 30 | }, 31 | { 32 | "name": "ohosTest", 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /entry/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { hapTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /entry/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /entry/oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "@hw-agconnect/api-ohos@^1.1.2": "@hw-agconnect/api-ohos@1.1.2", 9 | "@hw-agconnect/auth-ohos@^1.1.3": "@hw-agconnect/auth-ohos@1.1.3", 10 | "@hw-agconnect/base-ohos@^1.1.2": "@hw-agconnect/base-ohos@1.1.2", 11 | "@hw-agconnect/core-ohos@^1.1.2": "@hw-agconnect/core-ohos@1.1.3", 12 | "@hw-agconnect/core-ohos@^1.1.3": "@hw-agconnect/core-ohos@1.1.3", 13 | "@hw-agconnect/credential-ohos@^1.1.2": "@hw-agconnect/credential-ohos@1.1.3", 14 | "@hw-agconnect/credential-ohos@^1.1.3": "@hw-agconnect/credential-ohos@1.1.3", 15 | "@hw-agconnect/crypto-ohos@^1.1.2": "@hw-agconnect/crypto-ohos@1.1.2", 16 | "@hw-agconnect/function-ohos@^1.1.2": "@hw-agconnect/function-ohos@1.1.3", 17 | "@ohos/fast_ui@../base/fast_ui": "@ohos/fast_ui@../base/fast_ui", 18 | "@ohos/fast_util@../base/fast_util": "@ohos/fast_util@../base/fast_util", 19 | "@ohos/feature_home@../business/feature_home": "@ohos/feature_home@../business/feature_home", 20 | "@ohos/feature_setting@../business/feature_setting": "@ohos/feature_setting@../business/feature_setting", 21 | "@ohos/global_constant@../base/global_constant": "@ohos/global_constant@../base/global_constant", 22 | "@rex/fast_https_request@1.0.1": "@rex/fast_https_request@1.0.1", 23 | "bignumber.js@9.0.1": "bignumber.js@9.0.1" 24 | }, 25 | "packages": { 26 | "@hw-agconnect/api-ohos@1.1.2": { 27 | "name": "@hw-agconnect/api-ohos", 28 | "version": "1.1.2", 29 | "integrity": "sha512-3WVG+YLkXY0wisdskylIgE94rcK7Oo33muoNHcE7UtMwxDWM9vtf5pV9yyWZiQZct8x+Z1JR1u5xRUzVZ0HE3A==", 30 | "resolved": "https://repo.harmonyos.com/ohpm/@hw-agconnect/api-ohos/-/api-ohos-1.1.2.har", 31 | "registryType": "ohpm" 32 | }, 33 | "@hw-agconnect/auth-ohos@1.1.3": { 34 | "name": "@hw-agconnect/auth-ohos", 35 | "version": "1.1.3", 36 | "integrity": "sha512-TIJ96sYK1U3wh/BfIjENCGmMt2HIKmBUsaIMemZ1GA7kYpHGu+PEQup+szPmtd0Wz4YOfE4bemXX8dEgoZRlLw==", 37 | "resolved": "https://repo.harmonyos.com/ohpm/@hw-agconnect/auth-ohos/-/auth-ohos-1.1.3.har", 38 | "registryType": "ohpm", 39 | "dependencies": { 40 | "@hw-agconnect/api-ohos": "^1.1.2", 41 | "@hw-agconnect/base-ohos": "^1.1.2", 42 | "@hw-agconnect/credential-ohos": "^1.1.3" 43 | } 44 | }, 45 | "@hw-agconnect/base-ohos@1.1.2": { 46 | "name": "@hw-agconnect/base-ohos", 47 | "version": "1.1.2", 48 | "integrity": "sha512-rBHuByq1icoagEa1ME+LPJOoYXPywvmNLVUHSVmtbkjQgCfsJmBhbtSmqrSggInBpwbB4969GF2UZ7fpJhgr6w==", 49 | "resolved": "https://repo.harmonyos.com/ohpm/@hw-agconnect/base-ohos/-/base-ohos-1.1.2.har", 50 | "registryType": "ohpm", 51 | "dependencies": { 52 | "@hw-agconnect/crypto-ohos": "^1.1.2" 53 | } 54 | }, 55 | "@hw-agconnect/core-ohos@1.1.3": { 56 | "name": "@hw-agconnect/core-ohos", 57 | "version": "1.1.3", 58 | "integrity": "sha512-49b6lS5KBpjxUdq6p6dE6uzGoMqe3UAVFdPmtv7mdHGbQUAhqeNiA/9mIidrxdVZSgStGxfaY/8KeA2EJQ3aWw==", 59 | "resolved": "https://repo.harmonyos.com/ohpm/@hw-agconnect/core-ohos/-/core-ohos-1.1.3.har", 60 | "registryType": "ohpm", 61 | "dependencies": { 62 | "@hw-agconnect/api-ohos": "^1.1.2", 63 | "@hw-agconnect/base-ohos": "^1.1.2" 64 | } 65 | }, 66 | "@hw-agconnect/credential-ohos@1.1.3": { 67 | "name": "@hw-agconnect/credential-ohos", 68 | "version": "1.1.3", 69 | "integrity": "sha512-qo80Bq7Q83KQ8mRiS/tCaNK/g6gwZumvDXHF81mGOyDdzI7w9uTplDAFGUuj8vDi+K8bMMLIfsID6klb714/ag==", 70 | "resolved": "https://repo.harmonyos.com/ohpm/@hw-agconnect/credential-ohos/-/credential-ohos-1.1.3.har", 71 | "registryType": "ohpm", 72 | "dependencies": { 73 | "@hw-agconnect/api-ohos": "^1.1.2", 74 | "@hw-agconnect/core-ohos": "^1.1.3", 75 | "@hw-agconnect/base-ohos": "^1.1.2" 76 | } 77 | }, 78 | "@hw-agconnect/crypto-ohos@1.1.2": { 79 | "name": "@hw-agconnect/crypto-ohos", 80 | "version": "1.1.2", 81 | "integrity": "sha512-yLrv7Kit+swgTbbkgPrTLT3iI6Vhw4oae6K59jOmTSBztwTd9qkEo9Krp11S8SoKn3vy5+9bURMAPxP5DwwcZA==", 82 | "resolved": "https://repo.harmonyos.com/ohpm/@hw-agconnect/crypto-ohos/-/crypto-ohos-1.1.2.har", 83 | "registryType": "ohpm" 84 | }, 85 | "@hw-agconnect/function-ohos@1.1.3": { 86 | "name": "@hw-agconnect/function-ohos", 87 | "version": "1.1.3", 88 | "integrity": "sha512-7WnmycdRg8j+TId3s72JnD/E5omqdCVJaXAuLPVW5YAw/hxVVNjGcHfncx4ulL/DO9nMBvkSXjnxVDu/RmSgPw==", 89 | "resolved": "https://repo.harmonyos.com/ohpm/@hw-agconnect/function-ohos/-/function-ohos-1.1.3.har", 90 | "registryType": "ohpm", 91 | "dependencies": { 92 | "@hw-agconnect/api-ohos": "^1.1.2", 93 | "@hw-agconnect/base-ohos": "^1.1.2", 94 | "@hw-agconnect/auth-ohos": "^1.1.3", 95 | "bignumber.js": "9.0.1" 96 | } 97 | }, 98 | "@ohos/fast_ui@../base/fast_ui": { 99 | "name": "fast_ui", 100 | "version": "1.0.0", 101 | "resolved": "../base/fast_ui", 102 | "registryType": "local" 103 | }, 104 | "@ohos/fast_util@../base/fast_util": { 105 | "name": "fast_util", 106 | "version": "1.0.0", 107 | "resolved": "../base/fast_util", 108 | "registryType": "local" 109 | }, 110 | "@ohos/feature_home@../business/feature_home": { 111 | "name": "feature_home", 112 | "version": "1.0.0", 113 | "resolved": "../business/feature_home", 114 | "registryType": "local", 115 | "dependencies": { 116 | "@ohos/fast_ui": "file:../../base/fast_ui", 117 | "@ohos/fast_util": "file:../../base/fast_util", 118 | "@rex/fast_https_request": "1.0.1", 119 | "@ohos/global_constant": "file:../../base/global_constant" 120 | } 121 | }, 122 | "@ohos/feature_setting@../business/feature_setting": { 123 | "name": "feature_setting", 124 | "version": "1.0.0", 125 | "resolved": "../business/feature_setting", 126 | "registryType": "local", 127 | "dependencies": { 128 | "@ohos/fast_ui": "file:../../base/fast_ui", 129 | "@ohos/fast_util": "file:../../base/fast_util", 130 | "@ohos/global_constant": "file:../../base/global_constant" 131 | } 132 | }, 133 | "@ohos/global_constant@../base/global_constant": { 134 | "name": "global_constant", 135 | "version": "1.0.0", 136 | "resolved": "../base/global_constant", 137 | "registryType": "local" 138 | }, 139 | "@rex/fast_https_request@1.0.1": { 140 | "name": "@rex/fast_https_request", 141 | "version": "1.0.1", 142 | "integrity": "sha512-qFj8anVCIvuK5XeEsPz0OLpOiMu/q115j3e9EKwizWcv5mIuSTJ3srXH9wh1wepA4zSmsZcOl8nyaPtyyaR34A==", 143 | "resolved": "https://repo.harmonyos.com/ohpm/@rex/fast_https_request/-/fast_https_request-1.0.1.har", 144 | "registryType": "ohpm" 145 | }, 146 | "bignumber.js@9.0.1": { 147 | "name": "bignumber.js", 148 | "version": "9.0.1", 149 | "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", 150 | "resolved": "https://repo.harmonyos.com/ohpm/bignumber.js/-/bignumber.js-9.0.1.tgz", 151 | "shasum": "8d7ba124c882bfd8e43260c67475518d0689e4e5", 152 | "registryType": "ohpm" 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /entry/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "entry", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "", 6 | "author": "", 7 | "license": "", 8 | "dependencies": { 9 | "@ohos/fast_ui": "file:../base/fast_ui", 10 | "@ohos/fast_util": "file:../base/fast_util", 11 | "@ohos/global_constant": "file:../base/global_constant", 12 | "@ohos/feature_home": "file:../business/feature_home", 13 | "@ohos/feature_setting": "file:../business/feature_setting", 14 | // 云函数依赖 15 | "@hw-agconnect/api-ohos": "^1.1.2", 16 | "@hw-agconnect/core-ohos": "^1.1.2", 17 | "@hw-agconnect/function-ohos": "^1.1.2", 18 | "@hw-agconnect/credential-ohos": "^1.1.2", 19 | "@hw-agconnect/base-ohos": "^1.1.2" 20 | }, 21 | } 22 | 23 | -------------------------------------------------------------------------------- /entry/src/main/ets/entryability/EntryAbility.ets: -------------------------------------------------------------------------------- 1 | import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 2 | import { hilog } from '@kit.PerformanceAnalysisKit'; 3 | import { window } from '@kit.ArkUI'; 4 | 5 | export default class EntryAbility extends UIAbility { 6 | onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 7 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 8 | AppStorage.setOrCreate('foldStatusKey', false) 9 | } 10 | 11 | onDestroy(): void { 12 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); 13 | } 14 | 15 | onWindowStageCreate(windowStage: window.WindowStage): void { 16 | // Main window is created, set main page for this ability 17 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); 18 | windowStage.loadContent('pages/MainPage', (err) => { 19 | if (err.code) { 20 | hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 21 | return; 22 | } 23 | hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); 24 | }); 25 | } 26 | 27 | onWindowStageDestroy(): void { 28 | // Main window is destroyed, release UI related resources 29 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); 30 | } 31 | 32 | onForeground(): void { 33 | // Ability has brought to foreground 34 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); 35 | } 36 | 37 | onBackground(): void { 38 | // Ability has back to background 39 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /entry/src/main/ets/entryability/FoldStatusObserver.ets: -------------------------------------------------------------------------------- 1 | import mediaquery from '@ohos.mediaquery' 2 | 3 | /// 折叠屏幕变化监听 4 | abstract class FoldStatusObserver { 5 | public static readonly foldStatusKey = 'foldStatusKey' 6 | private static listener?: mediaquery.MediaQueryListener 7 | 8 | /// 在 MainPage aboutToAppear 生命周期内调用 9 | public static startListening() { 10 | FoldStatusObserver.listener = mediaquery.matchMediaSync('screen and (min-width: 400vp)') 11 | FoldStatusObserver.listener.on('change', FoldStatusObserver.onFoldStatusChange) 12 | } 13 | 14 | /// 在 MainPage aboutToDisappear 生命周期内调用 15 | public static stopListening() { 16 | FoldStatusObserver.listener?.off('change', FoldStatusObserver.onFoldStatusChange) 17 | } 18 | 19 | /// 在任意 Component 内通过使用 `@StorageProp('foldStatusKey') isFold: boolean = false` 进行监听变化 20 | private static onFoldStatusChange(result: mediaquery.MediaQueryResult): void { 21 | const status = AppStorage.get(FoldStatusObserver.foldStatusKey) 22 | if (result.matches !== status) { 23 | AppStorage.set(FoldStatusObserver.foldStatusKey, result.matches) 24 | } 25 | } 26 | } 27 | 28 | export { FoldStatusObserver } -------------------------------------------------------------------------------- /entry/src/main/ets/pages/MainPage.ets: -------------------------------------------------------------------------------- 1 | import { FastNavRouter, RouterModel } from '@ohos/fast_util/Index' 2 | import { 3 | AttributeModifierExample, 4 | BuilderNodeExample, 5 | CloudDatabaseExample, 6 | CloudFuncExample, 7 | ComponentFactoryExample, 8 | CustomDialogExample, 9 | EventBusExample, 10 | FixFoldUiExample, 11 | HomePage, 12 | HttpRequestExample, 13 | PermissionExample, 14 | RouterCallbackExample, 15 | TestNavPathJumpPage, 16 | ThrottleExample 17 | } from '@ohos/feature_home/Index' 18 | import { SettingPage } from '@ohos/feature_setting' 19 | import { PagePathConstants } from '@ohos/global_constant/Index' 20 | import { FoldStatusObserver } from '../entryability/FoldStatusObserver' 21 | 22 | enum TabItemEnum { 23 | home = '首页', 24 | setting = '设置', 25 | } 26 | 27 | interface HomeTabItem { 28 | type: TabItemEnum 29 | img: Resource 30 | selectImg: Resource 31 | } 32 | 33 | const homeTabs: HomeTabItem[] = [ 34 | { 35 | type: TabItemEnum.home, 36 | img: $r('app.media.ic_home_normal'), 37 | selectImg: $r('app.media.ic_home_select'), 38 | }, 39 | { 40 | type: TabItemEnum.setting, 41 | img: $r('app.media.ic_mine_normal'), 42 | selectImg: $r('app.media.ic_mine_select'), 43 | }, 44 | ] 45 | 46 | @Extend(Navigation) 47 | function appStyle() { 48 | .hideTitleBar(true) 49 | } 50 | 51 | @Extend(Image) 52 | function tabIconStyle() { 53 | .objectFit(ImageFit.Contain) 54 | .width('24vp') 55 | .height('24vp') 56 | } 57 | 58 | @Extend(Text) 59 | function tabLabelStyle() { 60 | .fontColor(0x4A4A4A) 61 | .fontSize('12fp') 62 | .textAlign(TextAlign.Center) 63 | } 64 | 65 | @Entry 66 | @Component 67 | struct MainPage { 68 | @Provide('navPathStack') navPathStack: NavPathStack = FastNavRouter.navPathStack; 69 | @State currentTab: HomeTabItem = homeTabs[0]; 70 | public readonly foldStatusKey = 'foldStatusKey' 71 | 72 | aboutToAppear(): void { 73 | FoldStatusObserver.startListening() 74 | } 75 | 76 | aboutToDisappear(): void { 77 | FoldStatusObserver.stopListening() 78 | } 79 | 80 | // 路由跳转控制 81 | @Builder 82 | PageMap(name: string, params?: RouterModel) { 83 | if (FastNavRouter.getBuilder(name) !== undefined) { 84 | // 测试动态路由 (TestDynamicNavPage) 85 | FastNavRouter.getBuilder(name).builder(params) 86 | } else { 87 | if (name === PagePathConstants.PAGE_HTTP_REQUEST) { 88 | HttpRequestExample() 89 | } else if (name === PagePathConstants.PAGE_EVENT_BUS) { 90 | EventBusExample() 91 | } else if (name === PagePathConstants.PAGE_CUSTOM_DIALOG) { 92 | CustomDialogExample() 93 | } else if (name === PagePathConstants.PAGE_ROUTER_CALLBACK) { 94 | RouterCallbackExample() 95 | } else if (name === PagePathConstants.PAGE_NAV_ROUTER_TEST) { 96 | TestNavPathJumpPage({ 97 | routerParams: params 98 | }) 99 | } else if (name === PagePathConstants.PAGE_THROTTLE_TEST) { 100 | ThrottleExample() 101 | } else if (name === PagePathConstants.PAGE_PERMISSION_TEST) { 102 | PermissionExample() 103 | } else if (name === PagePathConstants.DYNAMIC_UI_NODE_TEST) { 104 | BuilderNodeExample() 105 | } else if (name === PagePathConstants.FIX_FOLD_UI_EXAMPLE) { 106 | FixFoldUiExample() 107 | } else if (name === PagePathConstants.COMPONENT_FACTORY_EXAMPLE) { 108 | ComponentFactoryExample() 109 | } else if (name === PagePathConstants.ATTRIBUTE_MODIFIER_EXAMPLE) { 110 | AttributeModifierExample() 111 | } else if (name === PagePathConstants.CLOUD_FUNCTION_EXAMPLE) { 112 | CloudFuncExample() 113 | } else if (name === PagePathConstants.CLOUD_DATA_BASE_EXAMPLE) { 114 | CloudDatabaseExample() 115 | } 116 | } 117 | } 118 | 119 | @Builder 120 | TabBuilder(tabItem: HomeTabItem) { 121 | Column() { 122 | Image(tabItem.type === this.currentTab.type ? tabItem.selectImg : tabItem.img) 123 | .tabIconStyle() 124 | Text(tabItem.type.toString()) 125 | .tabLabelStyle() 126 | } 127 | .size({ width: '100%', height: '100%' }) 128 | .alignItems(HorizontalAlign.Center) 129 | .justifyContent(FlexAlign.Center) 130 | } 131 | 132 | build() { 133 | Navigation(this.navPathStack) { 134 | Tabs({ 135 | barPosition: BarPosition.End, 136 | }) { 137 | ForEach( 138 | homeTabs, (item: HomeTabItem, index) => { 139 | TabContent() { 140 | if (this.currentTab.type == TabItemEnum.home) { 141 | HomePage() 142 | } else { 143 | SettingPage() 144 | } 145 | } 146 | .tabBar( 147 | this.TabBuilder(item) 148 | ) 149 | }) 150 | } 151 | .scrollable(false) 152 | .animationDuration(0) 153 | .barHeight('48vp') 154 | .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP]) 155 | .onChange((index) => { 156 | this.currentTab = homeTabs[index] 157 | }) 158 | } 159 | .mode(NavigationMode.Stack) //不加这个在折叠屏会有问题 160 | .navBarWidth('100%') 161 | .height('100%') 162 | .width('100%') 163 | .backgroundColor($r('app.color.primary')) 164 | .navDestination(this.PageMap) 165 | .appStyle() 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /entry/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "entry", 4 | "type": "entry", 5 | "description": "$string:module_desc", 6 | "mainElement": "EntryAbility", 7 | "deviceTypes": [ 8 | "phone", 9 | "tablet" 10 | ], 11 | "deliveryWithInstall": true, 12 | "installationFree": true, 13 | "pages": "$profile:main_pages", 14 | "requestPermissions": [ 15 | { 16 | "name": "ohos.permission.INTERNET" 17 | }, 18 | { 19 | "name": "ohos.permission.LOCATION", 20 | "reason": "$string:app_location_reason", 21 | "usedScene": { 22 | "abilities": [ 23 | "EntryAbility" 24 | ], 25 | "when": "inuse" 26 | } 27 | }, 28 | { 29 | "name": "ohos.permission.APPROXIMATELY_LOCATION", 30 | "reason": "$string:app_location_reason", 31 | "usedScene": { 32 | "abilities": [ 33 | "EntryAbility" 34 | ], 35 | "when": "inuse" 36 | } 37 | } 38 | ], 39 | "atomicService": { 40 | "preloads": [ 41 | { 42 | "moduleName": "feature_hsp_page" 43 | }, 44 | ] 45 | }, 46 | "abilities": [ 47 | { 48 | "name": "EntryAbility", 49 | "srcEntry": "./ets/entryability/EntryAbility.ets", 50 | "description": "$string:EntryAbility_desc", 51 | "icon": "$media:labelIcon", 52 | "label": "$string:app_label", 53 | "startWindowIcon": "$media:startIcon", 54 | "startWindowBackground": "$color:start_window_background", 55 | "exported": true, 56 | "skills": [ 57 | { 58 | "entities": [ 59 | "entity.system.home" 60 | ], 61 | "actions": [ 62 | "action.system.home" 63 | ] 64 | } 65 | ] 66 | } 67 | ], 68 | "metadata": [ 69 | // 使用华为账号登录需要配置 clientID 70 | { 71 | "name": "client_id", 72 | "value": "111763805" 73 | }, 74 | ] 75 | } 76 | } -------------------------------------------------------------------------------- /entry/src/main/resources/base/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "start_window_background", 5 | "value": "#FFFFFF" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /entry/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "HarmonyAtomicService" 6 | }, 7 | { 8 | "name": "EntryAbility_desc", 9 | "value": "HarmonyAtomicService" 10 | }, 11 | { 12 | "name": "app_location_reason", 13 | "value": "测试位置权限" 14 | }, 15 | { 16 | "name": "EntryAbility_label", 17 | "value": "HarmonyAtomicService" 18 | }, 19 | { 20 | "name": "app_label", 21 | "value": "CodeLab" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /entry/src/main/resources/base/media/ic_home_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/entry/src/main/resources/base/media/ic_home_normal.png -------------------------------------------------------------------------------- /entry/src/main/resources/base/media/ic_home_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/entry/src/main/resources/base/media/ic_home_select.png -------------------------------------------------------------------------------- /entry/src/main/resources/base/media/ic_mine_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/entry/src/main/resources/base/media/ic_mine_normal.png -------------------------------------------------------------------------------- /entry/src/main/resources/base/media/ic_mine_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/entry/src/main/resources/base/media/ic_mine_select.png -------------------------------------------------------------------------------- /entry/src/main/resources/base/media/labelIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/entry/src/main/resources/base/media/labelIcon.png -------------------------------------------------------------------------------- /entry/src/main/resources/base/media/startIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/entry/src/main/resources/base/media/startIcon.png -------------------------------------------------------------------------------- /entry/src/main/resources/base/profile/main_pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": [ 3 | "pages/MainPage" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /entry/src/main/resources/rawfile/schema.json: -------------------------------------------------------------------------------- 1 | {"schemaVersion":1,"permissions":[{"permissions":[{"role":"World","rights":["Read","Upsert","Delete"]},{"role":"Authenticated","rights":["Read","Upsert","Delete"]},{"role":"Creator","rights":["Read","Upsert","Delete"]},{"role":"Administrator","rights":["Read","Upsert","Delete"]}],"objectTypeName":"LogReport"}],"objectTypes":[{"indexes":[{"indexName":"time","indexList":[{"fieldName":"time","sortType":"ASC"}]}],"objectTypeName":"LogReport","fields":[{"isNeedEncrypt":false,"fieldName":"id","notNull":true,"isSensitive":false,"belongPrimaryKey":true,"fieldType":"Integer"},{"isNeedEncrypt":false,"fieldName":"content","notNull":false,"isSensitive":false,"belongPrimaryKey":false,"fieldType":"String"},{"isNeedEncrypt":false,"fieldName":"time","notNull":false,"isSensitive":false,"belongPrimaryKey":false,"fieldType":"String"}]}]} -------------------------------------------------------------------------------- /entry/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "模块描述" 6 | }, 7 | { 8 | "name": "EntryAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "EntryAbility_label", 13 | "value": "label" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /features/feature_hsp_page/Index.ets: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/features/feature_hsp_page/Index.ets -------------------------------------------------------------------------------- /features/feature_hsp_page/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | }, 5 | "buildOptionSet": [ 6 | { 7 | "name": "release", 8 | "arkOptions": { 9 | "obfuscation": { 10 | "ruleOptions": { 11 | "enable": true, 12 | "files": [ 13 | "./obfuscation-rules.txt" 14 | ] 15 | } 16 | } 17 | }, 18 | }, 19 | ], 20 | "targets": [ 21 | { 22 | "name": "default" 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { hspTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: hspTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /features/feature_hsp_page/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /features/feature_hsp_page/oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "@ohos/fast_ui@../../base/fast_ui": "@ohos/fast_ui@../../base/fast_ui", 9 | "@ohos/fast_util@../../base/fast_util": "@ohos/fast_util@../../base/fast_util" 10 | }, 11 | "packages": { 12 | "@ohos/fast_ui@../../base/fast_ui": { 13 | "name": "fast_ui", 14 | "version": "1.0.0", 15 | "resolved": "../../base/fast_ui", 16 | "registryType": "local" 17 | }, 18 | "@ohos/fast_util@../../base/fast_util": { 19 | "name": "fast_util", 20 | "version": "1.0.0", 21 | "resolved": "../../base/fast_util", 22 | "registryType": "local" 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "feature_hsp_page", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "Index.ets", 6 | "author": "", 7 | "license": "Apache-2.0", 8 | "packageType": "InterfaceHar", 9 | "dependencies": { 10 | "@ohos/fast_ui": "file:../../base/fast_ui", 11 | "@ohos/fast_util": "file:../../base/fast_util" 12 | } 13 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/src/main/ets/pages/TestHspNavPathPage.ets: -------------------------------------------------------------------------------- 1 | /// 测试 NavPath 跳转 HSP 内页面 2 | /// 使用 NavPath 跳转 HSP 内页面,需要在 route_map.json 中进行声明,module.json5 内需要添加 "routerMap": "$profile:route_map" 3 | import { CommonFillButton } from '@ohos/fast_ui' 4 | import { RouterModel } from '@ohos/fast_util' 5 | 6 | @Builder 7 | export function TestHspNavPathPageBuilder() { 8 | TestHspNavPathPage() 9 | } 10 | 11 | @Component 12 | struct TestHspNavPathPage { 13 | routerParams?: RouterModel 14 | @State pathStack: NavPathStack = new NavPathStack() 15 | @State receiveParams: string = '' 16 | @State resultData: string = '' 17 | 18 | aboutToAppear(): void { 19 | this.resultData = (Math.random() * 100).toFixed(0).toString() 20 | } 21 | 22 | build() { 23 | NavDestination() { 24 | Column({ space: '30vp' }) { 25 | Text(`页面模块及路径:feature_hsp_page(hsp) TestHspNavPathPage.ets`).fontSize('12vp').fontColor(Color.Red) 26 | Text(`接收到的入参:${this.receiveParams}`).fontSize('15vp') 27 | Text(`页面随机数(用于测试回传): ${this.resultData}`).fontSize('18vp') 28 | CommonFillButton({ 29 | text: '关闭并返回结果', 30 | horizontalPadding: '40vp', 31 | verticalPadding: '10vp', 32 | event: () => { 33 | if (this.routerParams?.popCallback !== undefined) { 34 | this.routerParams.popCallback(`Router 回调结果:${this.resultData}`) 35 | } 36 | this.pathStack.pop() 37 | } 38 | }) 39 | } 40 | .height('100%') 41 | .width('100%') 42 | .justifyContent(FlexAlign.Center) 43 | } 44 | .title('NavPath跳转HSP页面') 45 | .onReady((context: NavDestinationContext) => { 46 | this.pathStack = context.pathStack 47 | this.routerParams = context.pathInfo.param as RouterModel 48 | this.receiveParams = this.routerParams.params as string 49 | }) 50 | } 51 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/src/main/ets/pages/TestHspRoutePage.ets: -------------------------------------------------------------------------------- 1 | import { CommonFillButton } from '@ohos/fast_ui/Index' 2 | import { FastRouter, RouterModel } from '@ohos/fast_util/Index' 3 | 4 | /// 测试 Route 跳转 HSP 内页面 5 | @Entry 6 | @Component 7 | struct TestHspRoutePage { 8 | routerParams?: RouterModel 9 | @State receiveParams: string = '' 10 | @State resultData: string = '' 11 | 12 | aboutToAppear(): void { 13 | this.routerParams = FastRouter.getRouterCurrentParams as RouterModel 14 | this.receiveParams = this.routerParams.params!.toString() 15 | this.resultData = (Math.random() * 100).toFixed(0).toString() 16 | } 17 | 18 | onBackPress(): boolean | void { 19 | FastRouter.pop() 20 | return true 21 | } 22 | 23 | build() { 24 | NavDestination() { 25 | Column({ space: '30vp' }) { 26 | Text(`页面模块及路径:feature_hsp_page(hsp) TestHspRoutePage.ets`).fontSize('12vp').fontColor(Color.Red) 27 | Text(`接收到的入参:${this.receiveParams}`).fontSize('15vp') 28 | Text(`页面随机数(用于测试回传): ${this.resultData}`).fontSize('18vp') 29 | CommonFillButton({ 30 | text: '关闭并返回结果', 31 | horizontalPadding: '40vp', 32 | verticalPadding: '10vp', 33 | event: () => { 34 | if (this.routerParams?.popCallback !== undefined) { 35 | this.routerParams.popCallback(`Router 回调结果:${this.resultData}`) 36 | } 37 | FastRouter.pop() 38 | } 39 | }) 40 | } 41 | .height('100%') 42 | .width('100%') 43 | .justifyContent(FlexAlign.Center) 44 | } 45 | .title('Route跳转HSP页面') 46 | } 47 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "feature_hsp_page", 4 | "type": "shared", 5 | "description": "$string:shared_desc", 6 | "deviceTypes": [ 7 | "phone", 8 | "tablet" 9 | ], 10 | "deliveryWithInstall": true, 11 | "installationFree": true, 12 | "pages": "$profile:main_pages", 13 | "routerMap": "$profile:route_map" 14 | } 15 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/src/main/resources/base/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "white", 5 | "value": "#FFFFFF" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "shared_desc", 5 | "value": "description" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /features/feature_hsp_page/src/main/resources/base/profile/main_pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": [ 3 | "pages/TestHspRoutePage" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /features/feature_hsp_page/src/main/resources/base/profile/route_map.json: -------------------------------------------------------------------------------- 1 | { 2 | "routerMap": [ 3 | { 4 | "name": "TestHspNavJumpCallback", 5 | "pageSourceFile": "src/main/ets/pages/TestHspNavPathPage.ets", 6 | "buildFunction": "TestHspNavPathPageBuilder", 7 | "data": { 8 | "description" : "this is PageOne" 9 | } 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /hvigor/hvigor-config.json5: -------------------------------------------------------------------------------- 1 | { 2 | "modelVersion": "5.0.0", 3 | "dependencies": { 4 | }, 5 | "execution": { 6 | // "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */ 7 | // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ 8 | // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ 9 | // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ 10 | // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ 11 | }, 12 | "logging": { 13 | // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ 14 | }, 15 | "debugging": { 16 | // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ 17 | }, 18 | "nodeOptions": { 19 | // "maxOldSpaceSize": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */ 20 | } 21 | } -------------------------------------------------------------------------------- /hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { appTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", 9 | "@ohos/hypium@1.0.16": "@ohos/hypium@1.0.16" 10 | }, 11 | "packages": { 12 | "@ohos/hamock@1.0.0": { 13 | "name": "@ohos/hamock", 14 | "version": "1.0.0", 15 | "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", 16 | "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har", 17 | "registryType": "ohpm" 18 | }, 19 | "@ohos/hypium@1.0.16": { 20 | "name": "@ohos/hypium", 21 | "version": "1.0.16", 22 | "integrity": "sha512-PC3jpwKERg68V+4dmKU+SLjNps9i5JcQH57rQriaTsh62NBgVZs4SceMmNOtrIOyldbEJ5mXSwoZwiG/nkRmTw==", 23 | "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.16.har", 24 | "registryType": "ohpm" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "modelVersion": "5.0.0", 3 | "name": "harmonyatomicservice", 4 | "version": "1.0.0", 5 | "description": "Please describe the basic information.", 6 | "main": "", 7 | "author": "", 8 | "license": "", 9 | "dependencies": { 10 | }, 11 | "devDependencies": { 12 | "@ohos/hypium": "1.0.16", 13 | "@ohos/hamock": "1.0.0" 14 | } 15 | } -------------------------------------------------------------------------------- /screenshots/cloud_db_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/screenshots/cloud_db_demo.png -------------------------------------------------------------------------------- /screenshots/cloud_func_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/screenshots/cloud_func_demo.png -------------------------------------------------------------------------------- /screenshots/sh_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/screenshots/sh_1.png --------------------------------------------------------------------------------