wangliang_wd

Merge branch 'main' of http://192.168.1.42/developOne/harmonyPool into main

* 'main' of http://192.168.1.42/developOne/harmonyPool:
  降级map api等级
  权限申请暂时注释掉
  增加logger日志开关
  增加权限申请工具类
  fix:电子报文字版列表,点击跳转详情事件添加
  app启动增加协议网络获取
  版面切换
  人民号顶导切换
  首页头部样式优化
  底导切换修复
  fix:隐藏卡片和创作者,隐藏搜索状态导航
  desc:4.0  搜索默认滚动
  desc:退出登录接口调试、RSA加密调试
  首页频道缓存
  播报推荐列表弹窗添加
  desc:首页搜索 滚动
Showing 37 changed files with 874 additions and 155 deletions
  1 +{
  2 + "code": "0",
  3 + "data": [
  4 + "习语",
  5 + "党史学习",
  6 + "高考倒计时"
  7 + ],
  8 + "message": "Success",
  9 + "success": true,
  10 + "timestamp": 1712562841885
  11 +}
@@ -5,6 +5,7 @@ import { BottomNavDTO } from '../../repository/bean/BottomNavDTO'; @@ -5,6 +5,7 @@ import { BottomNavDTO } from '../../repository/bean/BottomNavDTO';
5 import { UIUtils } from '../../repository/UIUtils'; 5 import { UIUtils } from '../../repository/UIUtils';
6 import { MinePageComponent } from './MinePageComponent'; 6 import { MinePageComponent } from './MinePageComponent';
7 import PageViewModel from '../../viewmodel/PageViewModel'; 7 import PageViewModel from '../../viewmodel/PageViewModel';
  8 +import { FirstTabTopComponent } from './FirstTabTopComponent';
8 9
9 const TAG = 'BottomNavigationComponent'; 10 const TAG = 'BottomNavigationComponent';
10 11
@@ -51,6 +52,9 @@ export struct BottomNavigationComponent { @@ -51,6 +52,9 @@ export struct BottomNavigationComponent {
51 // 我的页面组件数据列表 52 // 我的页面组件数据列表
52 MinePageComponent() 53 MinePageComponent()
53 } else { 54 } else {
  55 + if(index === 0 ){
  56 + FirstTabTopComponent()
  57 + }
54 TopNavigationComponent({ topNavList: navItem.topNavChannelList }) 58 TopNavigationComponent({ topNavList: navItem.topNavChannelList })
55 } 59 }
56 } 60 }
  1 +import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
  2 +/**
  3 + * 首页顶部搜索导航栏
  4 + * 竖向滚动实现方案
  5 + * 方案一 使用动画 + 定时器
  6 + * 方案二 使用容器组件Swiper(当前)
  7 + */
  8 +const TAG = "FirstTabTopComponent"
  9 +@Component
  10 +export struct FirstTabTopComponent{
  11 + @State searchTextData :string[] = []
  12 + private swiperController: SwiperController = new SwiperController()
  13 +
  14 + aboutToAppear(){
  15 + this.getSearchHint()
  16 + }
  17 +
  18 + getSearchHint(){
  19 + SearcherAboutDataModel.getSearchHintData(getContext(this)).then((value)=>{
  20 + if(value!=null){
  21 + this.searchTextData = value
  22 + }
  23 + }).catch((err:Error)=>{
  24 + console.log(TAG,JSON.stringify(err))
  25 + })
  26 + }
  27 +
  28 + build(){
  29 + Column(){
  30 + Row(){
  31 + Row(){
  32 + Image($r('app.media.search_icon'))
  33 + .objectFit(ImageFit.Cover)
  34 + .height('23lpx')
  35 + .width('23lpx')
  36 + .margin({right:'13lpx'})
  37 + .interpolation(ImageInterpolation.Medium)
  38 +
  39 + if(this.searchTextData!=null && this.searchTextData.length>0){
  40 + Swiper(this.swiperController) {
  41 + ForEach(this.searchTextData, (item: string, index: number ) => {
  42 + Text(item)
  43 + .fontWeight('400lpx')
  44 + .fontSize('25lpx')
  45 + .fontColor($r('app.color.color_666666'))
  46 + .lineHeight('35lpx')
  47 + .textAlign(TextAlign.Start)
  48 + .maxLines(1)
  49 + .textOverflow({ overflow: TextOverflow.Clip})
  50 + })
  51 + }
  52 + .loop(true)
  53 + .autoPlay(true)
  54 + .interval(3000)
  55 + .indicator(false)
  56 + .vertical(true)
  57 + }
  58 + }.width('257lpx')
  59 + .height('61lpx')
  60 + .padding({left:'31lpx'})
  61 + .backgroundImage($r('app.media.top_search_bg'))
  62 + .backgroundImageSize(ImageSize.Cover)
  63 + .alignItems(VerticalAlign.Center)
  64 +
  65 + Image($r('app.media.top_title_bg'))
  66 + .objectFit(ImageFit.Auto)
  67 + .height('58lpx')
  68 + .width('152lpx')
  69 + .interpolation(ImageInterpolation.Medium)
  70 +
  71 + Row(){
  72 + Text("早晚报")
  73 + }.backgroundImage($r('app.media.top_right_bg'))
  74 + .justifyContent(FlexAlign.Center)
  75 + .backgroundImageSize(ImageSize.Cover)
  76 + .width('257lpx')
  77 + .height('61lpx')
  78 + }.width('100%')
  79 + .justifyContent(FlexAlign.SpaceBetween)
  80 + }.height('73lpx')
  81 + .width('100%')
  82 + .justifyContent(FlexAlign.End)
  83 + .backgroundColor($r('app.color.white'))
  84 + }
  85 +
  86 +}
@@ -62,13 +62,15 @@ export struct MinePageComponent { @@ -62,13 +62,15 @@ export struct MinePageComponent {
62 //Grid 区域 62 //Grid 区域
63 MinePagePersonFunctionUI({personalData:$personalData}) 63 MinePagePersonFunctionUI({personalData:$personalData})
64 //Card 64 //Card
65 - MinePageCardUI() 65 + // MinePageCardUI()
66 //创作者区域 66 //创作者区域
67 67
68 - MinePageCreatorFunctionUI({creatorData:$creatorData}) 68 + // MinePageCreatorFunctionUI({creatorData:$creatorData})
69 //更多功能 69 //更多功能
70 MinePageMoreFunctionUI({moreData:$moreData}) 70 MinePageMoreFunctionUI({moreData:$moreData})
71 }.width('100%') 71 }.width('100%')
  72 + .height('100%')
  73 + .justifyContent(FlexAlign.Start)
72 } 74 }
73 75
74 @Styles setFullWidthAndHeight(){ 76 @Styles setFullWidthAndHeight(){
  1 +
  2 +import { Logger, ResourcesUtils } from 'wdKit';
  3 +import { ResponseDTO, WDHttp } from 'wdNetwork';
  4 +import HashMap from '@ohos.util.HashMap';
  5 +import { HttpUrlUtils } from '../network/HttpUrlUtils';
  6 +const TAG = "SearcherAboutDataModel"
  7 +
  8 +/**
  9 + * 我的页面 所有数据 获取封装类
  10 + */
  11 +class SearcherAboutDataModel{
  12 + private static instance: SearcherAboutDataModel;
  13 +
  14 + private constructor() { }
  15 +
  16 + /**
  17 + * 单例模式
  18 + * @returns
  19 + */
  20 + public static getInstance(): SearcherAboutDataModel {
  21 + if (!SearcherAboutDataModel.instance) {
  22 + SearcherAboutDataModel.instance = new SearcherAboutDataModel();
  23 + }
  24 + return SearcherAboutDataModel.instance;
  25 + }
  26 +
  27 + /**
  28 + * 首页 搜索提示滚动内容
  29 + */
  30 + getSearchHintData(context: Context): Promise<string[]> {
  31 + return new Promise<string[]>((success, error) => {
  32 + Logger.info(TAG, `getSearchHintData start`);
  33 + this.fetchSearchHintData().then((navResDTO: ResponseDTO<string[]>) => {
  34 + if (!navResDTO || navResDTO.code != 0) {
  35 + success(this.getSearchHintDataLocal(context))
  36 + return
  37 + }
  38 + Logger.info(TAG, "getSearchHintData then,SearchHintDataResDTO.timeStamp:" + navResDTO.timestamp);
  39 + let navigationBean = navResDTO.data as string[]
  40 + success(navigationBean);
  41 + }).catch((err: Error) => {
  42 + Logger.error(TAG, `fetchSearchHintData catch, error.name : ${err.name}, error.message:${err.message}`);
  43 + success(this.getSearchHintDataLocal(context))
  44 + })
  45 + })
  46 + }
  47 +
  48 + fetchSearchHintData() {
  49 + let url = HttpUrlUtils.getSearchHintDataUrl()
  50 + let headers: HashMap<string, string> = HttpUrlUtils.getYcgCommonHeaders();
  51 + return WDHttp.get<ResponseDTO<string[]>>(url, headers)
  52 + };
  53 +
  54 + async getSearchHintDataLocal(context: Context): Promise<string[]> {
  55 + Logger.info(TAG, `getSearchHintDataLocal start`);
  56 + let compRes: ResponseDTO<string[]> | null = await ResourcesUtils.getResourcesJson<ResponseDTO<string[]>>('search_hint_data.json' ,context);
  57 + if (!compRes || !compRes.data) {
  58 + Logger.info(TAG, `getSearchHintDataLocal compRes is empty`);
  59 + return []
  60 + }
  61 + Logger.info(TAG, `getSearchHintDataLocal compRes : ${JSON.stringify(compRes)}`);
  62 + return compRes.data
  63 + }
  64 +
  65 +
  66 +
  67 +}
  68 +
  69 +const searcherAboutDataModel = SearcherAboutDataModel.getInstance()
  70 +export default searcherAboutDataModel as SearcherAboutDataModel
@@ -116,6 +116,11 @@ export class HttpUrlUtils { @@ -116,6 +116,11 @@ export class HttpUrlUtils {
116 */ 116 */
117 static readonly APPOINTMENT_OPERATION_STATUS_PATH: string = "/api/live-center-message/zh/c/live/subscribe"; 117 static readonly APPOINTMENT_OPERATION_STATUS_PATH: string = "/api/live-center-message/zh/c/live/subscribe";
118 118
  119 + /**
  120 + * 首页 搜索提示
  121 + */
  122 + static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints";
  123 +
119 private static hostUrl: string = HttpUrlUtils.HOST_UAT; 124 private static hostUrl: string = HttpUrlUtils.HOST_UAT;
120 125
121 static getCommonHeaders(): HashMap<string, string> { 126 static getCommonHeaders(): HashMap<string, string> {
@@ -298,6 +303,11 @@ export class HttpUrlUtils { @@ -298,6 +303,11 @@ export class HttpUrlUtils {
298 return url 303 return url
299 } 304 }
300 305
  306 + static getSearchHintDataUrl() {
  307 + let url = HttpUrlUtils.HOST_SIT + HttpUrlUtils.SEARCH_HINT_DATA_PATH
  308 + return url
  309 + }
  310 +
301 311
302 /** 312 /**
303 * 点赞操作 313 * 点赞操作
@@ -9,5 +9,8 @@ export class SpConstants{ @@ -9,5 +9,8 @@ export class SpConstants{
9 static USER_LONG_TIME_NO_LOGIN_MARK="longTimeNoLoginMark" 9 static USER_LONG_TIME_NO_LOGIN_MARK="longTimeNoLoginMark"
10 static USER_STATUS="user_status" 10 static USER_STATUS="user_status"
11 static USER_TEMP_TOKEN="tempToken" 11 static USER_TEMP_TOKEN="tempToken"
  12 + //协议相关
  13 + static USER_PROTOCOL = "user_protocol" //用户协议
  14 + static PRIVATE_PROTOCOL = "private_protocol" //隐私协议
12 15
13 } 16 }
@@ -34,4 +34,6 @@ export { PermissionUtil } from './src/main/ets/utils/PermissionUtil' @@ -34,4 +34,6 @@ export { PermissionUtil } from './src/main/ets/utils/PermissionUtil'
34 34
35 export { UserDataLocal } from './src/main/ets/utils/UserDataLocal' 35 export { UserDataLocal } from './src/main/ets/utils/UserDataLocal'
36 36
37 -export { NumberFormatterUtils } from './src/main/ets/utils/NumberFormatterUtils'  
  37 +export { NumberFormatterUtils } from './src/main/ets/utils/NumberFormatterUtils'
  38 +
  39 +// export { PermissionUtils } from './src/main/ets/utils/PermissionUtils'
@@ -22,6 +22,7 @@ export class Logger { @@ -22,6 +22,7 @@ export class Logger {
22 private static domain: number = 0xFF00; 22 private static domain: number = 0xFF00;
23 private static prefix: string = 'SightApp'; 23 private static prefix: string = 'SightApp';
24 private static format: string = `%{public}s, %{public}s`; 24 private static format: string = `%{public}s, %{public}s`;
  25 + static isDebug: boolean = true;
25 26
26 /** 27 /**
27 * constructor. 28 * constructor.
@@ -35,26 +36,44 @@ export class Logger { @@ -35,26 +36,44 @@ export class Logger {
35 } 36 }
36 37
37 static debug(...args: string[]) { 38 static debug(...args: string[]) {
  39 + if(!Logger.isDebug){
  40 + return
  41 + }
38 hilog.debug(Logger.domain, Logger.prefix, Logger.format, args); 42 hilog.debug(Logger.domain, Logger.prefix, Logger.format, args);
39 } 43 }
40 44
41 static info(...args: string[]) { 45 static info(...args: string[]) {
  46 + if(!Logger.isDebug){
  47 + return
  48 + }
42 hilog.info(Logger.domain, Logger.prefix, Logger.format, args); 49 hilog.info(Logger.domain, Logger.prefix, Logger.format, args);
43 } 50 }
44 51
45 static warn(...args: string[]) { 52 static warn(...args: string[]) {
  53 + if(!Logger.isDebug){
  54 + return
  55 + }
46 hilog.warn(Logger.domain, Logger.prefix, Logger.format, args); 56 hilog.warn(Logger.domain, Logger.prefix, Logger.format, args);
47 } 57 }
48 58
49 static error(...args: string[]) { 59 static error(...args: string[]) {
  60 + if(!Logger.isDebug){
  61 + return
  62 + }
50 hilog.error(Logger.domain, Logger.prefix, Logger.format, args); 63 hilog.error(Logger.domain, Logger.prefix, Logger.format, args);
51 } 64 }
52 65
53 static fatal(...args: string[]) { 66 static fatal(...args: string[]) {
  67 + if(!Logger.isDebug){
  68 + return
  69 + }
54 hilog.fatal(Logger.domain, Logger.prefix, Logger.format, args); 70 hilog.fatal(Logger.domain, Logger.prefix, Logger.format, args);
55 } 71 }
56 72
57 static isLoggable(level: LogLevel) { 73 static isLoggable(level: LogLevel) {
  74 + if(!Logger.isDebug){
  75 + return
  76 + }
58 hilog.isLoggable(Logger.domain, Logger.prefix, level); 77 hilog.isLoggable(Logger.domain, Logger.prefix, level);
59 } 78 }
60 } 79 }
  1 +// import { abilityAccessCtrl, bundleManager, common, Permissions, Want } from '@kit.AbilityKit'
  2 +// import { BusinessError } from '@kit.BasicServicesKit'
  3 +// import { AppUtils } from './AppUtils'
  4 +// import { Logger } from './Logger'
  5 +//
  6 +// /**
  7 +// * 权限工具类
  8 +// * */
  9 +// export class PermissionUtils {
  10 +// //相机权限
  11 +// static CAMERA: Permissions = 'ohos.permission.CAMERA'
  12 +// //文件权限
  13 +// static READ_MEDIA: Permissions = 'ohos.permission.READ_MEDIA'
  14 +// static WRITE_MEDIA: Permissions = 'ohos.permission.WRITE_MEDIA'
  15 +// private static tokenId: number = 0
  16 +//
  17 +// /**检查权限是否授权*/
  18 +// static async checkPermissions(permission: Permissions): Promise<boolean> {
  19 +// let hasPermissions = false;
  20 +// let grantStatus: abilityAccessCtrl.GrantStatus = await PermissionUtils.checkAccessToken(permission);
  21 +//
  22 +// if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
  23 +// // 已经授权,可以继续访问目标操作
  24 +// hasPermissions = true;
  25 +// } else {
  26 +// hasPermissions = false;
  27 +// // 申请日历权限
  28 +// }
  29 +// return hasPermissions;
  30 +// }
  31 +//
  32 +// /**动态申请权限*/
  33 +// static reqPermissionsFromUser(permissions: Array<Permissions>, component: Object): Promise<boolean> {
  34 +//
  35 +// return new Promise((resolve, fail) => {
  36 +// let context = getContext(component) as common.UIAbilityContext;
  37 +// let atManager = abilityAccessCtrl.createAtManager();
  38 +// atManager.requestPermissionsFromUser(context, permissions).then((data) => {
  39 +// let grantStatus: Array<number> = data.authResults;
  40 +// let length: number = grantStatus.length;
  41 +//
  42 +// for (let i = 0; i < length; i++) {
  43 +// if (grantStatus[i] === 0) {
  44 +// // 用户授权,可以继续访问目标操作
  45 +// resolve(true);
  46 +// } else {
  47 +// resolve(false)
  48 +// }
  49 +// }
  50 +// }).catch((err: Error) => {
  51 +// fail(err)
  52 +// })
  53 +// });
  54 +// }
  55 +//
  56 +// /**跳转设置页面*/
  57 +// static openPermissionsInSystemSettings(context: Object): void {
  58 +// let uiContext = getContext(context) as common.UIAbilityContext;
  59 +// let wantInfo: Want = {
  60 +// bundleName: 'com.huawei.hmos.settings',
  61 +// abilityName: 'com.huawei.hmos.settings.MainAbility',
  62 +// uri: 'application_info_entry',
  63 +// parameters: {
  64 +// pushParams: AppUtils.getPackageName(uiContext) // 打开指定应用的设置页面
  65 +// }
  66 +// }
  67 +// uiContext.startAbility(wantInfo)
  68 +// }
  69 +//
  70 +// private static async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
  71 +// let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  72 +// let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
  73 +//
  74 +// // 获取应用程序的accessTokenID
  75 +// if (PermissionUtils.tokenId == 0) {
  76 +// try {
  77 +// let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
  78 +// let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
  79 +// PermissionUtils.tokenId = appInfo.accessTokenId;
  80 +// } catch (error) {
  81 +// const err: BusinessError = error as BusinessError;
  82 +// }
  83 +// }
  84 +// // 校验应用是否被授予权限
  85 +// try {
  86 +// grantStatus = await atManager.checkAccessToken(PermissionUtils.tokenId, permission);
  87 +// } catch (error) {
  88 +// const err: BusinessError = error as BusinessError;
  89 +// }
  90 +//
  91 +// return grantStatus;
  92 +// }
  93 +//
  94 +// }
@@ -169,6 +169,10 @@ export class HttpUrlUtils { @@ -169,6 +169,10 @@ export class HttpUrlUtils {
169 */ 169 */
170 static readonly FOLLOW_OPERATION_PATH: string = "/api/rmrb-interact/interact/zh/c/attention/operation"; 170 static readonly FOLLOW_OPERATION_PATH: string = "/api/rmrb-interact/interact/zh/c/attention/operation";
171 /** 171 /**
  172 + * 首页 搜索提示
  173 + */
  174 + static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints";
  175 + /**
172 * 早晚报列表 176 * 早晚报列表
173 * 根据页面id获取页面楼层列表 177 * 根据页面id获取页面楼层列表
174 * https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/pageInfo?pageId=28927 178 * https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/pageInfo?pageId=28927
@@ -390,7 +394,7 @@ export class HttpUrlUtils { @@ -390,7 +394,7 @@ export class HttpUrlUtils {
390 } 394 }
391 395
392 static getLogoutUrl() { 396 static getLogoutUrl() {
393 - let url = HttpUrlUtils._hostUrl + "/api/rmrb-user-center/user/zh/c/logout"; 397 + let url = HttpUrlUtils._hostUrl + "/api/rmrb-user-center/user/zh/c/appLogout";
394 return url; 398 return url;
395 } 399 }
396 400
@@ -419,6 +423,10 @@ export class HttpUrlUtils { @@ -419,6 +423,10 @@ export class HttpUrlUtils {
419 let url = HttpUrlUtils._hostUrl + "/api/rmrb-user-center/auth/zh/c/checkVerifyCode"; 423 let url = HttpUrlUtils._hostUrl + "/api/rmrb-user-center/auth/zh/c/checkVerifyCode";
420 return url; 424 return url;
421 } 425 }
  426 + static getAgreement() {
  427 + let url = HttpUrlUtils._hostUrl + "/api/rmrb-bff-display-zh/display/zh/c/agreement";
  428 + return url;
  429 + }
422 430
423 static getCheckVerifyByTokenCodeUrl() { 431 static getCheckVerifyByTokenCodeUrl() {
424 let url = HttpUrlUtils._hostUrl + "/api/rmrb-user-center/auth/zh/c/checkVerifyCodeByToken"; 432 let url = HttpUrlUtils._hostUrl + "/api/rmrb-user-center/auth/zh/c/checkVerifyCodeByToken";
@@ -510,6 +518,12 @@ export class HttpUrlUtils { @@ -510,6 +518,12 @@ export class HttpUrlUtils {
510 return url 518 return url
511 } 519 }
512 520
  521 + static getSearchHintDataUrl() {
  522 + let url = HttpUrlUtils._hostUrl + HttpUrlUtils.SEARCH_HINT_DATA_PATH
  523 + return url
  524 + }
  525 +
  526 +
513 527
514 // static getYcgCommonHeaders(): HashMap<string, string> { 528 // static getYcgCommonHeaders(): HashMap<string, string> {
515 // let headers: HashMap<string, string> = new HashMap<string, string>() 529 // let headers: HashMap<string, string> = new HashMap<string, string>()
@@ -58,3 +58,5 @@ export { AudioDetailComponent } from "./src/main/ets/components/AudioDetailCompo @@ -58,3 +58,5 @@ export { AudioDetailComponent } from "./src/main/ets/components/AudioDetailCompo
58 58
59 export { BroadcastPageComponent } from "./src/main/ets/components/broadcast/BroadcastPageComponent" 59 export { BroadcastPageComponent } from "./src/main/ets/components/broadcast/BroadcastPageComponent"
60 60
  61 +export { FirstTabTopSearchComponent } from "./src/main/ets/components/search/FirstTabTopSearchComponent"
  62 +
1 -import { CompInfoBean, CompDTO } from 'wdBean' 1 +import { CompInfoBean, CompDTO, CompList } from 'wdBean'
2 import { CommonConstants } from 'wdConstant'; 2 import { CommonConstants } from 'wdConstant';
3 import { ProcessUtils } from '../../utils/ProcessUtils'; 3 import { ProcessUtils } from '../../utils/ProcessUtils';
4 -  
5 /** 4 /**
6 * 播报--今日推荐列表 5 * 播报--今日推荐列表
7 */ 6 */
@@ -9,6 +8,12 @@ import { ProcessUtils } from '../../utils/ProcessUtils'; @@ -9,6 +8,12 @@ import { ProcessUtils } from '../../utils/ProcessUtils';
9 @Component 8 @Component
10 export struct RecommendLists { 9 export struct RecommendLists {
11 @Prop recommendCompInfoBean: CompInfoBean = {} as CompInfoBean // 推荐-组件信息 10 @Prop recommendCompInfoBean: CompInfoBean = {} as CompInfoBean // 推荐-组件信息
  11 + recommendDialog: CustomDialogController = new CustomDialogController({
  12 + builder: CustomDialogExample({
  13 + recommendLists: this.recommendCompInfoBean?.compList
  14 + }),
  15 + offset: { dx: 0, dy: 0 }
  16 + })
12 17
13 build() { 18 build() {
14 Column(){ 19 Column(){
@@ -32,7 +37,7 @@ export struct RecommendLists { @@ -32,7 +37,7 @@ export struct RecommendLists {
32 .justifyContent(FlexAlign.Center) 37 .justifyContent(FlexAlign.Center)
33 .margin({top: 5}) 38 .margin({top: 5})
34 .onClick(() => { 39 .onClick(() => {
35 - // console.log(1) 40 + this.recommendDialog.open()
36 }) 41 })
37 } 42 }
38 } 43 }
@@ -62,9 +67,65 @@ export struct RecommendLists { @@ -62,9 +67,65 @@ export struct RecommendLists {
62 ProcessUtils.processPage(item.operDataList[0]) 67 ProcessUtils.processPage(item.operDataList[0])
63 }) 68 })
64 } 69 }
  70 +}
65 71
66 - @Builder  
67 - recommendListItem() { 72 +@CustomDialog
  73 +struct CustomDialogExample {
  74 + controller: CustomDialogController
  75 + @Prop recommendLists: CompList[]
  76 + build() {
  77 + Column(){
  78 + Text('推荐列表')
  79 + .fontSize($r('app.float.selected_text_size'))
  80 + .fontWeight(500)
  81 + .fontColor($r('app.color.color_323232'))
  82 + .height(57)
  83 + .width(CommonConstants.FULL_WIDTH)
  84 + .padding({left: 16})
  85 + Divider()
  86 + List(){
  87 + ForEach(this.recommendLists, (item: CompDTO, index: number) => {
  88 + ListItem(){
  89 + this.listItem(item, index)
  90 + }
  91 + .onClick(() => {
  92 + ProcessUtils.processPage(item.operDataList[0])
  93 + this.controller.close()
  94 + })
  95 + })
  96 + }.layoutWeight(1)
  97 + Divider()
  98 + Text('取消')
  99 + .fontSize($r('app.float.font_size_16'))
  100 + .fontColor($r('app.color.color_323232'))
  101 + .width(CommonConstants.FULL_WIDTH)
  102 + .height(57)
  103 + .textAlign(TextAlign.Center)
  104 + .onClick(() => {
  105 + this.controller.close()
  106 + })
  107 + }
  108 + .height('80%')
  109 + }
68 110
  111 + @Builder listItem(item: CompDTO,index: number) {
  112 + Row(){
  113 + Text(String(index+1))
  114 + .width(24)
  115 + .height(24)
  116 + .textAlign(TextAlign.Center)
  117 + .fontSize($r('app.float.font_size_14'))
  118 + .fontColor($r('app.color.color_48505A'))
  119 + Text(item.operDataList[0].newsTitle)
  120 + .layoutWeight(1)
  121 + .maxLines(1)
  122 + .textOverflow({overflow:TextOverflow.Ellipsis})
  123 + .margin({left: 16})
  124 + .fontSize($r('app.float.font_size_16'))
  125 + .fontColor($r('app.color.color_212228'))
  126 + }
  127 + .width(CommonConstants.FULL_WIDTH)
  128 + .height(54)
  129 + .padding({left: 16, right: 16})
69 } 130 }
70 } 131 }
@@ -29,7 +29,8 @@ struct ChannelDialog { @@ -29,7 +29,8 @@ struct ChannelDialog {
29 @Link myChannelList: TopNavDTO[] 29 @Link myChannelList: TopNavDTO[]
30 @Link moreChannelList: TopNavDTO[] 30 @Link moreChannelList: TopNavDTO[]
31 @Link localChannelList: TopNavDTO[] 31 @Link localChannelList: TopNavDTO[]
32 - @Link indexSettingArray: string[] 32 + @Link homeChannelList: TopNavDTO[]
  33 + @Link indexSettingChannelId: number
33 controller?: CustomDialogController 34 controller?: CustomDialogController
34 confirm: (index: number) => void = () => { 35 confirm: (index: number) => void = () => {
35 } 36 }
@@ -48,9 +49,6 @@ struct ChannelDialog { @@ -48,9 +49,6 @@ struct ChannelDialog {
48 let targetItem = this.myChannelList[newIndex] 49 let targetItem = this.myChannelList[newIndex]
49 if (!(targetItem?.headlinesOn === 1 || targetItem?.movePermitted === 0 || targetItem?.homeChannel === '1')) { 50 if (!(targetItem?.headlinesOn === 1 || targetItem?.movePermitted === 0 || targetItem?.homeChannel === '1')) {
50 this.changeChannelIndex(index, newIndex) 51 this.changeChannelIndex(index, newIndex)
51 - if (index <= this.currentTopNavSelectedIndex || newIndex <= this.currentTopNavSelectedIndex) {  
52 - // this.currentTopNavSelectedIndex = this.myChannelList.findIndex(ele => ele.channelId === currentTopNavSelectedItem.channelId)  
53 - }  
54 } 52 }
55 } 53 }
56 54
@@ -214,22 +212,22 @@ struct ChannelDialog { @@ -214,22 +212,22 @@ struct ChannelDialog {
214 212
215 ListItem() { 213 ListItem() {
216 Flex({ justifyContent: FlexAlign.SpaceBetween }) { 214 Flex({ justifyContent: FlexAlign.SpaceBetween }) {
217 - ForEach(this.indexSettingArray, (text: string, index: number) => { 215 + ForEach(this.homeChannelList, (item: TopNavDTO, index: number) => {
218 Stack() { 216 Stack() {
219 - Image(this.indexSettingTabIndex === index ? $r('app.media.index_setting_button_active') : $r('app.media.index_setting_button')) 217 + Image(item.channelId === this.indexSettingChannelId ? $r('app.media.index_setting_button_active') : $r('app.media.index_setting_button'))
220 .objectFit(ImageFit.Auto) 218 .objectFit(ImageFit.Auto)
221 .rotate({ 219 .rotate({
222 angle: index === 1 ? 180 : 0 220 angle: index === 1 ? 180 : 0
223 }) 221 })
224 Row() { 222 Row() {
225 if (index === 0) { 223 if (index === 0) {
226 - Image(this.indexSettingTabIndex === index ? $r('app.media.recommend_icon') : $r('app.media.recommend_icon_active')) 224 + Image(item.channelId === this.indexSettingChannelId ? $r('app.media.recommend_icon') : $r('app.media.recommend_icon_active'))
227 .width(20) 225 .width(20)
228 } 226 }
229 - Text(text) 227 + Text(item.name)
230 .textAlign(TextAlign.Center) 228 .textAlign(TextAlign.Center)
231 .fontSize(16) 229 .fontSize(16)
232 - .fontColor(index === this.indexSettingTabIndex ? '#ffffff' : '#ED2800') 230 + .fontColor(item.channelId === this.indexSettingChannelId ? '#ffffff' : '#ED2800')
233 } 231 }
234 .width('100%') 232 .width('100%')
235 .justifyContent(FlexAlign.Center) 233 .justifyContent(FlexAlign.Center)
@@ -237,7 +235,7 @@ struct ChannelDialog { @@ -237,7 +235,7 @@ struct ChannelDialog {
237 .alignContent(Alignment.Start) 235 .alignContent(Alignment.Start)
238 .height(36) 236 .height(36)
239 .onClick(() => { 237 .onClick(() => {
240 - this.indexSettingTabIndex = index 238 + AppStorage.set('indexSettingChannelId',item.channelId)
241 }) 239 })
242 }) 240 })
243 } 241 }
@@ -280,7 +278,7 @@ struct ChannelDialog { @@ -280,7 +278,7 @@ struct ChannelDialog {
280 .fontSize(14) 278 .fontSize(14)
281 .fontColor(this.currentTopNavSelectedItem.channelId === item.channelId ? '#ED2800' : (item.homeChannel === '1' || item.movePermitted === 0 ? '#999999' : '#222222')) 279 .fontColor(this.currentTopNavSelectedItem.channelId === item.channelId ? '#ED2800' : (item.homeChannel === '1' || item.movePermitted === 0 ? '#999999' : '#222222'))
282 280
283 - if (this.isEditIng && item.myChannel !== '1') { 281 + if (this.isEditIng && item.delPermitted === 1) {
284 Image($r('app.media.icon_audio_close')) 282 Image($r('app.media.icon_audio_close'))
285 .width(12) 283 .width(12)
286 .margin({ left: 1 }) 284 .margin({ left: 1 })
@@ -292,7 +290,7 @@ struct ChannelDialog { @@ -292,7 +290,7 @@ struct ChannelDialog {
292 .backgroundColor(item.homeChannel === '1' || item.movePermitted === 0 ? '#F5F5F5' : '#ffffff') 290 .backgroundColor(item.homeChannel === '1' || item.movePermitted === 0 ? '#F5F5F5' : '#ffffff')
293 .onClick(() => { 291 .onClick(() => {
294 if (this.isEditIng) { 292 if (this.isEditIng) {
295 - if (item.myChannel !== '1') { 293 + if (item.delPermitted === 1) {
296 this.delChannelItem(index) 294 this.delChannelItem(index)
297 } 295 }
298 } else { 296 } else {
@@ -445,10 +443,13 @@ struct ChannelSubscriptionLayout { @@ -445,10 +443,13 @@ struct ChannelSubscriptionLayout {
445 @State indexSettingArray: string [] = ['推荐', '热点'] 443 @State indexSettingArray: string [] = ['推荐', '热点']
446 //当前选中的频道 444 //当前选中的频道
447 @Link currentTopNavSelectedIndex: number; 445 @Link currentTopNavSelectedIndex: number;
  446 + @Prop homeChannelList: TopNavDTO []
  447 + @Prop indexSettingChannelId: number
448 @Link myChannelList: TopNavDTO [] 448 @Link myChannelList: TopNavDTO []
449 @Link moreChannelList: TopNavDTO [] 449 @Link moreChannelList: TopNavDTO []
450 @Link localChannelList: TopNavDTO [] 450 @Link localChannelList: TopNavDTO []
451 - @Link @Watch('onChannelIdsUpdate') channelIds: number [] 451 + @Link channelIds: number []
  452 + @StorageLink('channelIds') storeChannelIds: string = ''
452 changeTab: (index: number) => void = () => { 453 changeTab: (index: number) => void = () => {
453 } 454 }
454 //频道弹窗点击切换频道 455 //频道弹窗点击切换频道
@@ -461,11 +462,13 @@ struct ChannelSubscriptionLayout { @@ -461,11 +462,13 @@ struct ChannelSubscriptionLayout {
461 let channelIdTmp = this.channelIds.splice(index1, 1) 462 let channelIdTmp = this.channelIds.splice(index1, 1)
462 this.myChannelList.splice(index2, 0, tmp[0]) 463 this.myChannelList.splice(index2, 0, tmp[0])
463 this.channelIds.splice(index2, 0, channelIdTmp[0]) 464 this.channelIds.splice(index2, 0, channelIdTmp[0])
  465 + this.storeChannelIds = this.channelIds.join(',')
464 } 466 }
465 //删除频道 467 //删除频道
466 delChannelItem = (index: number) => { 468 delChannelItem = (index: number) => {
467 let item = this.myChannelList.splice(index, 1)[0] 469 let item = this.myChannelList.splice(index, 1)[0]
468 this.channelIds.splice(index, 1) 470 this.channelIds.splice(index, 1)
  471 + this.storeChannelIds = this.channelIds.join(',')
469 if (item.moreChannel === '1') { 472 if (item.moreChannel === '1') {
470 this.moreChannelList.unshift(item) 473 this.moreChannelList.unshift(item)
471 } 474 }
@@ -477,6 +480,7 @@ struct ChannelSubscriptionLayout { @@ -477,6 +480,7 @@ struct ChannelSubscriptionLayout {
477 addChannelItem = (item: TopNavDTO) => { 480 addChannelItem = (item: TopNavDTO) => {
478 this.channelIds.push(item.channelId) 481 this.channelIds.push(item.channelId)
479 this.myChannelList.push(item) 482 this.myChannelList.push(item)
  483 + this.storeChannelIds = this.channelIds.join(',')
480 } 484 }
481 // @State currentTopNavSelectedIndex: number = 0 485 // @State currentTopNavSelectedIndex: number = 0
482 // @State topNavList: TopNavDTO [] = [ 486 // @State topNavList: TopNavDTO [] = [
@@ -1987,7 +1991,8 @@ struct ChannelSubscriptionLayout { @@ -1987,7 +1991,8 @@ struct ChannelSubscriptionLayout {
1987 dialogController: CustomDialogController | null = new CustomDialogController({ 1991 dialogController: CustomDialogController | null = new CustomDialogController({
1988 builder: ChannelDialog({ 1992 builder: ChannelDialog({
1989 currentTopNavSelectedIndex: $currentTopNavSelectedIndex, 1993 currentTopNavSelectedIndex: $currentTopNavSelectedIndex,
1990 - indexSettingArray: $indexSettingArray, 1994 + indexSettingChannelId: $indexSettingChannelId,
  1995 + homeChannelList: $homeChannelList,
1991 myChannelList: $myChannelList, 1996 myChannelList: $myChannelList,
1992 moreChannelList: $moreChannelList, 1997 moreChannelList: $moreChannelList,
1993 localChannelList: $localChannelList, 1998 localChannelList: $localChannelList,
@@ -2049,13 +2054,8 @@ struct ChannelSubscriptionLayout { @@ -2049,13 +2054,8 @@ struct ChannelSubscriptionLayout {
2049 // }) 2054 // })
2050 // } 2055 // }
2051 2056
2052 - onChannelIdsUpdate(){  
2053 - AppStorage.SetOrCreate('channelIds', this.channelIds.join(','));  
2054 - console.log(`AppStorage.get('channelIds')${AppStorage.get('channelIds')}`)  
2055 - }  
2056 2057
2057 aboutToAppear() { 2058 aboutToAppear() {
2058 - console.log(`myChannelListzz${this.channelIds}}`)  
2059 // this.topNavListHandle() 2059 // this.topNavListHandle()
2060 } 2060 }
2061 2061
@@ -64,13 +64,15 @@ export struct MinePageComponent { @@ -64,13 +64,15 @@ export struct MinePageComponent {
64 //Grid 区域 64 //Grid 区域
65 MinePagePersonFunctionUI({personalData:$personalData,isLogin:this.isLogin}) 65 MinePagePersonFunctionUI({personalData:$personalData,isLogin:this.isLogin})
66 //Card 66 //Card
67 - MinePageCardUI() 67 + //MinePageCardUI()
68 //创作者区域 68 //创作者区域
69 69
70 - MinePageCreatorFunctionUI({creatorData:$creatorData}) 70 + //MinePageCreatorFunctionUI({creatorData:$creatorData})
71 //更多功能 71 //更多功能
72 MinePageMoreFunctionUI({moreData:$moreData}) 72 MinePageMoreFunctionUI({moreData:$moreData})
73 }.width('100%') 73 }.width('100%')
  74 + .height('100%')
  75 + .justifyContent(FlexAlign.Start)
74 } 76 }
75 77
76 @Styles setFullWidthAndHeight(){ 78 @Styles setFullWidthAndHeight(){
@@ -3,10 +3,13 @@ import { LazyDataSource, Logger } from 'wdKit'; @@ -3,10 +3,13 @@ import { LazyDataSource, Logger } from 'wdKit';
3 import { WDRouterRule } from 'wdRouter'; 3 import { WDRouterRule } from 'wdRouter';
4 import { PageComponent } from './PageComponent'; 4 import { PageComponent } from './PageComponent';
5 import { ChannelSubscriptionLayout } from './ChannelSubscriptionLayout' 5 import { ChannelSubscriptionLayout } from './ChannelSubscriptionLayout'
  6 +import { FirstTabTopSearchComponent } from '../search/FirstTabTopSearchComponent';
6 7
7 const TAG = 'TopNavigationComponent'; 8 const TAG = 'TopNavigationComponent';
8 9
9 PersistentStorage.persistProp('channelIds', ''); 10 PersistentStorage.persistProp('channelIds', '');
  11 +PersistentStorage.persistProp('indexSettingChannelId', 0);
  12 +
10 /** 13 /**
11 * 顶部页签导航栏/顶导 14 * 顶部页签导航栏/顶导
12 */ 15 */
@@ -19,10 +22,12 @@ export struct TopNavigationComponent { @@ -19,10 +22,12 @@ export struct TopNavigationComponent {
19 // 顶导数据 22 // 顶导数据
20 @State @Watch('onTopNavigationDataUpdated') topNavList: TopNavDTO[] = [] 23 @State @Watch('onTopNavigationDataUpdated') topNavList: TopNavDTO[] = []
21 @State compList: LazyDataSource<CompDTO> = new LazyDataSource(); 24 @State compList: LazyDataSource<CompDTO> = new LazyDataSource();
  25 + @StorageProp('indexSettingChannelId') indexSettingChannelId: number = 0
22 //我的频道id列表 26 //我的频道id列表
23 - @State @Watch('onChannelIdsUpdate') channelIds: number[] = [] 27 + @State channelIds: number[] = []
24 //本地缓存频道id列表 28 //本地缓存频道id列表
25 @StorageProp('channelIds') storageChannelIds: string = '' 29 @StorageProp('channelIds') storageChannelIds: string = ''
  30 + @State homeChannelList: TopNavDTO[] = []
26 // 我的频道列表 31 // 我的频道列表
27 @State myChannelList: TopNavDTO[] = [] 32 @State myChannelList: TopNavDTO[] = []
28 // 更多频道列表 33 // 更多频道列表
@@ -31,33 +36,48 @@ export struct TopNavigationComponent { @@ -31,33 +36,48 @@ export struct TopNavigationComponent {
31 @State localChannelList: TopNavDTO[] = [] 36 @State localChannelList: TopNavDTO[] = []
32 readonly MAX_LINE: number = 1; 37 readonly MAX_LINE: number = 1;
33 38
34 - //处理接口顶导数据 39 + //处理新闻tab顶导频道数据
35 topNavListHandle() { 40 topNavListHandle() {
36 let _channelIds: number [] = [] 41 let _channelIds: number [] = []
37 - let _myChannelList : TopNavDTO [] = [] 42 + let _myChannelList: TopNavDTO [] = []
  43 + let _storageChannelIds: string [] = [] //list1
38 let defaultMyChannelList: TopNavDTO[] = [] 44 let defaultMyChannelList: TopNavDTO[] = []
39 - let handledTopNavList = [...this.topNavList]  
40 - handledTopNavList.sort((a, b) => { 45 + let defaultList = [...this.topNavList]
  46 + defaultList.sort((a, b) => {
41 return a.num - b.num; 47 return a.num - b.num;
42 }); 48 });
43 - handledTopNavList.forEach(item => { 49 +
  50 + //defaultMyChannelList
  51 + defaultList.forEach(item => {
44 if (item.defaultPermitted === 1 || item.movePermitted === 0 || item.delPermitted === 0 || item.headlinesOn === 1) { 52 if (item.defaultPermitted === 1 || item.movePermitted === 0 || item.delPermitted === 0 || item.headlinesOn === 1) {
45 defaultMyChannelList.push(item); 53 defaultMyChannelList.push(item);
46 } 54 }
  55 + if (item.defaultPermitted === 1) {
  56 + this.homeChannelList.push(item)
  57 + }
47 }) 58 })
48 59
  60 + //有缓存频道id
  61 + if (this.storageChannelIds) {
  62 + _storageChannelIds = this.storageChannelIds.split(',')
  63 + }
  64 +
49 defaultMyChannelList.forEach(item => { 65 defaultMyChannelList.forEach(item => {
50 item.myChannel = '1' 66 item.myChannel = '1'
51 if (item.defaultPermitted === 1) { 67 if (item.defaultPermitted === 1) {
52 item.homeChannel = '1' 68 item.homeChannel = '1'
53 } 69 }
54 - let index = handledTopNavList.findIndex(_item => _item.channelId === item.channelId) 70 + let index = defaultList.findIndex(_item => _item.channelId === item.channelId)
55 if (index !== -1) { 71 if (index !== -1) {
56 - handledTopNavList.splice(index, 1) 72 + defaultList.splice(index, 1)
57 } 73 }
58 }) 74 })
59 - handledTopNavList.unshift(...defaultMyChannelList)  
60 - handledTopNavList.forEach((item, index) => { 75 + defaultList.unshift(...defaultMyChannelList)
  76 +
  77 + defaultList.forEach((item, index) => {
  78 + if (this.storageChannelIds && _storageChannelIds.includes(String(item.channelId))) {
  79 + item.myChannel = '1'
  80 + }
61 if (item.channelType === 2) { 81 if (item.channelType === 2) {
62 item.localChannel = '1' 82 item.localChannel = '1'
63 } 83 }
@@ -75,118 +95,102 @@ export struct TopNavigationComponent { @@ -75,118 +95,102 @@ export struct TopNavigationComponent {
75 if (item.myChannel === '1') { 95 if (item.myChannel === '1') {
76 _myChannelList.push(item) 96 _myChannelList.push(item)
77 _channelIds.push(item.channelId) 97 _channelIds.push(item.channelId)
78 - }  
79 - if (item.moreChannel === '1') { 98 + } else if (item.moreChannel === '1') {
80 this.moreChannelList.push(item) 99 this.moreChannelList.push(item)
81 - }  
82 - if (item.localChannel === '1') { 100 + } else if (item.localChannel === '1') {
83 this.localChannelList.push(item) 101 this.localChannelList.push(item)
84 } 102 }
85 103
86 }) 104 })
  105 +
87 this.channelIds = _channelIds 106 this.channelIds = _channelIds
88 this.myChannelList = _myChannelList 107 this.myChannelList = _myChannelList
  108 +
  109 + //缓存首页频道
  110 + if (!this.indexSettingChannelId) {
  111 + AppStorage.set('indexSettingChannelId', this.homeChannelList[0].channelId)
  112 + } else {
  113 + let index = this.myChannelList.findIndex(_item => _item.channelId === this.indexSettingChannelId)
  114 + if (index > -1) {
  115 + this.currentTopNavSelectedIndex = index
  116 + }
  117 + }
89 } 118 }
90 119
91 isBroadcast(item: TopNavDTO) { 120 isBroadcast(item: TopNavDTO) {
92 return item.name === '播报' 121 return item.name === '播报'
93 } 122 }
94 123
  124 + isLayout(item: TopNavDTO) {
  125 + return item.name === '版面'
  126 + }
  127 +
  128 + jumpToENewPaper() {
  129 + let taskAction: Action = {
  130 + type: 'JUMP_INNER_NEW_PAGE',
  131 + params: {
  132 + pageID: 'E_NEWSPAPER'
  133 + } as Params,
  134 + };
  135 + WDRouterRule.jumpWithAction(taskAction)
  136 + }
  137 +
95 build() { 138 build() {
96 Column() { 139 Column() {
97 // 顶部搜索、日报logo、早晚报 140 // 顶部搜索、日报logo、早晚报
98 - RelativeContainer() {  
99 - Stack({ alignContent: Alignment.Center }) { 141 + Column() {
  142 + Row() {
  143 + FirstTabTopSearchComponent()
100 144
101 - Image($r('app.media.background_search'))  
102 - .width('100%')  
103 - .height('100%')  
104 - .objectFit(ImageFit.Contain) 145 + Image($r('app.media.icon_ren_min_ri_bao'))
  146 + .width(72)
  147 + .height(29)
  148 + .onClick((event: ClickEvent) => {
  149 + this.jumpToENewPaper()
  150 + })
105 151
106 - Row() {  
107 - Image($r('app.media.icon_search'))  
108 - .width(18)  
109 - .height(18)  
110 -  
111 - Text('河南大雪')  
112 - .fontColor($r('app.color.color_B0B0B0'))  
113 - .fontSize($r('app.float.font_size_13')) 152 + Stack({ alignContent: Alignment.Center }) {
  153 + Image($r('app.media.background_read_paper_home'))
  154 + .width('100%')
  155 + .height('100%')
  156 + .objectFit(ImageFit.Contain)
  157 + Row() {
  158 + Image($r('app.media.icon_read_paper_home'))
  159 + .width(18)
  160 + .height(18)
  161 + Text('早晚报')
  162 + .fontColor($r('app.color.color_B0B0B0'))
  163 + .fontSize($r('app.float.font_size_13'))
  164 + }
  165 + .alignItems(VerticalAlign.Center)
  166 + .justifyContent(FlexAlign.Center)
114 } 167 }
115 - .alignItems(VerticalAlign.Center)  
116 - .justifyContent(FlexAlign.Center)  
117 - }  
118 - .height(30)  
119 - .width(123)  
120 - .id('search')  
121 - .alignRules({  
122 - left: { anchor: "__container__", align: HorizontalAlign.Start },  
123 - center: { anchor: "__container__", align: VerticalAlign.Center }  
124 - })  
125 -  
126 - Image($r('app.media.icon_ren_min_ri_bao'))  
127 - .width(72)  
128 - .height(29)  
129 - .onClick((event: ClickEvent) => { 168 + .height(30)
  169 + .width(124)
  170 + .onClick(() => {
130 let taskAction: Action = { 171 let taskAction: Action = {
131 type: 'JUMP_INNER_NEW_PAGE', 172 type: 'JUMP_INNER_NEW_PAGE',
132 params: { 173 params: {
133 - pageID: 'E_NEWSPAPER' 174 + pageID: 'MorningEveningPaper'
134 } as Params, 175 } as Params,
135 }; 176 };
136 WDRouterRule.jumpWithAction(taskAction) 177 WDRouterRule.jumpWithAction(taskAction)
137 }) 178 })
138 - .id('ren_min')  
139 - .alignRules({  
140 - middle: { anchor: "__container__", align: HorizontalAlign.Center },  
141 - center: { anchor: "__container__", align: VerticalAlign.Center }  
142 - })  
143 -  
144 - Stack({ alignContent: Alignment.Center }) {  
145 - Image($r('app.media.background_read_paper_home'))  
146 - .width('100%')  
147 - .height('100%')  
148 - .objectFit(ImageFit.Contain)  
149 - Row() {  
150 - Image($r('app.media.icon_read_paper_home'))  
151 - .width(18)  
152 - .height(18)  
153 - Text('早晚报')  
154 - .fontColor($r('app.color.color_B0B0B0'))  
155 - .fontSize($r('app.float.font_size_13'))  
156 - }  
157 - .alignItems(VerticalAlign.Center)  
158 - .justifyContent(FlexAlign.Center)  
159 -  
160 - }  
161 - .height(30)  
162 - .width(124)  
163 - .id('read')  
164 - .alignRules({  
165 - right: { anchor: "__container__", align: HorizontalAlign.End },  
166 - center: { anchor: "__container__", align: VerticalAlign.Center }  
167 - })  
168 - .onClick((event: ClickEvent) => {  
169 -  
170 - let taskAction: Action = {  
171 - type: 'JUMP_INNER_NEW_PAGE',  
172 - params: {  
173 - pageID: 'MorningEveningPaper'  
174 - } as Params,  
175 - };  
176 - WDRouterRule.jumpWithAction(taskAction)  
177 - }) 179 + }.width('100%')
  180 + .justifyContent(FlexAlign.SpaceBetween)
178 } 181 }
179 .width('100%') 182 .width('100%')
180 .height(40) 183 .height(40)
  184 + .padding({ top: 10 })
  185 + .backgroundColor($r('app.color.white'))
181 .visibility(this._currentNavIndex == 0 ? Visibility.Visible : Visibility.None) 186 .visibility(this._currentNavIndex == 0 ? Visibility.Visible : Visibility.None)
182 187
183 // 频道分类list 188 // 频道分类list
184 Stack({ alignContent: Alignment.TopEnd }) { 189 Stack({ alignContent: Alignment.TopEnd }) {
185 -  
186 - Tabs({ controller: this.tabsController }) { 190 + Tabs({ index: this.currentTopNavSelectedIndex, controller: this.tabsController }) {
187 ForEach(this._currentNavIndex === 0 ? this.myChannelList : this.topNavList, (navItem: TopNavDTO, index: number) => { 191 ForEach(this._currentNavIndex === 0 ? this.myChannelList : this.topNavList, (navItem: TopNavDTO, index: number) => {
188 TabContent() { 192 TabContent() {
189 - if (!this.isBroadcast(navItem)) { 193 + if (!this.isBroadcast(navItem) && !this.isLayout(navItem)) {
190 PageComponent({ 194 PageComponent({
191 currentTopNavSelectedIndex: $currentTopNavSelectedIndex, 195 currentTopNavSelectedIndex: $currentTopNavSelectedIndex,
192 navIndex: index, 196 navIndex: index,
@@ -203,9 +207,12 @@ export struct TopNavigationComponent { @@ -203,9 +207,12 @@ export struct TopNavigationComponent {
203 .vertical(false) 207 .vertical(false)
204 .onChange((index: number) => { 208 .onChange((index: number) => {
205 Logger.info(TAG, `onChange index : ${index}`); 209 Logger.info(TAG, `onChange index : ${index}`);
206 - if (!this.isBroadcast(this.myChannelList[index])) { 210 + if (!this.isBroadcast(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index]) &&
  211 + !this.isLayout(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index])
  212 + ) {
207 this.currentTopNavSelectedIndex = index; 213 this.currentTopNavSelectedIndex = index;
208 - } else { 214 + }
  215 + if (this.isBroadcast(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index])) {
209 // 跳转到播报页面 216 // 跳转到播报页面
210 let taskAction: Action = { 217 let taskAction: Action = {
211 type: 'JUMP_INNER_NEW_PAGE', 218 type: 'JUMP_INNER_NEW_PAGE',
@@ -217,12 +224,18 @@ export struct TopNavigationComponent { @@ -217,12 +224,18 @@ export struct TopNavigationComponent {
217 WDRouterRule.jumpWithAction(taskAction) 224 WDRouterRule.jumpWithAction(taskAction)
218 this.tabsController.changeIndex(this.currentTopNavSelectedIndex) 225 this.tabsController.changeIndex(this.currentTopNavSelectedIndex)
219 } 226 }
  227 + if (this.isLayout(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index])) {
  228 + this.jumpToENewPaper()
  229 + this.tabsController.changeIndex(this.currentTopNavSelectedIndex)
  230 + }
220 }) 231 })
221 232
222 // 分类列表最右侧频道设置 233 // 分类列表最右侧频道设置
223 - if(this._currentNavIndex === 0){ 234 + if (this._currentNavIndex === 0) {
224 ChannelSubscriptionLayout({ 235 ChannelSubscriptionLayout({
225 currentTopNavSelectedIndex: $currentTopNavSelectedIndex, 236 currentTopNavSelectedIndex: $currentTopNavSelectedIndex,
  237 + indexSettingChannelId: this.indexSettingChannelId,
  238 + homeChannelList: this.homeChannelList,
226 myChannelList: $myChannelList, 239 myChannelList: $myChannelList,
227 moreChannelList: $moreChannelList, 240 moreChannelList: $moreChannelList,
228 localChannelList: $localChannelList, 241 localChannelList: $localChannelList,
@@ -270,15 +283,12 @@ export struct TopNavigationComponent { @@ -270,15 +283,12 @@ export struct TopNavigationComponent {
270 } 283 }
271 284
272 aboutToAppear() { 285 aboutToAppear() {
273 - if(this._currentNavIndex === 0){  
274 - this.topNavListHandle()  
275 - } 286 + //处理新闻tab顶导频道数据
  287 + this.topNavListHandle()
276 } 288 }
277 289
278 - onChannelIdsUpdate() { 290 + aboutToDisappear() {
279 AppStorage.set('channelIds', this.channelIds.join(',')) 291 AppStorage.set('channelIds', this.channelIds.join(','))
280 - console.log(`PersistentStorage channelIds: ${this.channelIds}`)  
281 - console.log(`PersistentStorage aboutToAppear: ${this.storageChannelIds}`)  
282 } 292 }
283 293
284 onTopNavigationDataUpdated() { 294 onTopNavigationDataUpdated() {
  1 +/**
  2 + * 首页顶部搜索导航栏
  3 + * 竖向滚动实现方案
  4 + * 方案一 使用动画 + 定时器
  5 + * 方案二 使用容器组件Swiper(当前)
  6 + */
  7 +import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
  8 +
  9 +const TAG = "FirstTabTopSearchComponent"
  10 +@Component
  11 +export struct FirstTabTopSearchComponent{
  12 + @State searchTextData :string[] = []
  13 + private swiperController: SwiperController = new SwiperController()
  14 +
  15 + aboutToAppear(){
  16 + this.getSearchHint()
  17 + }
  18 +
  19 + getSearchHint(){
  20 + SearcherAboutDataModel.getSearchHintData(getContext(this)).then((value)=>{
  21 + if(value!=null){
  22 + this.searchTextData = value
  23 + }
  24 + }).catch((err:Error)=>{
  25 + console.log(TAG,JSON.stringify(err))
  26 + })
  27 + }
  28 +
  29 + build(){
  30 + Row(){
  31 + Image($r('app.media.icon_search'))
  32 + .width(18)
  33 + .height(18)
  34 +
  35 + if(this.searchTextData!=null && this.searchTextData.length>0){
  36 + Swiper(this.swiperController) {
  37 + ForEach(this.searchTextData, (item: string, index: number ) => {
  38 + Text(item)
  39 + .fontWeight(400)
  40 + .fontColor($r('app.color.color_B0B0B0'))
  41 + .fontSize($r('app.float.font_size_13'))
  42 + .textAlign(TextAlign.Start)
  43 + .maxLines(1)
  44 + .textOverflow({ overflow: TextOverflow.Clip})
  45 + })
  46 + }
  47 + .loop(true)
  48 + .autoPlay(true)
  49 + .interval(3000)
  50 + .indicator(false)
  51 + .vertical(true)
  52 + .height(30)
  53 + }
  54 + }.height(30)
  55 + .width(124)
  56 + .padding({left:15})
  57 + .backgroundImage($r('app.media.background_search'))
  58 + .backgroundImageSize(ImageSize.Cover)
  59 + }
  60 +
  61 +}
@@ -12,6 +12,10 @@ import router from '@ohos.router'; @@ -12,6 +12,10 @@ import router from '@ohos.router';
12 import { WDRouterPage, WDRouterRule } from 'wdRouter'; 12 import { WDRouterPage, WDRouterRule } from 'wdRouter';
13 import { Params } from 'wdBean'; 13 import { Params } from 'wdBean';
14 import { SettingPasswordParams } from 'wdLogin'; 14 import { SettingPasswordParams } from 'wdLogin';
  15 +import { LoginViewModel } from 'wdLogin/src/main/ets/pages/login/LoginViewModel';
  16 +import { Router } from '@ohos.arkui.UIContext';
  17 +import promptAction from '@ohos.promptAction';
  18 +
15 export { SettingPasswordParams } from "wdLogin" 19 export { SettingPasswordParams } from "wdLogin"
16 20
17 @Component 21 @Component
@@ -83,16 +87,21 @@ export struct AccountAndSecurityLayout { @@ -83,16 +87,21 @@ export struct AccountAndSecurityLayout {
83 87
84 Column() { 88 Column() {
85 Button('退出登录',{ stateEffect: true ,type: ButtonType.Normal}).width('90%').height('80lpx').backgroundColor('#da3e22').fontColor('#fff').margin('20lpx').borderRadius('8lpx').onClick(()=>{ 89 Button('退出登录',{ stateEffect: true ,type: ButtonType.Normal}).width('90%').height('80lpx').backgroundColor('#da3e22').fontColor('#fff').margin('20lpx').borderRadius('8lpx').onClick(()=>{
86 - AlertDialog.show({  
87 - title: '🥟id : ' + "button",  
88 - message: '标题:' + '退出登录',  
89 - confirm: {  
90 - value: "OK",  
91 - action: () => {  
92 -  
93 - },  
94 - }  
95 - }) 90 + let login = new LoginViewModel;
  91 + promptAction.showToast({ message: '退出登录' })
  92 + login.logOut();
  93 + router.back();
  94 + router.back();
  95 + // AlertDialog.show({
  96 + // title: '🥟id : ' + "button",
  97 + // message: '标题:' + '退出登录',
  98 + // confirm: {
  99 + // value: "OK",
  100 + // action: () => {
  101 + //
  102 + // },
  103 + // }
  104 + // })
96 }) 105 })
97 } 106 }
98 107
1 -import { NewspaperListBean, NewspaperListItemBean, NewspaperPositionItemBean } from 'wdBean' 1 +import { Action, NewspaperListBean, NewspaperListItemBean, NewspaperPositionItemBean, Params } from 'wdBean'
  2 +import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO'
  3 +import { WDRouterRule } from 'wdRouter/Index'
2 import { ENewspaperPageDialog } from '../dialog/ENewspaperPageDialog' 4 import { ENewspaperPageDialog } from '../dialog/ENewspaperPageDialog'
3 5
4 /** 6 /**
@@ -143,6 +145,24 @@ export struct ENewspaperListDialog { @@ -143,6 +145,24 @@ export struct ENewspaperListDialog {
143 } 145 }
144 } 146 }
145 .alignItems(HorizontalAlign.Start) 147 .alignItems(HorizontalAlign.Start)
  148 + .onClick(() => {
  149 + let taskAction: Action = {
  150 + type: 'JUMP_INNER_NEW_PAGE',
  151 + params: {
  152 + contentID: '' + positionItem.newsId,
  153 + pageID: 'IMAGE_TEXT_DETAIL',
  154 + extra: {
  155 + relType: positionItem.relType ?? '',
  156 + relId: '' + positionItem.relId,
  157 + sourcePage: '5'
  158 + } as ExtraDTO
  159 + } as Params,
  160 + };
  161 + WDRouterRule.jumpWithAction(taskAction)
  162 + if (this.listDialogController) {
  163 + this.listDialogController.close()
  164 + }
  165 + })
146 } 166 }
147 167
148 }) 168 })
  1 +
  2 +import { Logger, ResourcesUtils } from 'wdKit';
  3 +import { HttpUrlUtils, ResponseDTO, WDHttp } from 'wdNetwork';
  4 +import HashMap from '@ohos.util.HashMap';
  5 +const TAG = "SearcherAboutDataModel"
  6 +
  7 +/**
  8 + * 我的页面 所有数据 获取封装类
  9 + */
  10 +class SearcherAboutDataModel{
  11 + private static instance: SearcherAboutDataModel;
  12 +
  13 + private constructor() { }
  14 +
  15 + /**
  16 + * 单例模式
  17 + * @returns
  18 + */
  19 + public static getInstance(): SearcherAboutDataModel {
  20 + if (!SearcherAboutDataModel.instance) {
  21 + SearcherAboutDataModel.instance = new SearcherAboutDataModel();
  22 + }
  23 + return SearcherAboutDataModel.instance;
  24 + }
  25 +
  26 + /**
  27 + * 首页 搜索提示滚动内容
  28 + */
  29 + getSearchHintData(context: Context): Promise<string[]> {
  30 + return new Promise<string[]>((success, error) => {
  31 + Logger.info(TAG, `getSearchHintData start`);
  32 + this.fetchSearchHintData().then((navResDTO: ResponseDTO<string[]>) => {
  33 + if (!navResDTO || navResDTO.code != 0) {
  34 + success(this.getSearchHintDataLocal(context))
  35 + return
  36 + }
  37 + Logger.info(TAG, "getSearchHintData then,SearchHintDataResDTO.timeStamp:" + navResDTO.timestamp);
  38 + let navigationBean = navResDTO.data as string[]
  39 + success(navigationBean);
  40 + }).catch((err: Error) => {
  41 + Logger.error(TAG, `fetchSearchHintData catch, error.name : ${err.name}, error.message:${err.message}`);
  42 + success(this.getSearchHintDataLocal(context))
  43 + })
  44 + })
  45 + }
  46 +
  47 + fetchSearchHintData() {
  48 + let url = HttpUrlUtils.getSearchHintDataUrl()
  49 + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
  50 + return WDHttp.get<ResponseDTO<string[]>>(url, headers)
  51 + };
  52 +
  53 + async getSearchHintDataLocal(context: Context): Promise<string[]> {
  54 + Logger.info(TAG, `getSearchHintDataLocal start`);
  55 + let compRes: ResponseDTO<string[]> | null = await ResourcesUtils.getResourcesJson<ResponseDTO<string[]>>(context,'search_hint_data.json' );
  56 + if (!compRes || !compRes.data) {
  57 + Logger.info(TAG, `getSearchHintDataLocal compRes is empty`);
  58 + return []
  59 + }
  60 + Logger.info(TAG, `getSearchHintDataLocal compRes : ${JSON.stringify(compRes)}`);
  61 + return compRes.data
  62 + }
  63 +
  64 +
  65 +
  66 +}
  67 +
  68 +const searcherAboutDataModel = SearcherAboutDataModel.getInstance()
  69 +export default searcherAboutDataModel as SearcherAboutDataModel
@@ -127,6 +127,14 @@ @@ -127,6 +127,14 @@
127 { 127 {
128 "name":"color_EEEEEE", 128 "name":"color_EEEEEE",
129 "value": "#EEEEEE" 129 "value": "#EEEEEE"
  130 + },
  131 + {
  132 + "name": "color_323232",
  133 + "value": "#323232"
  134 + },
  135 + {
  136 + "name": "color_48505A",
  137 + "value": "#48505A"
130 } 138 }
131 ] 139 ]
132 } 140 }
@@ -121,6 +121,7 @@ export class LoginModel { @@ -121,6 +121,7 @@ export class LoginModel {
121 bean['verifyCode'] = verifyCode 121 bean['verifyCode'] = verifyCode
122 bean['phone'] = phone 122 bean['phone'] = phone
123 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders(); 123 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
  124 + headers.set('cookie', '');
124 return new Promise<CheckVerifyBean>((success, fail) => { 125 return new Promise<CheckVerifyBean>((success, fail) => {
125 HttpRequest.post<ResponseDTO<CheckVerifyBean>>(HttpUrlUtils.getCheckVerifyCodeUrl(), bean, headers).then((data: ResponseDTO<CheckVerifyBean>) => { 126 HttpRequest.post<ResponseDTO<CheckVerifyBean>>(HttpUrlUtils.getCheckVerifyCodeUrl(), bean, headers).then((data: ResponseDTO<CheckVerifyBean>) => {
126 Logger.debug("LoginViewModel:success2 ", data.message) 127 Logger.debug("LoginViewModel:success2 ", data.message)
@@ -230,7 +231,7 @@ export class LoginModel { @@ -230,7 +231,7 @@ export class LoginModel {
230 231
231 return new Promise<string>((success, fail) => { 232 return new Promise<string>((success, fail) => {
232 HttpRequest.post<ResponseDTO<string>>(HttpUrlUtils.getLogoutUrl(), bean, headers).then((data: ResponseDTO<string>) => { 233 HttpRequest.post<ResponseDTO<string>>(HttpUrlUtils.getLogoutUrl(), bean, headers).then((data: ResponseDTO<string>) => {
233 - if (!data || !data.data) { 234 + if (!data) {
234 fail("数据为空") 235 fail("数据为空")
235 return 236 return
236 } 237 }
@@ -238,7 +239,7 @@ export class LoginModel { @@ -238,7 +239,7 @@ export class LoginModel {
238 fail(data.message) 239 fail(data.message)
239 return 240 return
240 } 241 }
241 - success(data.data) 242 + success('')
242 }, (error: Error) => { 243 }, (error: Error) => {
243 fail(error.message) 244 fail(error.message)
244 Logger.debug("LoginViewModel:error ", error.toString()) 245 Logger.debug("LoginViewModel:error ", error.toString())
@@ -105,12 +105,12 @@ struct LoginPage { @@ -105,12 +105,12 @@ struct LoginPage {
105 Text() { 105 Text() {
106 Span("我已阅读并同意").fontColor("#999999").fontSize(12) 106 Span("我已阅读并同意").fontColor("#999999").fontSize(12)
107 Span("《用户协议》").fontColor("#ED2800").fontSize(12).onClick(() => { 107 Span("《用户协议》").fontColor("#ED2800").fontSize(12).onClick(() => {
108 - let bean={contentId:"1",pageID:""} as Params 108 + let bean={contentID:"1",pageID:""} as Params
109 WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean) 109 WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean)
110 }) 110 })
111 Span("及").fontColor("#999999").fontSize(12) 111 Span("及").fontColor("#999999").fontSize(12)
112 Span("《隐私政策》").fontColor("#ED2800").fontSize(12).onClick(() => { 112 Span("《隐私政策》").fontColor("#ED2800").fontSize(12).onClick(() => {
113 - let bean={contentId:"2",pageID:""} as Params 113 + let bean={contentID:"2",pageID:""} as Params
114 WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean) 114 WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean)
115 }) 115 })
116 } 116 }
1 import router from '@ohos.router'; 1 import router from '@ohos.router';
2 import webview from '@ohos.web.webview'; 2 import webview from '@ohos.web.webview';
3 -import { Logger } from 'wdKit'; 3 +import { SpConstants } from 'wdConstant/Index';
  4 +import { Logger, SPHelper } from 'wdKit';
4 import { Params } from '../../../../../../../commons/wdRouter/oh_modules/wdBean/src/main/ets/bean/content/Params'; 5 import { Params } from '../../../../../../../commons/wdRouter/oh_modules/wdBean/src/main/ets/bean/content/Params';
5 6
6 7
@@ -11,14 +12,20 @@ const TAG = 'LoginProtocolWebview'; @@ -11,14 +12,20 @@ const TAG = 'LoginProtocolWebview';
11 struct LoginProtocolWebview { 12 struct LoginProtocolWebview {
12 webUrl: string = '' 13 webUrl: string = ''
13 webviewController: webview.WebviewController = new webview.WebviewController() 14 webviewController: webview.WebviewController = new webview.WebviewController()
  15 + userProtocol = "https://cdnpeoplefrontuat.aikan.pdnews.cn/rmrb/rmrb-protocol-zh-web/0.0.1/app/protocol-1005.html"
  16 + privateProtocol = 'https://cdnpeoplefrontuat.aikan.pdnews.cn/rmrb/rmrb-protocol-zh-web/0.0.1/app/protocol-1001.html'
14 17
15 - aboutToAppear() { 18 + async aboutToAppear() {
16 if (router.getParams()) { 19 if (router.getParams()) {
17 let params = router.getParams() as Params 20 let params = router.getParams() as Params
  21 + Logger.info(TAG, 'params.contentID:' + params.contentID);
18 if (params.contentID == "1") { 22 if (params.contentID == "1") {
19 - this.webUrl = "https://cdnpeoplefrontuat.aikan.pdnews.cn/rmrb/rmrb-protocol-zh-web/0.0.1/app/protocol-1005.html" 23 + this.webUrl = await SPHelper.default.get(SpConstants.USER_PROTOCOL, this.userProtocol) as string
  24 + this.webviewController.loadUrl(this.webUrl)
  25 +
20 } else { 26 } else {
21 - this.webUrl = "https://cdnpeoplefrontuat.aikan.pdnews.cn/rmrb/rmrb-protocol-zh-web/0.0.1/app/protocol-1001.html" 27 + this.webUrl = await SPHelper.default.get(SpConstants.PRIVATE_PROTOCOL, this.privateProtocol) as string
  28 + this.webviewController.loadUrl(this.webUrl)
22 } 29 }
23 } 30 }
24 31
@@ -33,7 +40,7 @@ struct LoginProtocolWebview { @@ -33,7 +40,7 @@ struct LoginProtocolWebview {
33 .aspectRatio(1) 40 .aspectRatio(1)
34 .onClick(() => { 41 .onClick(() => {
35 router.back(); 42 router.back();
36 - }).margin({left:16}) 43 + }).margin({ left: 16 })
37 Text() 44 Text()
38 } 45 }
39 .alignItems(VerticalAlign.Center) 46 .alignItems(VerticalAlign.Center)
@@ -5,6 +5,8 @@ import { SPHelper } from 'wdKit' @@ -5,6 +5,8 @@ import { SPHelper } from 'wdKit'
5 import { CheckVerifyBean } from './CheckVerifyBean' 5 import { CheckVerifyBean } from './CheckVerifyBean'
6 import cryptoFramework from '@ohos.security.cryptoFramework' 6 import cryptoFramework from '@ohos.security.cryptoFramework'
7 import buffer from '@ohos.buffer' 7 import buffer from '@ohos.buffer'
  8 +import { encryptMessage } from '../../utils/cryptoUtil'
  9 +
8 import { 10 import {
9 SpConstants 11 SpConstants
10 } from '../../../../../../../commons/wdNetwork/oh_modules/wdConstant/src/main/ets/constants/SpConstants' 12 } from '../../../../../../../commons/wdNetwork/oh_modules/wdConstant/src/main/ets/constants/SpConstants'
@@ -119,7 +121,8 @@ export class LoginViewModel { @@ -119,7 +121,8 @@ export class LoginViewModel {
119 //重置密码 需要老密码 121 //重置密码 需要老密码
120 resetPassword(password: string, tempToken: string) { 122 resetPassword(password: string, tempToken: string) {
121 return new Promise<string>(async (success, fail) => { 123 return new Promise<string>(async (success, fail) => {
122 - let passwordNew = await this.doMd(password) 124 +
  125 + let passwordNew = await encryptMessage(password);
123 this.loginModel.resetPassword(passwordNew, tempToken).then((data) => { 126 this.loginModel.resetPassword(passwordNew, tempToken).then((data) => {
124 success(data) 127 success(data)
125 }).catch((message: string) => { 128 }).catch((message: string) => {
@@ -132,7 +135,7 @@ export class LoginViewModel { @@ -132,7 +135,7 @@ export class LoginViewModel {
132 //忘记密码 135 //忘记密码
133 forgotPassword(password: string, tempToken: string) { 136 forgotPassword(password: string, tempToken: string) {
134 return new Promise<string>(async (success, fail) => { 137 return new Promise<string>(async (success, fail) => {
135 - let passwordNew = await this.doMd(password) 138 + let passwordNew = await encryptMessage(password)
136 this.loginModel.forgotPassword(passwordNew, tempToken).then((data) => { 139 this.loginModel.forgotPassword(passwordNew, tempToken).then((data) => {
137 success(data) 140 success(data)
138 }).catch((message: string) => { 141 }).catch((message: string) => {
@@ -146,9 +149,18 @@ export class LoginViewModel { @@ -146,9 +149,18 @@ export class LoginViewModel {
146 return new Promise<string>(async (success, fail) => { 149 return new Promise<string>(async (success, fail) => {
147 this.loginModel.logOut().then((data) => { 150 this.loginModel.logOut().then((data) => {
148 //清除登录状态以及token、userid等信息 151 //清除登录状态以及token、userid等信息
149 - HttpUrlUtils.setUserId('');  
150 - HttpUrlUtils.setUserType('');  
151 - HttpUrlUtils.setUserToken(''); 152 +
  153 + SPHelper.default.save(SpConstants.USER_FIRST_MARK, '')
  154 + SPHelper.default.save(SpConstants.USER_ID, '')
  155 + SPHelper.default.save(SpConstants.USER_JWT_TOKEN, '')
  156 + SPHelper.default.save(SpConstants.USER_LONG_TIME_NO_LOGIN_MARK, '')
  157 + SPHelper.default.save(SpConstants.USER_REFRESH_TOKEN, '')
  158 + SPHelper.default.save(SpConstants.USER_STATUS, '')
  159 + SPHelper.default.save(SpConstants.USER_Type, '')
  160 + SPHelper.default.save(SpConstants.USER_NAME, '')
  161 + HttpUrlUtils.setUserId("")
  162 + HttpUrlUtils.setUserType("")
  163 + HttpUrlUtils.setUserToken('')
152 success(data) 164 success(data)
153 }).catch((message: string) => { 165 }).catch((message: string) => {
154 fail(message) 166 fail(message)
@@ -188,7 +188,7 @@ export struct SettingPasswordLayout { @@ -188,7 +188,7 @@ export struct SettingPasswordLayout {
188 Row() { 188 Row() {
189 TextInput({ placeholder: item.inputPlacholder }) 189 TextInput({ placeholder: item.inputPlacholder })
190 .type(InputType.Password) 190 .type(InputType.Password)
191 - .showPasswordIcon(false) 191 + .showPasswordIcon(true)
192 .backgroundColor('#00000000') 192 .backgroundColor('#00000000')
193 .onChange((value: string) => { 193 .onChange((value: string) => {
194 this.inputTextChange(value, item.inputTag) 194 this.inputTextChange(value, item.inputTag)
  1 +import cryptoFramework from '@ohos.security.cryptoFramework';
  2 +import buffer from '@ohos.buffer';
  3 +import util from '@ohos.util';
  4 +
  5 +// 加密消息
  6 +
  7 +let pubKeyString = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAI05e8RfyEnLW/Un629lVJoVHntIanEAETot5nRcLmPJpXbC5lf5UgvVrDPPmoTxc567Hg9qq3AyAqWrSyqI6MECAwEAAQ==';
  8 +
  9 +async function encryptMessagePromise(publicKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) {
  10 + let cipher = cryptoFramework.createCipher('RSA1024|PKCS1');
  11 + await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null);
  12 + let encryptData = await cipher.doFinal(plainText);
  13 + return encryptData;
  14 +}
  15 +// 解密消息
  16 +async function decryptMessagePromise(privateKey: cryptoFramework.PriKey, cipherText: cryptoFramework.DataBlob) {
  17 + let decoder = cryptoFramework.createCipher('RSA1024|PKCS1');
  18 + await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, privateKey, null);
  19 + let decryptData = await decoder.doFinal(cipherText);
  20 + return decryptData;
  21 +}
  22 +
  23 +
  24 +// 生成RSA密钥对
  25 +async function genKeyPairByData() {
  26 +
  27 + let base64 = new util.Base64Helper();
  28 + let pubKeyData = base64.decodeSync(pubKeyString);
  29 +
  30 + let pkData = new Uint8Array(buffer.from(pubKeyString, 'utf-8').buffer)
  31 + let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyData };
  32 +
  33 + let pkData2 = new Uint8Array([48, 129, 159, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 141, 0, 48, 129, 137, 2, 129, 129, 0, 197, 64, 10, 198, 14, 110, 65, 92, 206, 35, 28, 123, 153, 24, 134, 255, 145, 74, 42, 173, 40, 215, 146, 58, 143, 46, 10, 195, 154, 160, 69, 196, 220, 152, 179, 44, 111, 200, 84, 78, 215, 73, 210, 181, 12, 29, 70, 68, 36, 135, 153, 89, 230, 202, 130, 212, 111, 243, 234, 92, 131, 62, 145, 50, 73, 48, 104, 245, 46, 70, 45, 157, 147, 143, 140, 162, 156, 216, 220, 49, 121, 142, 194, 33, 223, 201, 0, 16, 163, 210, 240, 118, 92, 147, 121, 220, 17, 114, 24, 52, 125, 135, 176, 88, 21, 83, 86, 17, 156, 88, 250, 48, 79, 86, 128, 248, 105, 208, 133, 140, 13, 153, 164, 191, 136, 164, 44, 53, 2, 3, 1, 0, 1]);
  34 + let pubKeyBlob2: cryptoFramework.DataBlob = { data: pkData2 };
  35 +
  36 + let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024');
  37 +
  38 +
  39 + rsaGenerator.convertKey(pubKeyBlob2, null, (err, keyPair) => {
  40 + if (err) {
  41 + console.error(`convertKey failed, ${err.code}, ${err.message}`);
  42 + }
  43 + console.info('convertKey success');
  44 + });
  45 +
  46 + rsaGenerator.convertKey(pubKeyBlob, null, (err, keyPair) => {
  47 + if (err) {
  48 + console.error(`convertKey failed, ${err.code}, ${err.message}`);
  49 + }
  50 + console.info('convertKey success');
  51 + });
  52 +
  53 + let keyPair = await rsaGenerator.convertKey(pubKeyBlob, null)
  54 + console.info('convertKey success');
  55 +
  56 +
  57 +
  58 +
  59 + return keyPair;
  60 +}
  61 +
  62 +export async function encryptMessage(text:string) {
  63 + let keyPair = await genKeyPairByData();
  64 + let pubKey = keyPair.pubKey;
  65 + let priKey = keyPair.priKey;
  66 + let message = text;
  67 + // 把字符串按utf-8解码为Uint8Array
  68 + let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
  69 + let encryptText = await encryptMessagePromise(pubKey, plainText);
  70 +
  71 + //base 64加密
  72 + let base64 = new util.Base64Helper();
  73 +
  74 + let result = base64.encodeToStringSync(encryptText.data);
  75 +
  76 + return result;
  77 +}
  1 +export interface AgreementBean{
  2 + description:string
  3 + linkUrl:string
  4 + name:string
  5 + plat:string
  6 + system:string
  7 + versionCode:string
  8 + versionId:string
  9 + type:number
  10 +}
@@ -8,6 +8,7 @@ import preferences from '@ohos.data.preferences' @@ -8,6 +8,7 @@ import preferences from '@ohos.data.preferences'
8 import { GlobalContext } from '../../utils/GlobalContext' 8 import { GlobalContext } from '../../utils/GlobalContext'
9 import { WDRouterRule } from 'wdRouter'; 9 import { WDRouterRule } from 'wdRouter';
10 import { WDRouterPage } from 'wdRouter'; 10 import { WDRouterPage } from 'wdRouter';
  11 +import { LaunchModel } from '../viewModel/LaunchModel'
11 12
12 @Entry 13 @Entry
13 @Component 14 @Component
@@ -85,6 +86,7 @@ struct LaunchPage { @@ -85,6 +86,7 @@ struct LaunchPage {
85 // let isJumpPrivacy: boolean = globalThis.isJumpPrivacy ?? false; 86 // let isJumpPrivacy: boolean = globalThis.isJumpPrivacy ?? false;
86 // let isJumpPrivacy: boolean = (GlobalContext.getContext().getObject('isJumpPrivacy') as boolean) ?? false; 87 // let isJumpPrivacy: boolean = (GlobalContext.getContext().getObject('isJumpPrivacy') as boolean) ?? false;
87 //if (!isJumpPrivacy) { 88 //if (!isJumpPrivacy) {
  89 + this.requestAgreement()
88 this.dialogController.open(); 90 this.dialogController.open();
89 // } 91 // }
90 } else { 92 } else {
@@ -146,6 +148,10 @@ struct LaunchPage { @@ -146,6 +148,10 @@ struct LaunchPage {
146 148
147 } 149 }
148 150
149 - 151 + requestAgreement() {
  152 + //请求隐私协议接口
  153 + let launchModel = new LaunchModel()
  154 + launchModel.getAgreement()
  155 + }
150 156
151 } 157 }
@@ -83,7 +83,7 @@ export default struct CustomDialogComponent { @@ -83,7 +83,7 @@ export default struct CustomDialogComponent {
83 .fontColor(Color.Red) 83 .fontColor(Color.Red)
84 .onClick(() => { 84 .onClick(() => {
85 85
86 - let bean={contentId:"1",pageID:""} as Params 86 + let bean={contentID:"2",pageID:""} as Params
87 WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean) 87 WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean)
88 88
89 //GlobalContext.getContext().setObject('isJumpPrivacy', true); 89 //GlobalContext.getContext().setObject('isJumpPrivacy', true);
@@ -100,7 +100,7 @@ export default struct CustomDialogComponent { @@ -100,7 +100,7 @@ export default struct CustomDialogComponent {
100 .fontColor(Color.Red) 100 .fontColor(Color.Red)
101 .onClick(() => { 101 .onClick(() => {
102 102
103 - let bean={contentId:"2",pageID:""} as Params 103 + let bean={contentID:"1",pageID:""} as Params
104 WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean) 104 WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean)
105 105
106 //GlobalContext.getContext().setObject('isJumpPrivacy', true); 106 //GlobalContext.getContext().setObject('isJumpPrivacy', true);
  1 +import { HttpUrlUtils, ResponseDTO } from 'wdNetwork/Index';
  2 +// import { HashMap } from '@kit.ArkTS';
  3 +import HashMap from '@ohos.util.HashMap';
  4 +import { AgreementBean } from '../launchPage/AgreementBean';
  5 +import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest';
  6 +import { Logger, SPHelper } from 'wdKit/Index';
  7 +import { SpConstants } from 'wdConstant/Index';
  8 +
  9 +export class LaunchModel {
  10 + getAgreement() {
  11 + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
  12 + return new Promise<AgreementBean>((success, fail) => {
  13 + HttpRequest.get<ResponseDTO<Array<AgreementBean>>>(HttpUrlUtils.getAgreement(), headers).then((data: ResponseDTO<Array<AgreementBean>>) => {
  14 + if (!data || !data.data) {
  15 + fail("数据为空")
  16 + return
  17 + }
  18 + if (data.code != 0) {
  19 + fail(data.message)
  20 + return
  21 + }
  22 + Logger.debug("LaunchModel:success2 ", JSON.stringify(data))
  23 + //保存数据
  24 + for (let i = 0; i < data.data.length; i++) {
  25 + if (data.data[i].type == 1) {
  26 + SPHelper.default.save(SpConstants.USER_PROTOCOL, data.data[i].linkUrl)
  27 + } else if (data.data[i].type == 2) {
  28 + SPHelper.default.save(SpConstants.PRIVATE_PROTOCOL, data.data[i].linkUrl)
  29 + }
  30 + }
  31 +
  32 + }, (error: Error) => {
  33 + Logger.debug("LaunchModel:error2 ", error.toString())
  34 + fail(error.message)
  35 + })
  36 + })
  37 + }
  38 +}
  1 +{
  2 + "code": "0",
  3 + "data": [
  4 + "习语",
  5 + "党史学习",
  6 + "高考倒计时"
  7 + ],
  8 + "message": "Success",
  9 + "success": true,
  10 + "timestamp": 1712562841885
  11 +}