zhangbo1_wd

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

... ... @@ -35,7 +35,11 @@ export class HttpUrlUtils {
* 详情页面详情接口
*/
static readonly DETAIL_PATH: string = "/api/rmrb-bff-display-zh/content/zh/c/content/detail";
private static hostUrl: string = HttpUrlUtils.HOST_PRODUCT;
/**
* 批查接口,查询互动相关数据,如收藏数、评论数等
*/
static readonly INTERACT_DATA_PATH: string = "/api/rmrb-contact/contact/zh/c/content/interactData";
private static hostUrl: string = HttpUrlUtils.HOST_UAT;
static getCommonHeaders(): HashMap<string, string> {
let headers: HashMap<string, string> = new HashMap<string, string>()
... ... @@ -52,12 +56,15 @@ export class HttpUrlUtils {
headers.set('os_version', this.getOsVersion())
headers.set('versionCode', this.getVersionCode())
headers.set('system', this.getTerminalId())
headers.set('version_name', 'debug')
headers.set('EagleEye-TraceID', '0B6DE03D2997435BA875FFBE05425ED2')
headers.set('version_name', this.getVersionName())
headers.set('EagleEye-TraceID', 'D539562E48554A60977AF4BECB6D6C7A')
headers.set('imei', this.getImei())
headers.set('Accept-Language', 'zh')
headers.set('city', this.getCity())
headers.set('city_dode', this.getCityCode())
headers.set('mpassid', 'ZbHTMeTsfaYDAHqt8ZHIzcPs')
// TODO 判断是否登录
headers.set('userId', this.getUserId())
headers.set('userType', this.getUserType())
... ... @@ -107,6 +114,11 @@ export class HttpUrlUtils {
return url;
}
static getInteractDataUrl() {
let url = this.hostUrl + this.INTERACT_DATA_PATH;
return url;
}
static addSpecialHeaders(headers: HashMap<string, string>) {
switch (this.hostUrl) {
case this.HOST_UAT:
... ... @@ -161,12 +173,12 @@ export class HttpUrlUtils {
private static getDeviceId() {
// TODO
return 'b5cf725d-193d-3215-8c77-e76fe15ce64d';
return '8a81226a-cabd-3e1b-b630-b51db4a720ed';
}
private static getVersion() {
// TODO
return '202312251034';
return '202401242103';
}
private static getVersionCode() {
... ... @@ -174,13 +186,18 @@ export class HttpUrlUtils {
return '7301';
}
private static getVersionName() {
// TODO
return '7.3.0.1';
}
private static getAdCode() {
return '340000';
}
private static getOsVersion() {
// TODO
return '13';
return '12';
}
private static getCityCode() {
... ... @@ -207,7 +224,7 @@ export class HttpUrlUtils {
private static getImei() {
// TODO
return 'b5cf725d-193d-3215-8c77-e76fe15ce64d';
return '8a81226a-cabd-3e1b-b630-b51db4a720ed';
}
private static getUserId() {
... ...
... ... @@ -3,6 +3,7 @@ import { NavigationBodyDTO } from './bean/NavigationBodyDTO';
import { PageDTO } from './bean/PageDTO';
import HashMap from '@ohos.util.HashMap';
import { HttpUrlUtils } from '../network/HttpUrlUtils';
import { InteractDataDTO } from './bean/InteractDataDTO';
export class PageRepository {
static fetchNavigationDataApi() {
... ... @@ -23,4 +24,10 @@ export class PageRepository {
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.get<ResponseDTO<string>>(url, headers)
};
static fetchInteractData(param: object) {
let url = HttpUrlUtils.getInteractDataUrl()
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.post<ResponseDTO<InteractDataDTO[]>>(url, param, headers)
};
}
\ No newline at end of file
... ...
import { FullColumnImgUrlsDTO } from './FullColumnImgUrlsDTO';
import { InteractDataDTO } from './InteractDataDTO';
import { LiveInfo } from './LiveInfo'
import { VideoInfo } from './VideoInfo'
... ... @@ -49,4 +50,6 @@ export interface ContentDTO {
liveInfo?: LiveInfo; // 直播新闻信息【BFF聚合】
videoInfo?: VideoInfo; // 视频新闻信息【BFF聚合】,视频非原片+清晰度最高的
corner:string;
// 二次请求接口,返回的数据,这里组装到content里;TODO 后续优化
interactData:InteractDataDTO;
}
\ No newline at end of file
... ...
/**
* 批查接口查询互动相关数据,返回数据bean
*/
export interface InteractDataDTO {
collectNum: number;
commentNum: number;
contentId: string;
contentType: number;
likeNum: number;
readNum: number;
shareNum: number;
}
\ No newline at end of file
... ...
/**
* 批查接口查询互动相关数据,返回数据bean
*/
export interface InteractParam {
contentList: Array<ContentBean>;
// 默认0;是否详情页访问;默认0:非详情;1:详情页(只有访问详情页时(detail=1),才触发浏览量加1)
detail: string;
}
export interface ContentBean {
contentId: string;
contentType: string;
}
\ No newline at end of file
... ...
... ... @@ -13,12 +13,12 @@ export class RefreshConstants {
/**
* The delay time.
*/
static readonly DELAY_TIME: number = 1000;
static readonly DELAY_TIME: number = 200;
/**
* The animation duration.
*/
static readonly ANIMATION_DURATION: number = 2000;
static readonly ANIMATION_DURATION: number = 200;
/**
* The RefreshConstant constants.
*/
... ...
import { Logger, ResourcesUtils } from 'wdKit';
import { CollectionUtils, Logger, ResourcesUtils, StringUtils } from 'wdKit';
import { ResponseDTO, } from 'wdNetwork';
import { PageRepository } from '../repository/PageRepository';
import { NavigationBodyDTO } from '../repository/bean/NavigationBodyDTO';
import { PageDTO } from '../repository/bean/PageDTO';
import { BaseViewModel } from './BaseViewModel';
import { InteractDataDTO } from '../repository/bean/InteractDataDTO';
import { ContentBean, InteractParam } from '../repository/bean/InteractParam';
import { CompDTO } from '../repository/bean/CompDTO';
const TAG = 'PageViewModel';
/**
... ... @@ -11,6 +14,11 @@ const TAG = 'PageViewModel';
* mock数据是本地json数据,可自行修改内容(‘entry\src\main\resources\rawfile\’目录)
*/
const mock_switch = false;
/**
* 互动数据获取开关开关,默认开。
* TODO 后续需要优化掉,变为二次请求异步刷新
*/
const interact_sync_switch = true;
/**
* 处理返回后的数据
... ... @@ -112,7 +120,18 @@ export class PageViewModel extends BaseViewModel {
return
}
Logger.info(TAG, "getPageData then,resDTO.timeStamp:" + resDTO.timestamp);
success(resDTO.data);
if (!interact_sync_switch) {
success(resDTO.data);
return;
}
// TODO 打开同步请求互动数据,待优化为异步加载
if (CollectionUtils.isEmpty(resDTO.data.compList)) {
success(resDTO.data);
} else {
this.getInteractData(resDTO.data.compList).then(() => {
success(resDTO.data);
})
}
})
.catch((err: Error) => {
Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`);
... ... @@ -120,6 +139,122 @@ export class PageViewModel extends BaseViewModel {
})
})
}
async getInteractData(compList: CompDTO[]) {
let param: InteractParam = this.getInteractParams(compList);
const SIZE = 20;
// 批查接口,参数size限制20,这里截断分批查询,0,20;20,40...
let count = Math.ceil(param.contentList.length / SIZE);
let promises = new Array;
if (count == 1) {
let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(param);
promises.push(promise);
} else {
for (let i = 1;i <= count; i++) {
// 将查询参数截断(参数限制20个),分批请求接口
let subList = new Array<ContentBean>();
let start = 0;
let end = 0;
if (i == count) {
start = (i - 1) * SIZE;
end = param.contentList.length;
subList = CollectionUtils.getSubElements(param.contentList, start, end)
} else {
start = (i - 1) * SIZE;
end = start + SIZE;
subList = CollectionUtils.getSubElements(param.contentList, start, end)
}
let subParam: InteractParam = {} as InteractParam;
subParam.contentList = subList;
let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(subParam);
promises.push(promise);
}
}
return new Promise<CompDTO[]>((success, error) => {
Promise.all(promises).then((result) => {
if (!CollectionUtils.isArray(result)) {
success(compList);
return;
}
let allInteractDataList = new Array();
result.forEach((value: InteractDataDTO[]) => {
if (value != null && value.length > 0) {
allInteractDataList.push(...value);
}
})
// 批查全部完成,统一设置到comp里
this.resetInteract(allInteractDataList, compList);
success(compList);
})
})
}
private createInteractDataPromise(param: InteractParam) {
return new Promise<InteractDataDTO[]>((success, error) => {
PageRepository.fetchInteractData(param).then((resDTO: ResponseDTO<InteractDataDTO[]>) => {
if (this.isRespondsInvalid(resDTO, 'getInteractData')) {
Logger.info(TAG, "getInteractData then,resDTO.timeStamp:" + resDTO.timestamp);
success(null);
return;
}
success(resDTO.data);
}).catch((err: Error) => {
Logger.error(TAG, `getInteractData catch, error.name : ${err.name}, error.message:${err.message}`);
// 无论是否成功(暂不做重试),都回调结果,通知刷新数据
success(null);
})
});
}
private resetInteract(interact: InteractDataDTO[], compList: CompDTO[]) {
if (interact == null || interact.length == 0) {
return
}
interact.forEach((interactData) => {
let id = interactData.contentId;
outer: for (let i = 0;i < compList.length; i++) {
let comp = compList[i];
if (comp == null || comp.operDataList == null || comp.operDataList.length == 0) {
continue;
}
for (let j = 0;j < comp.operDataList.length; j++) {
let content = comp.operDataList[j];
if (content == null) {
continue;
}
if (id == content.objectId) {
content.interactData = interactData;
break outer;
}
}
}
})
}
private getInteractParams(compList: CompDTO[]): InteractParam {
if (compList == null || compList.length == 0) {
return null;
}
let param: InteractParam = {} as InteractParam;
param.contentList = new Array<ContentBean>();
compList.forEach((value) => {
let contentList = value.operDataList;
if (contentList != null && contentList.length > 0) {
contentList.forEach((v) => {
if (StringUtils.isNotEmpty(v.objectId)) {
let bean = {} as ContentBean;
bean.contentId = v.objectId;
bean.contentType = v.objectType;
param.contentList.push(bean);
}
})
}
})
return param;
}
}
... ...
... ... @@ -17,7 +17,7 @@ export class CollectionUtils {
* @returns {boolean} true(empty)
*/
static isEmpty(collection?: any[]): boolean {
return !collection || collection.length === 0;
return!collection || collection.length === 0;
}
// static isEmptyList<T>(list1?: LinkList<T>): boolean {
... ... @@ -68,6 +68,25 @@ export class CollectionUtils {
return index >= 0 && index < collection.length ? collection[index] : null;
}
/**
* 截取集合部分数据。
* start:0 - end:20 截取0-19,共20个数据
*/
static getSubElements(collection?: any[], start?: number, end?: number): any[] {
if (CollectionUtils.isEmpty(collection) || start === undefined || end === undefined) {
return null;
}
if (start < 0 || end < start) {
return null;
}
if (end > collection.length) {
return null;
}
let ss = collection.slice(start, end);
ss;
return collection.slice(start, end);
}
static isArray(value: any): boolean {
if (typeof Array.isArray === 'function') {
return Array.isArray(value);
... ...
... ... @@ -36,10 +36,21 @@ export class HttpRequest {
return service.delete(url, config)
}
static post<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
static post0<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
return service.post(url, data, config)
}
static post<T = any>(url: string, data1?: any, headers?: HashMap<string, string>): Promise<T> {
let requestHeaders: AxiosHeaders = new AxiosHeaders()
headers?.forEach((v, k) => {
requestHeaders.set(k, v);
});
let config: AxiosRequestConfig = {
headers: requestHeaders as RawAxiosRequestHeaders,
}
return service.post(url, data1, config)
}
static put<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
return service.put(url, data, config)
}
... ...