zhangbo1_wd

合入4.0 互动数据接口相关代码

@@ -17,7 +17,9 @@ export { Action } from './src/main/ets/bean/content/Action' @@ -17,7 +17,9 @@ export { Action } from './src/main/ets/bean/content/Action'
17 export { Params } from './src/main/ets/bean/content/Params' 17 export { Params } from './src/main/ets/bean/content/Params'
18 18
19 export { Pic } from './src/main/ets/bean/content/Pic' 19 export { Pic } from './src/main/ets/bean/content/Pic'
20 - 20 +export { InteractDataDTO } from './src/main/ets/bean/content/InteractDataDTO';
  21 +export { InteractParam } from './src/main/ets/bean/content/InteractParam';
  22 +export { ContentBean } from './src/main/ets/bean/content/ContentBean';
21 export { LabelBean } from './src/main/ets/bean/component/extra/LabelBean'; 23 export { LabelBean } from './src/main/ets/bean/component/extra/LabelBean';
22 24
23 export { LabelDTO } from './src/main/ets/bean/component/extra/LabelDTO'; 25 export { LabelDTO } from './src/main/ets/bean/component/extra/LabelDTO';
1 import { FullColumnImgUrlDTO } from '../detail/FullColumnImgUrlDTO'; 1 import { FullColumnImgUrlDTO } from '../detail/FullColumnImgUrlDTO';
2 import { LiveInfoDTO } from '../detail/LiveInfoDTO'; 2 import { LiveInfoDTO } from '../detail/LiveInfoDTO';
3 import { VideoInfoDTO } from '../detail/VideoInfoDTO'; 3 import { VideoInfoDTO } from '../detail/VideoInfoDTO';
4 - 4 +import { InteractDataDTO } from './src/main/ets/bean/content/InteractDataDTO';
5 export interface ContentDTO { 5 export interface ContentDTO {
6 cityCode: string; 6 cityCode: string;
7 coverSize: string; 7 coverSize: string;
@@ -54,4 +54,7 @@ export interface ContentDTO { @@ -54,4 +54,7 @@ export interface ContentDTO {
54 videoInfo?: VideoInfoDTO; // 视频新闻信息【BFF聚合】,视频非原片+清晰度最高的 54 videoInfo?: VideoInfoDTO; // 视频新闻信息【BFF聚合】,视频非原片+清晰度最高的
55 55
56 newsSummary: string; //appstyle:2 ,新闻详情 56 newsSummary: string; //appstyle:2 ,新闻详情
  57 +
  58 + // 二次请求接口,返回的数据,这里组装到content里;TODO 后续优化
  59 + interactData:InteractDataDTO;
57 } 60 }
  1 +/**
  2 + * 批查接口查询互动相关数据,返回数据bean
  3 + */
  4 +export interface InteractDataDTO {
  5 + collectNum: number;
  6 + commentNum: number;
  7 + contentId: string;
  8 + contentType: number;
  9 + likeNum: number;
  10 + readNum: number;
  11 + shareNum: number;
  12 +}
  1 +/**
  2 + * 批查接口查询互动相关数据,返回数据bean
  3 + */
  4 +export interface InteractParam {
  5 + contentList: Array<ContentBean>;
  6 + // 默认0;是否详情页访问;默认0:非详情;1:详情页(只有访问详情页时(detail=1),才触发浏览量加1)
  7 + detail: string;
  8 +}
  9 +
  10 +export interface ContentBean {
  11 + contentId: string;
  12 + contentType: string;
  13 +}
1 import HashMap from '@ohos.util.HashMap'; 1 import HashMap from '@ohos.util.HashMap';
2 import { HttpUrlUtils, ResponseDTO, WDHttp } from 'wdNetwork'; 2 import { HttpUrlUtils, ResponseDTO, WDHttp } from 'wdNetwork';
3 import { DateTimeUtils } from 'wdKit'; 3 import { DateTimeUtils } from 'wdKit';
4 -import { ContentDetailDTO, NavigationBodyDTO, PageDTO } from 'wdBean'; 4 +import { ContentDetailDTO, NavigationBodyDTO, PageDTO,InteractDataDTO } from 'wdBean';
5 5
6 export class PageRepository { 6 export class PageRepository {
7 static getBottomNavGroupUrl() { 7 static getBottomNavGroupUrl() {
@@ -35,6 +35,11 @@ export class PageRepository { @@ -35,6 +35,11 @@ export class PageRepository {
35 return url; 35 return url;
36 } 36 }
37 37
  38 + static getInteractDataUrl() {
  39 + let url = HttpUrlUtils.getHost() + this.INTERACT_DATA_PATH;
  40 + return url;
  41 + }
  42 +
38 static fetchNavigationDataApi() { 43 static fetchNavigationDataApi() {
39 let url = PageRepository.getBottomNavGroupUrl(); 44 let url = PageRepository.getBottomNavGroupUrl();
40 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders(); 45 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
@@ -52,4 +57,10 @@ export class PageRepository { @@ -52,4 +57,10 @@ export class PageRepository {
52 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders(); 57 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
53 return WDHttp.get<ResponseDTO<ContentDetailDTO>>(url, headers) 58 return WDHttp.get<ResponseDTO<ContentDetailDTO>>(url, headers)
54 }; 59 };
  60 +
  61 + static fetchInteractData(param: object) {
  62 + let url = HttpUrlUtils.getInteractDataUrl()
  63 + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
  64 + return WDHttp.post<ResponseDTO<InteractDataDTO[]>>(url, param, headers)
  65 + };
55 } 66 }
@@ -13,12 +13,12 @@ export class RefreshConstants { @@ -13,12 +13,12 @@ export class RefreshConstants {
13 /** 13 /**
14 * The delay time. 14 * The delay time.
15 */ 15 */
16 - static readonly DELAY_TIME: number = 1000; 16 + static readonly DELAY_TIME: number = 200;
17 17
18 /** 18 /**
19 * The animation duration. 19 * The animation duration.
20 */ 20 */
21 - static readonly ANIMATION_DURATION: number = 2000; 21 + static readonly ANIMATION_DURATION: number = 200;
22 /** 22 /**
23 * The RefreshConstant constants. 23 * The RefreshConstant constants.
24 */ 24 */
1 -import { NavigationBodyDTO, PageDTO } from 'wdBean';  
2 -import { Logger, ResourcesUtils } from 'wdKit'; 1 +import { NavigationBodyDTO, PageDTO,InteractDataDTO,ContentBean, InteractParam,CompDTO } from 'wdBean';
  2 +import { CollectionUtils, Logger, ResourcesUtils, StringUtils } from 'wdKit';
3 import { ResponseDTO, } from 'wdNetwork'; 3 import { ResponseDTO, } from 'wdNetwork';
4 import { PageRepository } from '../repository/PageRepository'; 4 import { PageRepository } from '../repository/PageRepository';
5 import { BaseViewModel } from './BaseViewModel'; 5 import { BaseViewModel } from './BaseViewModel';
@@ -10,7 +10,11 @@ const TAG = 'PageViewModel'; @@ -10,7 +10,11 @@ const TAG = 'PageViewModel';
10 * mock数据是本地json数据,可自行修改内容(‘entry\src\main\resources\rawfile\’目录) 10 * mock数据是本地json数据,可自行修改内容(‘entry\src\main\resources\rawfile\’目录)
11 */ 11 */
12 const mock_switch = false; 12 const mock_switch = false;
13 - 13 +/**
  14 + * 互动数据获取开关开关,默认开。
  15 + * TODO 后续需要优化掉,变为二次请求异步刷新
  16 + */
  17 +const interact_sync_switch = true;
14 /** 18 /**
15 * 处理返回后的数据 19 * 处理返回后的数据
16 */ 20 */
@@ -123,7 +127,18 @@ export class PageViewModel extends BaseViewModel { @@ -123,7 +127,18 @@ export class PageViewModel extends BaseViewModel {
123 return 127 return
124 } 128 }
125 Logger.info(TAG, "getNavData then,resDTO.timestamp:" + resDTO.timestamp); 129 Logger.info(TAG, "getNavData then,resDTO.timestamp:" + resDTO.timestamp);
126 - success(resDTO.data); 130 + if (!interact_sync_switch) {
  131 + success(resDTO.data);
  132 + return;
  133 + }
  134 + // TODO 打开同步请求互动数据,待优化为异步加载
  135 + if (CollectionUtils.isEmpty(resDTO.data.compList)) {
  136 + success(resDTO.data);
  137 + } else {
  138 + this.getInteractData(resDTO.data.compList).then(() => {
  139 + success(resDTO.data);
  140 + })
  141 + }
127 }) 142 })
128 .catch((err: Error) => { 143 .catch((err: Error) => {
129 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`); 144 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`);
@@ -131,6 +146,122 @@ export class PageViewModel extends BaseViewModel { @@ -131,6 +146,122 @@ export class PageViewModel extends BaseViewModel {
131 }) 146 })
132 }) 147 })
133 } 148 }
  149 +
  150 + async getInteractData(compList: CompDTO[]) {
  151 + let param: InteractParam = this.getInteractParams(compList);
  152 + const SIZE = 20;
  153 + // 批查接口,参数size限制20,这里截断分批查询,0,20;20,40...
  154 + let count = Math.ceil(param.contentList.length / SIZE);
  155 + let promises = new Array;
  156 + if (count == 1) {
  157 + let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(param);
  158 + promises.push(promise);
  159 + } else {
  160 + for (let i = 1;i <= count; i++) {
  161 + // 将查询参数截断(参数限制20个),分批请求接口
  162 + let subList = new Array<ContentBean>();
  163 + let start = 0;
  164 + let end = 0;
  165 + if (i == count) {
  166 + start = (i - 1) * SIZE;
  167 + end = param.contentList.length;
  168 + subList = CollectionUtils.getSubElements(param.contentList, start, end)
  169 + } else {
  170 + start = (i - 1) * SIZE;
  171 + end = start + SIZE;
  172 + subList = CollectionUtils.getSubElements(param.contentList, start, end)
  173 + }
  174 + let subParam: InteractParam = {} as InteractParam;
  175 + subParam.contentList = subList;
  176 + let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(subParam);
  177 + promises.push(promise);
  178 + }
  179 + }
  180 +
  181 + return new Promise<CompDTO[]>((success, error) => {
  182 + Promise.all(promises).then((result) => {
  183 + if (!CollectionUtils.isArray(result)) {
  184 + success(compList);
  185 + return;
  186 + }
  187 +
  188 + let allInteractDataList = new Array();
  189 + result.forEach((value: InteractDataDTO[]) => {
  190 + if (value != null && value.length > 0) {
  191 + allInteractDataList.push(...value);
  192 + }
  193 + })
  194 + // 批查全部完成,统一设置到comp里
  195 + this.resetInteract(allInteractDataList, compList);
  196 + success(compList);
  197 + })
  198 + })
  199 + }
  200 +
  201 + private createInteractDataPromise(param: InteractParam) {
  202 + return new Promise<InteractDataDTO[]>((success, error) => {
  203 + PageRepository.fetchInteractData(param).then((resDTO: ResponseDTO<InteractDataDTO[]>) => {
  204 + if (this.isRespondsInvalid(resDTO, 'getInteractData')) {
  205 + Logger.info(TAG, "getInteractData then,resDTO.timeStamp:" + resDTO.timestamp);
  206 + success(null);
  207 + return;
  208 + }
  209 + success(resDTO.data);
  210 + }).catch((err: Error) => {
  211 + Logger.error(TAG, `getInteractData catch, error.name : ${err.name}, error.message:${err.message}`);
  212 + // 无论是否成功(暂不做重试),都回调结果,通知刷新数据
  213 + success(null);
  214 + })
  215 + });
  216 + }
  217 +
  218 + private resetInteract(interact: InteractDataDTO[], compList: CompDTO[]) {
  219 + if (interact == null || interact.length == 0) {
  220 + return
  221 + }
  222 + interact.forEach((interactData) => {
  223 + let id = interactData.contentId;
  224 + outer: for (let i = 0;i < compList.length; i++) {
  225 + let comp = compList[i];
  226 + if (comp == null || comp.operDataList == null || comp.operDataList.length == 0) {
  227 + continue;
  228 + }
  229 + for (let j = 0;j < comp.operDataList.length; j++) {
  230 + let content = comp.operDataList[j];
  231 + if (content == null) {
  232 + continue;
  233 + }
  234 + if (id == content.objectId) {
  235 + content.interactData = interactData;
  236 + break outer;
  237 + }
  238 + }
  239 + }
  240 + })
  241 + }
  242 +
  243 + private getInteractParams(compList: CompDTO[]): InteractParam {
  244 + if (compList == null || compList.length == 0) {
  245 + return null;
  246 + }
  247 +
  248 + let param: InteractParam = {} as InteractParam;
  249 + param.contentList = new Array<ContentBean>();
  250 + compList.forEach((value) => {
  251 + let contentList = value.operDataList;
  252 + if (contentList != null && contentList.length > 0) {
  253 + contentList.forEach((v) => {
  254 + if (StringUtils.isNotEmpty(v.objectId)) {
  255 + let bean = {} as ContentBean;
  256 + bean.contentId = v.objectId;
  257 + bean.contentType = v.objectType;
  258 + param.contentList.push(bean);
  259 + }
  260 + })
  261 + }
  262 + })
  263 + return param;
  264 + }
134 } 265 }
135 266
136 267
@@ -160,5 +160,24 @@ export class CollectionUtils { @@ -160,5 +160,24 @@ export class CollectionUtils {
160 const arr = unescape(encodeURIComponent(str)).split('').map(val => val.charCodeAt(0)); 160 const arr = unescape(encodeURIComponent(str)).split('').map(val => val.charCodeAt(0));
161 return new Uint8Array(arr); 161 return new Uint8Array(arr);
162 } 162 }
  163 +
  164 + /**
  165 + * 截取集合部分数据。
  166 + * start:0 - end:20 截取0-19,共20个数据
  167 + */
  168 + static getSubElements(collection?: any[], start?: number, end?: number): any[] {
  169 + if (CollectionUtils.isEmpty(collection) || start === undefined || end === undefined) {
  170 + return null;
  171 + }
  172 + if (start < 0 || end < start) {
  173 + return null;
  174 + }
  175 + if (end > collection.length) {
  176 + return null;
  177 + }
  178 + let ss = collection.slice(start, end);
  179 + ss;
  180 + return collection.slice(start, end);
  181 + }
163 } 182 }
164 183
@@ -56,13 +56,24 @@ export class HttpRequest { @@ -56,13 +56,24 @@ export class HttpRequest {
56 return service.get(url, config) 56 return service.get(url, config)
57 } 57 }
58 58
59 - static post<T = ResponseDTO<string>>(url: string, data?: object, headers?: HashMap<string, string>): Promise<T> { 59 + static post0<T = ResponseDTO<string>>(url: string, data?: object, headers?: HashMap<string, string>): Promise<T> {
60 let config: AxiosRequestConfig = { 60 let config: AxiosRequestConfig = {
61 headers: HttpRequest.buildHeaderWithGlobalHeader(headers) 61 headers: HttpRequest.buildHeaderWithGlobalHeader(headers)
62 } 62 }
63 return service.post(url, data, config) 63 return service.post(url, data, config)
64 } 64 }
65 65
  66 + static post<T = any>(url: string, data1?: any, headers?: HashMap<string, string>): Promise<T> {
  67 + let requestHeaders: AxiosHeaders = new AxiosHeaders()
  68 + headers?.forEach((v, k) => {
  69 + requestHeaders.set(k, v);
  70 + });
  71 + let config: AxiosRequestConfig = {
  72 + headers: requestHeaders as RawAxiosRequestHeaders,
  73 + }
  74 + return service.post(url, data1, config)
  75 + }
  76 +
66 static put<T = ResponseDTO<string>>(url: string, data?: object, headers?: HashMap<string, string>): Promise<T> { 77 static put<T = ResponseDTO<string>>(url: string, data?: object, headers?: HashMap<string, string>): Promise<T> {
67 let config: AxiosRequestConfig = { 78 let config: AxiosRequestConfig = {
68 headers: HttpRequest.buildHeaderWithGlobalHeader(headers) 79 headers: HttpRequest.buildHeaderWithGlobalHeader(headers)
@@ -34,7 +34,10 @@ export class HttpUrlUtils { @@ -34,7 +34,10 @@ export class HttpUrlUtils {
34 * 详情页面详情接口 34 * 详情页面详情接口
35 */ 35 */
36 static readonly DETAIL_PATH: string = "/api/rmrb-bff-display-zh/content/zh/c/content/detail"; 36 static readonly DETAIL_PATH: string = "/api/rmrb-bff-display-zh/content/zh/c/content/detail";
37 - 37 + /**
  38 + * 批查接口,查询互动相关数据,如收藏数、评论数等
  39 + */
  40 + static readonly INTERACT_DATA_PATH: string = "/api/rmrb-contact/contact/zh/c/content/interactData";
38 private static hostUrl: string = HttpUrlUtils.HOST_PRODUCT; 41 private static hostUrl: string = HttpUrlUtils.HOST_PRODUCT;
39 42
40 static getCommonHeaders(): HashMap<string, string> { 43 static getCommonHeaders(): HashMap<string, string> {
@@ -55,8 +58,8 @@ export class HttpUrlUtils { @@ -55,8 +58,8 @@ export class HttpUrlUtils {
55 //headers.set('X-Ca-Stage', 'PRE') 58 //headers.set('X-Ca-Stage', 'PRE')
56 headers.set('versionCode', HttpUrlUtils.getVersionCode()) 59 headers.set('versionCode', HttpUrlUtils.getVersionCode())
57 headers.set('system', HttpUrlUtils.getTerminalId()) 60 headers.set('system', HttpUrlUtils.getTerminalId())
58 - headers.set('version_name', 'debug')  
59 - headers.set('EagleEye-TraceID', '0B6DE03D2997435BA875FFBE05425ED2') 61 + headers.set('version_name', this.getVersionName())
  62 + headers.set('EagleEye-TraceID', 'D539562E48554A60977AF4BECB6D6C7A')
60 headers.set('imei', HttpUrlUtils.getImei()) 63 headers.set('imei', HttpUrlUtils.getImei())
61 headers.set('Accept-Language', 'zh') 64 headers.set('Accept-Language', 'zh')
62 headers.set('city', HttpUrlUtils.getCity()) 65 headers.set('city', HttpUrlUtils.getCity())
@@ -64,6 +67,8 @@ export class HttpUrlUtils { @@ -64,6 +67,8 @@ export class HttpUrlUtils {
64 // TODO 判断是否登录 67 // TODO 判断是否登录
65 headers.set('userId', HttpUrlUtils.getUserId()) 68 headers.set('userId', HttpUrlUtils.getUserId())
66 headers.set('userType', HttpUrlUtils.getUserType()) 69 headers.set('userType', HttpUrlUtils.getUserType())
  70 +
  71 + headers.set('mpassid', 'ZbHTMeTsfaYDAHqt8ZHIzcPs')
67 HttpUrlUtils.addSpecialHeaders(headers); 72 HttpUrlUtils.addSpecialHeaders(headers);
68 // Logger.debug("TAG", '******************* commonHeaders headers start ******************************** '); 73 // Logger.debug("TAG", '******************* commonHeaders headers start ******************************** ');
69 // headers.forEach((v,k)=>{ 74 // headers.forEach((v,k)=>{
@@ -131,12 +136,12 @@ export class HttpUrlUtils { @@ -131,12 +136,12 @@ export class HttpUrlUtils {
131 136
132 private static getDeviceId() { 137 private static getDeviceId() {
133 // TODO 138 // TODO
134 - return 'b5cf725d-193d-3215-8c77-e76fe15ce64d'; 139 + return '8a81226a-cabd-3e1b-b630-b51db4a720ed';
135 } 140 }
136 141
137 private static getVersion() { 142 private static getVersion() {
138 // TODO 143 // TODO
139 - return '202312251034'; 144 + return '202401242103';
140 } 145 }
141 146
142 private static getVersionCode() { 147 private static getVersionCode() {
@@ -144,13 +149,18 @@ export class HttpUrlUtils { @@ -144,13 +149,18 @@ export class HttpUrlUtils {
144 return '7301'; 149 return '7301';
145 } 150 }
146 151
  152 + private static getVersionName() {
  153 + // TODO
  154 + return '7.3.0.1';
  155 + }
  156 +
147 private static getAdCode() { 157 private static getAdCode() {
148 return '340000'; 158 return '340000';
149 } 159 }
150 160
151 private static getOsVersion() { 161 private static getOsVersion() {
152 // TODO 162 // TODO
153 - return '13'; 163 + return '12';
154 } 164 }
155 165
156 public static getCityCode() { 166 public static getCityCode() {
@@ -177,7 +187,7 @@ export class HttpUrlUtils { @@ -177,7 +187,7 @@ export class HttpUrlUtils {
177 187
178 private static getImei() { 188 private static getImei() {
179 // TODO 189 // TODO
180 - return 'b5cf725d-193d-3215-8c77-e76fe15ce64d'; 190 + return '8a81226a-cabd-3e1b-b630-b51db4a720ed';
181 } 191 }
182 192
183 private static getUserId() { 193 private static getUserId() {