order-logistics-info.vue 9.09 KB
<template>
  <layout-app :title="logisticInfo.expressSender">
    <div class="logistics-wrapper">
      <div class="header">
        <img class="step" alt="" :src="stageImgUrl" />
      </div>
      <div class="content">
        <!-- 物流信息 -->
        <div v-if="logisticInfo.wayBillCode" class="platform-delivery-info">
          <div class="icon-wrapper">
            <i />
          </div>
          <div class="info">
            <p>
              <span class="label">快递公司:</span>
              <span>
                {{ logisticInfo.expressCompanyName }}
              </span>
              <!-- <span class="platform-info">{{ platformName }}</span> -->
            </p>
            <p>
              <span class="label">快递单号:</span>
              <span>
                {{ logisticInfo.wayBillCode }}
              </span>
              <i ref="copy" class="copy"></i>
            </p>
          </div>
        </div>

        <div
          class="delivery-detail"
          v-for="(detailInfo, i) in detailList"
          :key="i"
        >
          <span class="title">{{ detailInfo.title }}</span>
          <time-line :isGoingOn="i === 0" :deliveryList="detailInfo.detailList">
            <template #content="{detail: {miniFaultConfirm} }">
              <div class="judge-content-wrapper" v-if="miniFaultConfirm">
                <p class="tip">
                  <span
                    :class="miniFaultConfirm.showBtn ? '' : 'tipTextGray'"
                    >{{ miniFaultConfirm.text }}</span
                  >
                  <span v-if="miniFaultConfirm.showBtn">
                    ,请在<count-down
                      :leftTime="miniFaultConfirm.leftTime"
                      :isShowIcon="false"
                      class="judge-count-down"
                    />之前确定是否接受
                  </span>
                </p>
                <ul class="img-wrapper">
                  <li
                    v-for="(imgUrl, i) in miniFaultConfirm.imageUrls"
                    :key="i"
                  >

                    <ImageFormat
                      :data-secc="imgUrl"
                      :src="imgUrl"
                      alt=""
                      :width="70"
                      :height="70"
                    />
                  </li>
                  <li v-if="miniFaultConfirm.imageUrls.length > 3">
                    <Button class="more">查看更多</Button>
                  </li>
                </ul>
                <div class="actions-wrapper" v-if="miniFaultConfirm.showBtn">
                  <Button @click="flawRejectDialog">不接受</Button>
                  <Button @click="flawAcceptDialog">接受,请发货</Button>
                </div>
              </div>
            </template>
          </time-line>
        </div>
      </div>
    </div>
  </layout-app>
</template>

<script>
import { createNamespacedHelpers } from "vuex";
import TimeLine from "./components/time-line";
import { expressTypeEnum } from "constants/logistics-constants";
import CountDown from "./components/count-down";
import { Button } from "cube-ui";
import Clipboard from "clipboard";

const STORE_PATH = "order/logisticsInfo";

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

export default {
  components: {
    TimeLine,
    CountDown,
    Button
  },
  data() {
    return {
      stageImgUrl: ""
    };
  },
  computed: {
    ...mapState(["logisticInfo"]),
    platformName() {
      const { expressType: type } = this.logisticInfo;

      return expressTypeEnum[type];
    },
    detailList() {
      const {
        // 物流信息
        expressInfoDetailTitle = "",
        expressInfoDetailList = [],

        // 鉴定信息
        judgeExpressInfoDetailTitle = "",
        judgeExpressInfoDetailList = [],

        // 卖家物流信息
        supplementExpressInfoDetailTitle = "",
        supplementExpressInfoDetailList = []
      } = this.logisticInfo;

      return [
        { title: expressInfoDetailTitle, detailList: expressInfoDetailList },
        {
          title: judgeExpressInfoDetailTitle,
          detailList: judgeExpressInfoDetailList
        },
        {
          title: supplementExpressInfoDetailTitle,
          detailList: supplementExpressInfoDetailList
        }
      ].filter(item => item.detailList.length > 0);
    }
  },

  asyncData({ store, router }) {
    return store.dispatch(`${STORE_PATH}/fetchLogisticInfo`, router.params);
  },
  methods: {
    ...mapActions(["fetchLogisticInfo", "flawReject", "flawAccept"]),

    flawAcceptDialog() {
      this.$createDialog({
        type: "confirm",
        title: "",
        content: "您确定接受瑕疵吗?",
        confirmBtn: {
          text: "接受",
          active: true,
          disabled: false,
          href: "javascript:;"
        },
        cancelBtn: {
          text: "我再想想",
          active: false,
          disabled: false,
          href: "javascript:;"
        },

        onConfirm: () => {
          const params = this.$route.params;
          const { code } = params;
          const that = this;

          this.flawAccept({
            orderCode: code
          }).then(() => {
            that.fetchLogisticInfo(params);
          });
        },

        onCancel: () => {}
      }).show();
    },

    flawRejectDialog() {
      this.$createDialog({
        type: "confirm",
        title: "",
        content: "您确定不接受瑕疵吗?",
        confirmBtn: {
          text: "拒绝",
          active: true,
          disabled: false,
          href: "javascript:;"
        },
        cancelBtn: {
          text: "我再想想",
          active: false,
          disabled: false,
          href: "javascript:;"
        },

        onConfirm: () => {
          const params = this.$route.params;
          const { code } = params;
          const that = this;

          this.flawReject({
            orderCode: code
          }).then(() => {
            that.fetchLogisticInfo(params);
          });
        },

        onCancel: () => {}
      }).show();
    }
  },
  activated() {
    this.$nextTick(() => {
      const { stage } = this.logisticInfo;
      this.stageImgUrl = require(`../../statics/image/order/logistics_progress_${stage}@3x.png`);
    });
    if (this.$refs.copy) {
      this.copyBtn = new Clipboard(this.$refs.copy, {
        text: () => {
          return this.logisticInfo.wayBillCode;
        }
      });
      this.copyBtn.on("success", () => {
        this.$createToast({
          txt: "复制成功",
          type: "txt"
        }).show();
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.logistics-wrapper {
  height: calc(100vh - 90px);
  -webkit-box-orient: vertical;
  overflow-x: auto;

  .judge-content-wrapper {
    font-size: 24px;
    color: #000;
    line-height: 1.5;
    margin-bottom: 20px;

    .actions-wrapper {
      display: flex;
      margin-top: 60px;

      button {
        font-size: 28px;
        background: #fff;
        color: #000;
        border-radius: 35px;
        padding: 16px 36px 14px 36px;
        width: 240px;
        border: 1px solid #ccc;
        line-height: 1.3;

        &:last-child {
          border: none;
          background: #002b47;
          color: #fff;
          margin-left: 40px;
        }
      }
    }

    .tip {
      margin-top: 20px;
      margin-bottom: 10px;
    }

    .tipTextGray {
      color: #999;
    }

    .judge-count-down {
      color: #d0021b;
      font-size: 12px;
      display: inline-block;
    }

    .img-wrapper {
      // display: inline-block;
      display: flex;

      .more {
        background: #fff;
        font-size: 24px;
        height: 100%;
        width: 100%;
        color: #999;
        padding: 0;
      }

      li {
        min-width: 3.5rem;
        height: 3.5rem;
        display: inline-block;
        text-align: center;
      }
    }
  }

  .content {
    padding: 0 40px;

    .delivery-detail {
      .title {
        font-size: 24px;
        padding: 8px 18px 6px 18px;
        background: #f0f0f0;
        display: inline-block;
      }
    }

    .icon-wrapper {
      width: 48px;
      height: 48px;

      i {
        display: block;
        background: url("~statics/image/order/logistics-icon@3x.png") no-repeat;
        background-size: contain;
        width: 100%;
        height: 100%;

        &.sf {
          background: url("~statics/image/order/sf-logo.png") no-repeat;
        }
      }
    }

    .platform-delivery-info {
      display: flex;
      align-items: center;
      margin-bottom: 64px;

      .copy {
        width: 50px;
        height: 25px;
        display: inline-block;
        background: url("~statics/image/order/copy@3x.png") no-repeat;
        background-size: contain;
        background-position: center;
      }

      .info {
        margin-left: 20px;

        .label {
          color: #999;
          padding-right: 10px;
        }

        & > :first-child {
          margin-bottom: 10px;
        }
      }
    }
  }

  .header {
    padding-bottom: 60px;
    border-bottom: 1px solid #eee;
    margin-bottom: 38px;

    .step {
      display: block;
      margin: 0 auto;
      height: 100px;
    }
  }
}
</style>