zhangbo1_wd

新增互动数据接口,页面添加互动数据的请求

@@ -35,7 +35,11 @@ export class HttpUrlUtils { @@ -35,7 +35,11 @@ export class HttpUrlUtils {
35 * 详情页面详情接口 35 * 详情页面详情接口
36 */ 36 */
37 static readonly DETAIL_PATH: string = "/api/rmrb-bff-display-zh/content/zh/c/content/detail"; 37 static readonly DETAIL_PATH: string = "/api/rmrb-bff-display-zh/content/zh/c/content/detail";
38 - private static hostUrl: string = HttpUrlUtils.HOST_PRODUCT; 38 + /**
  39 + * 批查接口,查询互动相关数据,如收藏数、评论数等
  40 + */
  41 + static readonly INTERACT_DATA_PATH: string = "/api/rmrb-contact/contact/zh/c/content/interactData";
  42 + private static hostUrl: string = HttpUrlUtils.HOST_UAT;
39 43
40 static getCommonHeaders(): HashMap<string, string> { 44 static getCommonHeaders(): HashMap<string, string> {
41 let headers: HashMap<string, string> = new HashMap<string, string>() 45 let headers: HashMap<string, string> = new HashMap<string, string>()
@@ -52,12 +56,15 @@ export class HttpUrlUtils { @@ -52,12 +56,15 @@ export class HttpUrlUtils {
52 headers.set('os_version', this.getOsVersion()) 56 headers.set('os_version', this.getOsVersion())
53 headers.set('versionCode', this.getVersionCode()) 57 headers.set('versionCode', this.getVersionCode())
54 headers.set('system', this.getTerminalId()) 58 headers.set('system', this.getTerminalId())
55 - headers.set('version_name', 'debug')  
56 - headers.set('EagleEye-TraceID', '0B6DE03D2997435BA875FFBE05425ED2') 59 + headers.set('version_name', this.getVersionName())
  60 + headers.set('EagleEye-TraceID', 'D539562E48554A60977AF4BECB6D6C7A')
57 headers.set('imei', this.getImei()) 61 headers.set('imei', this.getImei())
58 headers.set('Accept-Language', 'zh') 62 headers.set('Accept-Language', 'zh')
59 headers.set('city', this.getCity()) 63 headers.set('city', this.getCity())
60 headers.set('city_dode', this.getCityCode()) 64 headers.set('city_dode', this.getCityCode())
  65 +
  66 + headers.set('mpassid', 'ZbHTMeTsfaYDAHqt8ZHIzcPs')
  67 +
61 // TODO 判断是否登录 68 // TODO 判断是否登录
62 headers.set('userId', this.getUserId()) 69 headers.set('userId', this.getUserId())
63 headers.set('userType', this.getUserType()) 70 headers.set('userType', this.getUserType())
@@ -107,6 +114,11 @@ export class HttpUrlUtils { @@ -107,6 +114,11 @@ export class HttpUrlUtils {
107 return url; 114 return url;
108 } 115 }
109 116
  117 + static getInteractDataUrl() {
  118 + let url = this.hostUrl + this.INTERACT_DATA_PATH;
  119 + return url;
  120 + }
  121 +
110 static addSpecialHeaders(headers: HashMap<string, string>) { 122 static addSpecialHeaders(headers: HashMap<string, string>) {
111 switch (this.hostUrl) { 123 switch (this.hostUrl) {
112 case this.HOST_UAT: 124 case this.HOST_UAT:
@@ -161,12 +173,12 @@ export class HttpUrlUtils { @@ -161,12 +173,12 @@ export class HttpUrlUtils {
161 173
162 private static getDeviceId() { 174 private static getDeviceId() {
163 // TODO 175 // TODO
164 - return 'b5cf725d-193d-3215-8c77-e76fe15ce64d'; 176 + return '8a81226a-cabd-3e1b-b630-b51db4a720ed';
165 } 177 }
166 178
167 private static getVersion() { 179 private static getVersion() {
168 // TODO 180 // TODO
169 - return '202312251034'; 181 + return '202401242103';
170 } 182 }
171 183
172 private static getVersionCode() { 184 private static getVersionCode() {
@@ -174,13 +186,18 @@ export class HttpUrlUtils { @@ -174,13 +186,18 @@ export class HttpUrlUtils {
174 return '7301'; 186 return '7301';
175 } 187 }
176 188
  189 + private static getVersionName() {
  190 + // TODO
  191 + return '7.3.0.1';
  192 + }
  193 +
177 private static getAdCode() { 194 private static getAdCode() {
178 return '340000'; 195 return '340000';
179 } 196 }
180 197
181 private static getOsVersion() { 198 private static getOsVersion() {
182 // TODO 199 // TODO
183 - return '13'; 200 + return '12';
184 } 201 }
185 202
186 private static getCityCode() { 203 private static getCityCode() {
@@ -207,7 +224,7 @@ export class HttpUrlUtils { @@ -207,7 +224,7 @@ export class HttpUrlUtils {
207 224
208 private static getImei() { 225 private static getImei() {
209 // TODO 226 // TODO
210 - return 'b5cf725d-193d-3215-8c77-e76fe15ce64d'; 227 + return '8a81226a-cabd-3e1b-b630-b51db4a720ed';
211 } 228 }
212 229
213 private static getUserId() { 230 private static getUserId() {
@@ -3,6 +3,7 @@ import { NavigationBodyDTO } from './bean/NavigationBodyDTO'; @@ -3,6 +3,7 @@ import { NavigationBodyDTO } from './bean/NavigationBodyDTO';
3 import { PageDTO } from './bean/PageDTO'; 3 import { PageDTO } from './bean/PageDTO';
4 import HashMap from '@ohos.util.HashMap'; 4 import HashMap from '@ohos.util.HashMap';
5 import { HttpUrlUtils } from '../network/HttpUrlUtils'; 5 import { HttpUrlUtils } from '../network/HttpUrlUtils';
  6 +import { InteractDataDTO } from './bean/InteractDataDTO';
6 7
7 export class PageRepository { 8 export class PageRepository {
8 static fetchNavigationDataApi() { 9 static fetchNavigationDataApi() {
@@ -23,4 +24,10 @@ export class PageRepository { @@ -23,4 +24,10 @@ export class PageRepository {
23 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders(); 24 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
24 return WDHttp.get<ResponseDTO<string>>(url, headers) 25 return WDHttp.get<ResponseDTO<string>>(url, headers)
25 }; 26 };
  27 +
  28 + static fetchInteractData(param: object) {
  29 + let url = HttpUrlUtils.getInteractDataUrl()
  30 + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
  31 + return WDHttp.post<ResponseDTO<InteractDataDTO[]>>(url, param, headers)
  32 + };
26 } 33 }
1 import { FullColumnImgUrlsDTO } from './FullColumnImgUrlsDTO'; 1 import { FullColumnImgUrlsDTO } from './FullColumnImgUrlsDTO';
  2 +import { InteractDataDTO } from './InteractDataDTO';
2 import { LiveInfo } from './LiveInfo' 3 import { LiveInfo } from './LiveInfo'
3 import { VideoInfo } from './VideoInfo' 4 import { VideoInfo } from './VideoInfo'
4 5
@@ -49,4 +50,6 @@ export interface ContentDTO { @@ -49,4 +50,6 @@ export interface ContentDTO {
49 liveInfo?: LiveInfo; // 直播新闻信息【BFF聚合】 50 liveInfo?: LiveInfo; // 直播新闻信息【BFF聚合】
50 videoInfo?: VideoInfo; // 视频新闻信息【BFF聚合】,视频非原片+清晰度最高的 51 videoInfo?: VideoInfo; // 视频新闻信息【BFF聚合】,视频非原片+清晰度最高的
51 corner:string; 52 corner:string;
  53 + // 二次请求接口,返回的数据,这里组装到content里;TODO 后续优化
  54 + interactData:InteractDataDTO;
52 } 55 }
  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 +}
@@ -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 { Logger, ResourcesUtils } from 'wdKit'; 1 +import { CollectionUtils, Logger, ResourcesUtils, StringUtils } from 'wdKit';
2 import { ResponseDTO, } from 'wdNetwork'; 2 import { ResponseDTO, } from 'wdNetwork';
3 import { PageRepository } from '../repository/PageRepository'; 3 import { PageRepository } from '../repository/PageRepository';
4 import { NavigationBodyDTO } from '../repository/bean/NavigationBodyDTO'; 4 import { NavigationBodyDTO } from '../repository/bean/NavigationBodyDTO';
5 import { PageDTO } from '../repository/bean/PageDTO'; 5 import { PageDTO } from '../repository/bean/PageDTO';
6 import { BaseViewModel } from './BaseViewModel'; 6 import { BaseViewModel } from './BaseViewModel';
  7 +import { InteractDataDTO } from '../repository/bean/InteractDataDTO';
  8 +import { ContentBean, InteractParam } from '../repository/bean/InteractParam';
  9 +import { CompDTO } from '../repository/bean/CompDTO';
7 10
8 const TAG = 'PageViewModel'; 11 const TAG = 'PageViewModel';
9 /** 12 /**
@@ -11,6 +14,11 @@ const TAG = 'PageViewModel'; @@ -11,6 +14,11 @@ const TAG = 'PageViewModel';
11 * mock数据是本地json数据,可自行修改内容(‘entry\src\main\resources\rawfile\’目录) 14 * mock数据是本地json数据,可自行修改内容(‘entry\src\main\resources\rawfile\’目录)
12 */ 15 */
13 const mock_switch = false; 16 const mock_switch = false;
  17 +/**
  18 + * 互动数据获取开关开关,默认开。
  19 + * TODO 后续需要优化掉,变为二次请求异步刷新
  20 + */
  21 +const interact_sync_switch = true;
14 22
15 /** 23 /**
16 * 处理返回后的数据 24 * 处理返回后的数据
@@ -112,7 +120,18 @@ export class PageViewModel extends BaseViewModel { @@ -112,7 +120,18 @@ export class PageViewModel extends BaseViewModel {
112 return 120 return
113 } 121 }
114 Logger.info(TAG, "getPageData then,resDTO.timeStamp:" + resDTO.timestamp); 122 Logger.info(TAG, "getPageData then,resDTO.timeStamp:" + resDTO.timestamp);
115 - success(resDTO.data); 123 + if (!interact_sync_switch) {
  124 + success(resDTO.data);
  125 + return;
  126 + }
  127 + // TODO 打开同步请求互动数据,待优化为异步加载
  128 + if (CollectionUtils.isEmpty(resDTO.data.compList)) {
  129 + success(resDTO.data);
  130 + } else {
  131 + this.getInteractData(resDTO.data.compList).then(() => {
  132 + success(resDTO.data);
  133 + })
  134 + }
116 }) 135 })
117 .catch((err: Error) => { 136 .catch((err: Error) => {
118 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`); 137 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`);
@@ -120,6 +139,122 @@ export class PageViewModel extends BaseViewModel { @@ -120,6 +139,122 @@ export class PageViewModel extends BaseViewModel {
120 }) 139 })
121 }) 140 })
122 } 141 }
  142 +
  143 + async getInteractData(compList: CompDTO[]) {
  144 + let param: InteractParam = this.getInteractParams(compList);
  145 + const SIZE = 20;
  146 + // 批查接口,参数size限制20,这里截断分批查询,0,20;20,40...
  147 + let count = Math.ceil(param.contentList.length / SIZE);
  148 + let promises = new Array;
  149 + if (count == 1) {
  150 + let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(param);
  151 + promises.push(promise);
  152 + } else {
  153 + for (let i = 1;i <= count; i++) {
  154 + // 将查询参数截断(参数限制20个),分批请求接口
  155 + let subList = new Array<ContentBean>();
  156 + let start = 0;
  157 + let end = 0;
  158 + if (i == count) {
  159 + start = (i - 1) * SIZE;
  160 + end = param.contentList.length;
  161 + subList = CollectionUtils.getSubElements(param.contentList, start, end)
  162 + } else {
  163 + start = (i - 1) * SIZE;
  164 + end = start + SIZE;
  165 + subList = CollectionUtils.getSubElements(param.contentList, start, end)
  166 + }
  167 + let subParam: InteractParam = {} as InteractParam;
  168 + subParam.contentList = subList;
  169 + let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(subParam);
  170 + promises.push(promise);
  171 + }
  172 + }
  173 +
  174 + return new Promise<CompDTO[]>((success, error) => {
  175 + Promise.all(promises).then((result) => {
  176 + if (!CollectionUtils.isArray(result)) {
  177 + success(compList);
  178 + return;
  179 + }
  180 +
  181 + let allInteractDataList = new Array();
  182 + result.forEach((value: InteractDataDTO[]) => {
  183 + if (value != null && value.length > 0) {
  184 + allInteractDataList.push(...value);
  185 + }
  186 + })
  187 + // 批查全部完成,统一设置到comp里
  188 + this.resetInteract(allInteractDataList, compList);
  189 + success(compList);
  190 + })
  191 + })
  192 + }
  193 +
  194 + private createInteractDataPromise(param: InteractParam) {
  195 + return new Promise<InteractDataDTO[]>((success, error) => {
  196 + PageRepository.fetchInteractData(param).then((resDTO: ResponseDTO<InteractDataDTO[]>) => {
  197 + if (this.isRespondsInvalid(resDTO, 'getInteractData')) {
  198 + Logger.info(TAG, "getInteractData then,resDTO.timeStamp:" + resDTO.timestamp);
  199 + success(null);
  200 + return;
  201 + }
  202 + success(resDTO.data);
  203 + }).catch((err: Error) => {
  204 + Logger.error(TAG, `getInteractData catch, error.name : ${err.name}, error.message:${err.message}`);
  205 + // 无论是否成功(暂不做重试),都回调结果,通知刷新数据
  206 + success(null);
  207 + })
  208 + });
  209 + }
  210 +
  211 + private resetInteract(interact: InteractDataDTO[], compList: CompDTO[]) {
  212 + if (interact == null || interact.length == 0) {
  213 + return
  214 + }
  215 + interact.forEach((interactData) => {
  216 + let id = interactData.contentId;
  217 + outer: for (let i = 0;i < compList.length; i++) {
  218 + let comp = compList[i];
  219 + if (comp == null || comp.operDataList == null || comp.operDataList.length == 0) {
  220 + continue;
  221 + }
  222 + for (let j = 0;j < comp.operDataList.length; j++) {
  223 + let content = comp.operDataList[j];
  224 + if (content == null) {
  225 + continue;
  226 + }
  227 + if (id == content.objectId) {
  228 + content.interactData = interactData;
  229 + break outer;
  230 + }
  231 + }
  232 + }
  233 + })
  234 + }
  235 +
  236 + private getInteractParams(compList: CompDTO[]): InteractParam {
  237 + if (compList == null || compList.length == 0) {
  238 + return null;
  239 + }
  240 +
  241 + let param: InteractParam = {} as InteractParam;
  242 + param.contentList = new Array<ContentBean>();
  243 + compList.forEach((value) => {
  244 + let contentList = value.operDataList;
  245 + if (contentList != null && contentList.length > 0) {
  246 + contentList.forEach((v) => {
  247 + if (StringUtils.isNotEmpty(v.objectId)) {
  248 + let bean = {} as ContentBean;
  249 + bean.contentId = v.objectId;
  250 + bean.contentType = v.objectType;
  251 + param.contentList.push(bean);
  252 + }
  253 + })
  254 + }
  255 + })
  256 + return param;
  257 + }
123 } 258 }
124 259
125 260
@@ -17,7 +17,7 @@ export class CollectionUtils { @@ -17,7 +17,7 @@ export class CollectionUtils {
17 * @returns {boolean} true(empty) 17 * @returns {boolean} true(empty)
18 */ 18 */
19 static isEmpty(collection?: any[]): boolean { 19 static isEmpty(collection?: any[]): boolean {
20 - return !collection || collection.length === 0; 20 + return!collection || collection.length === 0;
21 } 21 }
22 22
23 // static isEmptyList<T>(list1?: LinkList<T>): boolean { 23 // static isEmptyList<T>(list1?: LinkList<T>): boolean {
@@ -68,6 +68,25 @@ export class CollectionUtils { @@ -68,6 +68,25 @@ export class CollectionUtils {
68 return index >= 0 && index < collection.length ? collection[index] : null; 68 return index >= 0 && index < collection.length ? collection[index] : null;
69 } 69 }
70 70
  71 + /**
  72 + * 截取集合部分数据。
  73 + * start:0 - end:20 截取0-19,共20个数据
  74 + */
  75 + static getSubElements(collection?: any[], start?: number, end?: number): any[] {
  76 + if (CollectionUtils.isEmpty(collection) || start === undefined || end === undefined) {
  77 + return null;
  78 + }
  79 + if (start < 0 || end < start) {
  80 + return null;
  81 + }
  82 + if (end > collection.length) {
  83 + return null;
  84 + }
  85 + let ss = collection.slice(start, end);
  86 + ss;
  87 + return collection.slice(start, end);
  88 + }
  89 +
71 static isArray(value: any): boolean { 90 static isArray(value: any): boolean {
72 if (typeof Array.isArray === 'function') { 91 if (typeof Array.isArray === 'function') {
73 return Array.isArray(value); 92 return Array.isArray(value);
@@ -36,10 +36,21 @@ export class HttpRequest { @@ -36,10 +36,21 @@ export class HttpRequest {
36 return service.delete(url, config) 36 return service.delete(url, config)
37 } 37 }
38 38
39 - static post<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> { 39 + static post0<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
40 return service.post(url, data, config) 40 return service.post(url, data, config)
41 } 41 }
42 42
  43 + static post<T = any>(url: string, data1?: any, headers?: HashMap<string, string>): Promise<T> {
  44 + let requestHeaders: AxiosHeaders = new AxiosHeaders()
  45 + headers?.forEach((v, k) => {
  46 + requestHeaders.set(k, v);
  47 + });
  48 + let config: AxiosRequestConfig = {
  49 + headers: requestHeaders as RawAxiosRequestHeaders,
  50 + }
  51 + return service.post(url, data1, config)
  52 + }
  53 +
43 static put<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> { 54 static put<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
44 return service.put(url, data, config) 55 return service.put(url, data, config)
45 } 56 }