Skip to content

加载(loading)的用法

loading一般选择在一个大方法中添加,方法中增加try、catch、finally,一般方法入口增加loading,方法在执行的过程中,各子方法一般不要增加loading,大方法执行结束时,也就是finally中,调用loadingClose,结束loading。

注意事项:

  • 页面入口统一的增加loading
  • getEnableAudit、getReportStatus、getSelectRule均不做loading处理
  • finally中结束调用loadingClose,结束loading

代码示例:

vue
<!-- 报表审核与上报 -->
<template>
  <!-- 容器 -->
  <div class="pfs-gfa-report" :key="unique" v-if="pageVisible">
    <!-- 头部区域 -->
    <v-header :context-info="contextInfo" :content-type="contentType" :report-status="reportStatus" :enable-audit="enableAudit" :user-permission="userPermission" :reconciliation-visible="reconciliationVisible" :is-basic-agy="isBasicAgy" :is-single-report="isSingleReport" :set-content-type="setContentType" :get-report-status="getReportStatus" :get-content-type="getContentType" :on-audit="onAudit" />
    <!-- 内容区域 -->
    <v-content :context-info="contextInfo" :content-type="contentType" :page-disabled="pageDisabled" :is-formula-audit-version-is-new="isFormulaAuditVersionIsNew" />
    <!-- 单位报表状态 -->
    <v-report-status :context-info="contextInfo" :report-status="reportStatus" :enable-audit="enableAudit" />
  </div>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex';
import { GET_LOGIN_INFO, SET_PFS_CONTEXT_AGY, REMOVE_PFS_CONTEXT_AGY } from '@/store/login';
import util from '@/assets/js/util';
import fetch from '@/config/fetch';
import { getViewParams, isRegister } from '@/mixin/system';
import { isAgency, isSingleReport } from '@/modules/pfs/pfs-gfa/common/gfa-service';
import { CONTENT_TYPE, REPORT_STATUS, FORMULA_VERSION } from '@/modules/pfs/pfs-gfa/pfs-gfa-report/constant';
import { reportStatusDisplay } from '@/modules/pfs/pfs-gfa/pfs-gfa-report/service';
import vHeader from '@/modules/pfs/pfs-gfa/pfs-gfa-report/header/index';
import vContent from '@/modules/pfs/pfs-gfa/pfs-gfa-report/content/index';
import vReportStatus from '@/modules/pfs/pfs-gfa/pfs-gfa-report/report-status';

/**
 * 对账单审核级次(控制规则)
 */
const RECONCILIATION_CHECK = {
  AGY: '1', //单位
  DEPART: '2', //部门
};

export default {
  name: 'PFS_GFA_REPORT',
  components: {
    vHeader,
    vContent,
    vReportStatus,
  },
  /**
   * 获取子组件传来的方法,用于beforeRouteEnter,beforeRouteLeave钩子中
   */
  provide() {
    return {
      registerRouteEnterHandler: this.registerRouteEnterHandler,
      unRegisterRouteEnterHandler: this.unRegisterRouteEnterHandler,
      registerRouteLeaveHandler: this.registerRouteLeaveHandler,
      unRegisterRouteLeaveHandler: this.unRegisterRouteLeaveHandler,
    };
  },
  data() {
    return {
      unique: '', //页面key,用于刷新页面用
      queryParams: '',  //URL携带的参数
      contextInfo: {}, //页面上下文数据(保存导航页跳转时的参数)
      contentType: CONTENT_TYPE.INTEGRITY,  //内容区域显示类型
      enableAudit: false, //是否启用两岗审核
      reportStatus: '', //报表状态
      reconciliationVisible: true, //对账单审核是否显示
      timer: null, //定时器对象
      routeEnterHandler: [], //子组件传递的供父组件的beforeRouteEnter钩子调用的方法集合
      routeLeaveHandler: [], //子组件传递的供父组件的beforeRouteLeave钩子调用的方法集合
      isFormulaAuditVersionIsNew: true, //审核公式版本是否为新版
    };
  },
  beforeRouteEnter(to, from, next) {
    next((vm) => {
      vm.init();
    });
  },
  beforeRouteLeave(to, from, next) {
    this.onRouteLeave();
    next();
  },
  methods: {
    ...mapMutations([SET_PFS_CONTEXT_AGY, REMOVE_PFS_CONTEXT_AGY]),
    /**
     * 初始化
     * 1、重置页面key,
     * 2、设置上下文数据
     * 3、获取是否启用两岗审核状态、获取报表状态
     * 4、设置决算、财报工作空间单位信息
     * 5、检查报表
     * 6、输出业务日志
     * 7、处理子组件传递的设置滚动条方法
     */
    async init() {
      try {
        // TODO:页面入口统一的增加loading,
        this.$loading();
        if (this.queryParams !== this.$route.query.query) {
          this.unique = '';
          await this.$nextTick();
          this.setContextInfo();
          // TODO:getEnableAudit、getReportStatus、getSelectRule均不做loading处理
          await Promise.all([this.getEnableAudit(), this.getReportStatus(), this.getSelectRule()]);
          this.SET_PFS_CONTEXT_AGY({
            routerName: this.$route.name,
            agyInfo: {
              code: this.contextInfo.agencyCode,
              name: this.contextInfo.agencyName,
            },
          });
          this.unique = util.generateShortId(true);
        }
        await this.checkReport();
        this.onRouteEnter();
        this.printLog();
      } catch (err) {
        console.error(err);
        this.$message({
          type: 'error',
          message: err.msg,
        });
      } finally {
        // TODO:finally中调用loadingClose,结束loading
        this.$loadingClose();
      }
    },
    /**
     * 设置上下文数据
     */
    setContextInfo() {
      this.queryParams = this.$route.query.query;
      let contextInfo = getViewParams(this.queryParams);
      this.$set(this.$data, 'contextInfo', util.freezeDeep(contextInfo));
    },
    /**
     * 获取是否启用两岗审核('1':启用、'2':未启用)
     */
    getEnableAudit() {
      return new Promise((resolve, reject) => {
        fetch.get('/gfa/fr/gfa/rpt/selectTwoSendRule', {
          params: {
            fiscalYear: this.contextInfo.fiscalYear,
          }
        }).then(({ data }) => {
          this.enableAudit = data === '1';
          return resolve();
        }).catch(reject);
      });
    },
    /**
     * 获取报表状态
     */
    getReportStatus() {
      return new Promise((resolve, reject) => {
        let {
          agencyCode,
          mofDivCode,
          fiscalYear,
          taskId,
          transType,
        } = this.contextInfo;
        fetch.post('/gfa/fr/gfa/rpt/allStatus', {
          agencyCode,
          mofDivCode,
          fiscalYear,
          taskId,
          transType,
        }).then(({ data }) => {
          this.reportStatus = data;
          return resolve();
        }).catch(reject);
      });
    },
    /**
     * 获取控制规则
     * 1、获取对账单节点是否显示
     *    1、对账单审核级次为部门时,如果报送主体是单位,则节点不显示
     * 2、判断当前公式版本是否为新版
     */
    getSelectRule() {
      return new Promise((resolve, reject) => {
        fetch
        .post('/gfa/gfa/report/rule/setting/selectRule', {
          fiscalYear: this.contextInfo.fiscalYear,
          reportCode: 'GFA_REPORT_RULE',
        })
        .then(({ data }) => {
          data = data || {};
          if(data.accountCheck === RECONCILIATION_CHECK.DEPART && this.isBasicAgy){
            this.reconciliationVisible = false;
          }
          this.isFormulaAuditVersionIsNew = data.formulaVersion === FORMULA_VERSION.NEW;
          return resolve();
        })
        .catch(reject);
      });
    },
    /**
     * 设置内容区域显示类型
     */
    setContentType(value) {
      this.contentType = value;
    },
    /**
     * 获取审核结果
     */
    getAuditResult(cacheKey) {
      return new Promise((resolve, reject) => {
        let flag = true;
        this.timer = setInterval(() => {
          if (flag) {
            flag = false;
            fetch.get(`/gfa/fr/gfa/rpt/getCheckMsg?cacheKey=${cacheKey}`).then(({ data }) => {
              if (data.isDone === 1) {
                clearInterval(this.timer);
                this.timer = null;
                return resolve();
              } else {
                this.$loading(data.msg);
              }
            }).catch((err) => {
              clearInterval(this.timer);
              this.timer = null;
              return reject(err);
            }).finally(() => {
              flag = true;
            });
          }
        }, 2000);
      });
    },
    /**
     * 获取当前有效的内容区域显示类型
     * 1、对账单不显示的时候,需要将数据里的对账单节点删除
     * 2、是基层单位时,需要将数据里的户数核对与汇总检查删除
     * 3、报表小类不等于单户表时,需要将数据里的数据一致性检查删除
     */
    getContentType() {
      let contentTypeList = Object.values(CONTENT_TYPE);
      if (!this.reconciliationVisible) {
        _.remove(contentTypeList, (e) => e === CONTENT_TYPE.RECONCILIATION);
      }
      if (this.isBasicAgy) {
        _.remove(contentTypeList, (e) => {
          return [CONTENT_TYPE.DW_NUM, CONTENT_TYPE.SUMMARY_CHECK].includes(e);
        });
      }
      if (!this.isSingleReport) {
        _.remove(contentTypeList, (e) => e === CONTENT_TYPE.ACC_CHECK);
      }
      return contentTypeList;
    },
    /**
     * 构建重新运行审核参数
     */
    buildAuditParams() {
      let { userCode, userName } = this.GET_LOGIN_INFO;
      let { agencyCode, agencyName, dwType, mofDivCode, transType, taskId, fiscalYear, perdType, acctPeriod, lastyearCode } = this.contextInfo;
      return {
        agencyCode,
        agencyName,
        mofDivCode,
        taskId,
        fiscalYear,
        year: fiscalYear,
        acctPeriod,
        lastyearCode,
        perdType,
        transType,
        dataVer: 0,
        userCode,
        userName,
        createUserCode: userCode,
        createUser: userName,
        receiveAgencyCode: agencyCode,
        receiveAgencyName: agencyName,
        receiveDwType: dwType,
        receiveMofDivCode: mofDivCode,
        checkList: this.getContentType(),
      };
    },
    /**
     * 检查报表
     * 1、检查报表是否有修改过数据,如果修改过,需要重新运行审核(返回值 0 或者 2的时候,需要重新运行审核)
     * 2、如果需要重新审核,则提示用户,并重新审核报表
     * 3、审核成功之后,需要重新渲染页面数据
     */
    async checkReport() {
      try {
        let { agencyCode, mofDivCode, transType, taskId, fiscalYear } = this.contextInfo;
        let needAudit = await fetch.post('/gfa/fr/gfa/rpt/dataStatus', {
          agencyCode,
          setYear: fiscalYear,
          mofDivCode,
          taskId,
          transType,
        }).then(({ data }) => [0, 2].includes(data));
        if (needAudit) {
          await this.$alert('报表数据发生变化,需要重新审核,请等待!', '', {
            confirmButtonText: '确定',
            showClose: false,
          });
          this.$loading('开始运行审核!');
          await this.auditReport();
          this.unique = util.generateShortId(true);
        }
      } catch (err) {
        return Promise.reject(err);
      }
    },
    /**
     * 审核报表
     * 1、构建运行审核参数
     * 2、运行审核
     * 3、获取进度条状态
     */
    async auditReport() {
      try {
        let { data } = await fetch.post('/gfa/fr/gfa/rpt/recheck', this.buildAuditParams());
        await this.getAuditResult(data.cacheKey);
      } catch (err) {
        Promise.reject(err);
      }
    },
    /**
     * 重新运行审核
     * 1、审核报表
     * 2、提示用户,并重置页面
     */
    async onAudit() {
      try {
        this.$loading();
        await this.auditReport();
        this.$alert('审核完成,将重新获取页面数据!', '', {
          confirmButtonText: '确定',
          showClose: false,
          callback: async () => {
            try {
              this.unique = '';
              await this.$nextTick();
              this.unique = util.generateShortId(true);
            } catch (err) {
              throw new Error(err);
            }
          }
        });
      } catch (err) {
        console.error(err);
        this.$message({
          type: 'error',
          message: err.msg,
        });
      } finally {
        this.$loadingClose();
      }
    },
    /**
     * 判断按钮是否有权限
     */
    isRegister(key) {
      return isRegister(this.$route.name, key);
    },
    /**
     * 输出业务日志
     */
    printLog() {
      console.info('系统是否启用两岗审核:', this.enableAudit ? '已启用' : '未启用');
      console.info('单位是否显示对账单审核节点:', this.reconciliationVisible ? '显示' : '不显示');
      console.info('单位是否为基层单位:', this.isBasicAgy ? '是基层单位' : '不是基层单位');
      console.info('当前报表状态为:', reportStatusDisplay(this.reportStatus, this.enableAudit));
      console.info('用户是否启用送审相关权限:', this.userPermission.submit ? '已启用' : '未启用');
      console.info('用户是否启用复核和上报权限:', this.userPermission.reviewReport ? '已启用' : '未启用');
      console.info('用户是否启用同步内网权限:', this.userPermission.syncIntranet ? '已启用' : '未启用');
      console.info('用户是否启用同步外网权限:', this.userPermission.syncInternet ? '已启用' : '未启用');
      console.info('审核公式版本', this.isFormulaAuditVersionIsNew ? '新版' : '旧版');
    },
    /**
     * 处理子组件传递的设置滚动条方法
     */
    onRouteEnter() {
      this.routeEnterHandler.forEach((e) => e());
    },
    /**
     * 处理子组件传递的获取滚动条方法
     */
    onRouteLeave() {
      this.routeLeaveHandler.forEach((e) => e());
    },
    /**
     * 子组件创建时,向父组件传递方法,供父组件在beforeRouteEnter钩子中使用
     */
    registerRouteEnterHandler(handler) {
      this.routeEnterHandler.push(handler);
    },
    /**
     * 子组件销毁时,通知父组件去除自己创建时传递的供父组件在beforeRouteEnter钩子中使用的方法
     */
    unRegisterRouteEnterHandler(handler) {
      this.routeEnterHandler = this.routeEnterHandler.filter((e) => {
        return e !== handler;
      });
    },
    /**
     * 子组件创建时,向父组件传递方法,供父组件在beforeRouteLeave钩子中使用
     */
    registerRouteLeaveHandler(handler) {
      this.routeLeaveHandler.push(handler);
    },
    /**
     * 子组件销毁时,通知父组件去除自己创建时传递的供父组件在beforeRouteLeave钩子中使用的方法
     */
    unRegisterRouteLeaveHandler(handler) {
      this.routeLeaveHandler = this.routeLeaveHandler.filter((e) => {
        return e !== handler;
      });
    },
  },
  computed: {
    ...mapGetters([GET_LOGIN_INFO]),
    /**
     * 页面是否显示
     */
    pageVisible() {
      return util.isNotEmpty(this.unique);
    },
    /**
     * 页面是否禁止操作
     * 1、如果开启了两岗审核,则只有未送审时页面可以填数据,其余状态禁止操作
     * 2、如果未开启了两岗审核,则只有未复核时页面可以填数据,其余状态禁止操作
     */
    pageDisabled() {
      if (this.enableAudit) {
        return this.reportStatus !== REPORT_STATUS.NO_SUBMIT;
      } else {
        return this.reportStatus !== REPORT_STATUS.NOT_REVIEW;
      }
    },
    /**
     * 用户资源权限
     */
    userPermission() {
      return {
        submit: this.isRegister('btn-audit-send'),
        reviewReport: this.isRegister('btn-audit-submit'),
        syncIntranet: this.isRegister('btn-syn-Intranet'),
        syncInternet: this.isRegister('btn-syn-lntranetout'),
      };
    },
    /**
     * 是否为基层单位
     */
    isBasicAgy() {
      return isAgency(this.contextInfo.rptType);
    },
    /**
     * 是否是单户表
     */
    isSingleReport() {
      return isSingleReport(this.contextInfo.rptType);
    },
  },
  /**
   * 销毁定时器
   */
  beforeDestroy() {
    clearInterval(this.timer);
    this.timer = null;
    this.REMOVE_PFS_CONTEXT_AGY(this.$route.name);
  },
};
</script>
<style lang="scss" scoped>
@import '~@/assets/style/variables.scss';
.pfs-gfa-report {
  position: relative;
  width: 100%;
}
</style>