LegoRequest.ets 8.56 KB
/**
 * 乐高数据请求调度
 */
import { NetDataStatusType } from '../enum/NetDataStatusType';
import { WDGroup } from '../layout/WDGroup';
import { WDPage } from '../layout/WDPage';
import { Synchronizer } from './Synchronizer';
import List from '@ohos.util.List';
import { WDComp } from '../layout/WDComp';
import { ItemBean } from '../bean/ItemBean';
import { ItemDTO } from '../bean/ItemDTO';
import { PageListener } from '../layout/PageListener';
import { LegoUtil } from '../utils/LegoUtil';
import { Logger } from 'wdKit';
import { Lego } from './LegoService';
import { GroupRequest } from './GroupRequest';

const TAG = 'LegoRequest';

export class LegoRequest {
  /**
   * 记录MGPage的数据请求状态
   */
  private pageStatus: number = NetDataStatusType.INITIAL;
  /**
   * MGPage对象,所有数据请求都是基于此对象进行。
   */
  private page: WDPage;
  /**
   * 最后一次请求的MGGroup对象
   */
  private lastGroup?: WDGroup;
  /**
   * 最后一次请求的MGGroup对象所对应的Index
   */
  private lastGroupIndex: number = -1;
  /**
   * 同步管理器
   */
  private synchronizer: Synchronizer;
  /**
   * 待处理的任务列表
   */
  private taskList: List<Lego.Callback> = new List();
  /**
   * 当前MGPage对象中所包含的所有MGGroup对象
   */
  private allGroupList: List<WDGroup> = new List();
  /**
   * 记录所有返回的MGGroup,用于判断是首次返回还是更新。
   */
  private callbackGroupList: List<WDGroup> = new List();
  /**
   * 记录所有返回的MGComp,用于判断是首次返回还是更新。
   */
  private callbackCompList: List<WDComp<ItemBean, ItemDTO>> = new List();

  /**
   * 调试开关
   */
  // public static DEBUG: boolean = false;

  /**
   * 构造函数:Lego数据请求统筹对象
   * @param page 目标MGPage对象
   */
  constructor(page: WDPage) {
    this.page = page;
    this.synchronizer = new Synchronizer();
  }

  /**
   * 数据请求
   * @param isRefresh 是否为刷新
   * @param callback 回调
   */
  public request(isRefresh: boolean, legoCallback: Lego.Callback) {
    // TODO: 通过MGPage#sendRequest获取Page数据,PageListener监听状态。
    if (isRefresh) {
      this.synchronizer = new Synchronizer();
      this.lastGroup = undefined;
      this.allGroupList.clear();
      this.callbackGroupList.clear();
      this.callbackCompList.clear();
      this.pageStatus = NetDataStatusType.INITIAL;

      // 如果刷新任务过来,前面待处理的任务会被清空。
      // 如果对业务产生不良影响,后续改进。
      this.taskList.clear();
    }
    // 如果Page正在请求中,则需要等待请求结束。
    if (this.pageStatus == NetDataStatusType.LOADING && !isRefresh) {
      this.taskList.add(legoCallback);
    }

    if (this.allGroupList.isEmpty() || isRefresh) {
      let pageListener: PageListener = {
        onPageLoaded: (page: WDPage): void => {
          this.pageStatus = NetDataStatusType.LOADED;
          // Page级别回调
          legoCallback.onPageLoaded(page);

          this.allGroupList.clear();

          let groups: List<WDGroup> = this.page.getGroups();
          if (groups) {
            this.allGroupList = groups;
          }

          if (this.allGroupList.isEmpty()) {
            let msg: string = "onPageLayoutLoaded : allGroupList is empty --> PageID = " + LegoUtil.getPageId(page);
            this.synchronizer.onError(page, msg, legoCallback);
          } else {
            this.doNext(isRefresh, legoCallback);
            // 开始进行待处理的任务
            if (!this.taskList.isEmpty()) {
              for (let index = 0; index < this.taskList.length; index++) {
                let legoCb: Lego.Callback = this.taskList[index]
                this.doNext(false, legoCb);
              }
            }
            this.taskList.clear();
          }
          return
        },
        onPageFailed: (page: WDPage): void => {
          this.pageStatus = NetDataStatusType.FAILED;

          let msg: string = "onPageLayoutFailed --> PageID = " + LegoUtil.getPageId(page);
          this.synchronizer.onError(page, msg, legoCallback);
          return
        },
        onGroupLoaded: (page: WDPage, group: WDGroup): void => {
          // todo:
          // if (this.callbackGroupList.has(group)) {
          //   this.synchronizer.onGroupUpdate(group, legoCallback);
          // } else {
          //   this.callbackGroupList.add(group);
          //   this.synchronizer.checkStatus("onGroupLoaded", group, legoCallback);
          // }
          legoCallback.onGroupUpdate(group);
          return
        },
        onGroupFailed: (page: WDPage, group: WDGroup): void => {
          if (!this.callbackGroupList.has(group)) {
            this.callbackGroupList.add(group);
            let msg: string = "onGroupFailed --> PageID = " + LegoUtil.getPageId(group.getParent()) + ", GroupID = " + LegoUtil.getGroupId(group);
            this.synchronizer.onFailed(msg, group, legoCallback);
          }
          return
        },
        onCompLoaded: (page: WDPage, group: WDGroup, comp: WDComp<ItemBean, ItemDTO>): void => {
          Logger.info(TAG, `onCompLoaded page.getId: ${page.getId()}, group.getId: ${group.getId()}, comp.getId: ${comp.getId()}`);
          // if (this.callbackCompList.has(comp)) {
          //   this.synchronizer.onCompUpdate(comp, legoCallback);
          // } else {
          //   this.callbackCompList.add(comp);
          //   this.synchronizer.checkStatus("onCompLoaded", comp.getParent(), legoCallback);
          // }
          if (group.hasDataLoaded()) {
            if (group.hasAllCompLoadedSuccess()) {
              // 回调到界面展示
              legoCallback.onLoaded(group);
              // legoCallback.onGroupUpdate(group);
            }
            // 同时请求下一个group
            this.doNext(false, legoCallback)
          }
          return
        },
        onCompFailed: (page: WDPage, group: WDGroup, comp: WDComp<ItemBean, ItemDTO>): void => {
          Logger.info(TAG, `onCompFailed page.getId: ${page.getId()}, group.getId: ${group.getId()}, comp.getId: ${comp.getId()}`);
          // if (!this.callbackCompList.has(comp)) {
          //   this.callbackCompList.add(comp);
          //   this.synchronizer.checkStatus("onCompFailed", comp.getParent(), legoCallback);
          // }
          if (group.hasDataLoaded()) {
            // 回调到界面展示
            // legoCallback.onLoaded(group);
            // legoCallback.onGroupUpdate(group);
            // 同时请求下一个group
            this.doNext(false, legoCallback)
          }
          return
        }
      };
      this.page.setListener(pageListener);
      this.pageStatus = NetDataStatusType.LOADING;
      this.page.sendRequest(isRefresh);
    } else {
      this.doNext(false, legoCallback);
    }
  }

  /**
   * 进行下一步处理流程
   * 根据请求顺序获取待请求MGGroup,并将请求动作交给GroupRequest继续处理。
   */
  private doNext(isRefresh: boolean, legoCallback: Lego.Callback) {
    // TODO: 通过GroupRequest获取Group数据
    let groupRequest: GroupRequest = new GroupRequest();
    // 加载更多
    if (groupRequest.loadMore(this.lastGroup)) {
      return;
    }

    // 首次请求状态初始化
    if (!this.lastGroup) {
      this.lastGroupIndex = -1;
    }
    let groupIndex: number = this.lastGroupIndex + 1;
    if (groupIndex < 0) {
      groupIndex = 0;
    }

    // 合法性校验
    if (!this.checkIndex(groupIndex)) {
      return;
    }

    Logger.info(TAG, `doNext groupIndex: ${groupIndex}`);

    if (!this.allGroupList.isEmpty() && groupIndex < this.allGroupList.length) {
      let tempGroup: WDGroup = this.allGroupList.get(groupIndex);

      // 状态记录
      this.lastGroup = tempGroup;
      this.lastGroupIndex = groupIndex;

      if (tempGroup) {
        this.synchronizer.addGroup(tempGroup, legoCallback);

        let isRequest: boolean = groupRequest.request(isRefresh, tempGroup);

        // 如果当前Group没有可以请求的Comp则尝试下一个Group
        if (!isRequest) {
          // 无需请求直接返回回调
          // this.synchronizer.checkStatus("groupLoaded", tempGroup, legoCallback);

          // 回调到界面展示
          if (!tempGroup.getGroupDTO()?.branchMark) {
            legoCallback.onLoaded(tempGroup);
          }
          // 同时请求下一个group
          this.doNext(false, legoCallback)
        }
      }
    } else {
      // Page中所有Group已加载完毕
      legoCallback.onCompleted(this.page);
    }
  }

  // todo
  private checkIndex(groupIndex: number): boolean {
    return true;
  }
}