order-list.vue 6.3 KB
<template>
  <layout-app
    :title="$route.params.owner === 'sell' ? '我的出售' : '我的购买订单'"
    class="list-page"
  >
    <status-nav
      class="order-status-nav"
      :status="status"
      :owner="owner"
      @select="onStatusChange"
    />
    <div class="content-wrapper">
      <LayoutScroll
        @scroll="scrollHandler"
        @pulling-up="fetchData"
        @pulling-down="onRefresh"
        :loading="loadingOptions"
        class="order-list-scroll-wrap"
        ref="scroll"
      >
        <ul class="list-wrapper">
          <li v-for="order in viewOrderList" :key="order.orderCode">
            <order-item-header :order="order" />
            <order-item :order="order" />
            <!-- 订单操作 -->
            <div class="footer-wrapper">
              <count-down :leftTime="order.leftTime" />
              <order-actions
                class="actions"
                pageName="list"
                :order="order"
                @on-action="
                  action => {
                    onAction({ action, order });
                    onInSaleOrderAction({ action, order });
                  }
                "
                @on-video="params => onVideoHandle(params)"
              />
            </div>
            <div class="video-wrapper">
              <VideoPlayer
                :ref="order.orderCode"
                class="video-player"
                :source="order.appraiseVideoUrl"
              ></VideoPlayer>
            </div>
          </li>
        </ul>
        <empty-list
          @touch.prevent
          class="empty-wrapper"
          tip="这里什么都没有..."
          v-show="orderStatus.isShowEmpty"
        />
      </LayoutScroll>
    </div>
  </layout-app>
</template>

<script>
import { createNamespacedHelpers } from "vuex";

import OrderItem from "./components/order-item";
import StatusNav from "./components/status-nav";
import OrderItemHeader from "./components/order-item-header";
import VideoPlayer from "./components/video-player";

import EmptyList from "components//ufo-no-item";

import OrderActions from "../components/order-actions";
import CountDown from "../components/count-down";

import orderActionMixin from "../mixin/order-action";
import orderInSaleActionMixin from "../mixin/order-in-sale-action";
import { orderStatusKey, getOrderStatus } from "constants/order-constants";

const STORE_PATH = "order/orderList";

const detailRouterNames = ["buyOrderDetail", "sellOrderDetail"];
const listRouterNames = ["OrderList", "InSaleOrderList"];

const refetchBackList = ["OrderList"];

const { mapActions, mapState, mapMutations } = createNamespacedHelpers(
  STORE_PATH
);

export default {
  // 订单操作
  mixins: [orderActionMixin, orderInSaleActionMixin],
  components: {
    OrderItem,
    StatusNav,
    OrderItemHeader,
    EmptyList,
    OrderActions,
    CountDown,
    VideoPlayer
  },
  data() {
    return {
      scrollY: 0,
      isScrollFetch: true
    };
  },
  props: {
    owner: String,
    status: Number
  },
  computed: {
    ...mapState(["orderListByType"]),
    orderStatus() {
      return this.orderListByType[orderStatusKey(this.owner, this.status)];
    },
    viewOrderList() {
      return this.orderStatus.orderList;
    },
    loadingOptions() {
      return {
        hide: !this.viewOrderList || !this.viewOrderList.length,
        noMore: this.orderStatus.page >= this.orderStatus.pagetotal
      };
    }
  },
  activated() {
    if (this.scrollY) {
      this.isScrollFetch = false;
      this.$refs.scroll.scrollTo(this.scrollY);
    }
  },

  // 只有列表进入详情返回时不刷新列表
  beforeRouteEnter(to, from, next) {
    next(vm => {
      let { owner, status, isRefetch = false } = to.params;
      status = getOrderStatus(owner, status);
      // if (detailRouterNames.includes(from.name)) {
      //   const { from: detailFrom } = vm.$store.state.order.orderDetail;
      //   if (listRouterNames.includes(detailFrom.name)) {
      //     isRefetch = false;
      //   }
      // }
      if (isRefetch || !from.name) {
        vm.$store.commit(`${STORE_PATH}/resetData`, { owner, status });
        vm.$store.dispatch(`${STORE_PATH}/fetchOrderList`, { owner, status });
      }
    });
  },

  beforeRouteLeave(to, from, next) {
    if (!detailRouterNames.includes(to.name)) {
      this.scrollY = 0;
    }
    next();
  },

  beforeRouteUpdate(to, from, next) {
    let { owner, status } = to.params;
    status = getOrderStatus(owner, status);

    this.scrollY = 0;
    this.$refs.scroll.scrollTo(this.scrollY);
    this.resetData({ owner, status });
    this.fetchOrderList({ owner, status });
    next();
  },
  methods: {
    ...mapActions(["fetchOrderList", "confirmReceipt"]),
    ...mapMutations(["resetData"]),
    scrollHandler({ y }) {
      this.scrollY = -y;
    },
    fetchData() {
      if (this.isScrollFetch) {
        this.fetchOrderList({
          owner: this.owner,
          status: this.status
        });
      } else {
        this.isScrollFetch = true;
      }
    },
    onRefresh() {
      this.resetData({
        owner: this.owner,
        status: this.status
      });
      this.fetchData();
    },
    onVideoHandle({ videoUrl, orderCode }) {
      if (!videoUrl) {
        return;
      }
      const $video = this.$refs[`${orderCode}`][0];

      if ($video) {
        $video.parentHandleclick();
      }
    },
    onStatusChange(status) {
      this.$router.replace({
        name: this.$route.name,
        params: {
          owner: this.owner,
          status
        }
      });
    }
  }
};
</script>
<style lang="scss" scoped>
.list-page /deep/ .layout-context {
  display: flex;
  flex-direction: column;
}

.order-status-nav {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

.content-wrapper {
  flex: 1 0 0;

  .footer-wrapper {
    display: flex;
    margin-top: 40px;

    .actions {
      flex: 1;
    }
  }

  .empty-wrapper {
    margin: 20vh 0;
  }

  .order-list-scroll-wrap {
    width: 100%;
    padding-top: 100px;
    box-sizing: border-box;
    position: absolute;
    top: 0;
    bottom: 0;

    .list-wrapper {
      li {
        padding: 40px 40px 0;
        border-bottom: 1px solid #eee;
      }

      & :last-child {
        border-bottom: 0;
      }
    }
  }

  .video-wrapper {
    overflow: hidden;
  }

  .video-player {
    display: block;
    height: 40px;
    opacity: 0;
  }
}
</style>