card.vue 11.3 KB
<template>
  <view class="card">
    <view class="card-header">
      <view class="title">
        <view class="order-no">
          <field-copy :value="item.code" v-if="item.code">{{ item.code }} </field-copy>
          <!--          <view v-if="!onlyShow" class="image" @click.stop="qrShow">-->
          <!--            <image style="height: 30upx; width: 30upx" src="/static/qr.png"></image>-->
          <!--          </view>-->
        </view>
        <view style="display: flex; align-items: center">
          <render-dict v-if="item.status" class="status" :style="{ color: colorMap[item.status] }" dict="FREIGHT_GOODS_SOURCE_STATUS" :value="item.status"></render-dict>
          <u-icon v-if="!onlyShow" name="arrow-right" size="14"></u-icon>
        </view>
      </view>
    </view>
    <view class="card-content">
      <view class="cc-info">
        <view class="info-v">
          <view class="v-t">
            <view class="v-t-img">
              <image src="@/static/svgs/user.svg" />
            </view>
            <text>{{ item.projectName }}</text>
          </view>
          <view class="v-t">
            <text style="white-space: nowrap; overflow: hidden; color: #999; max-width: 50vw; text-overflow: ellipsis"> {{ formatSpecification }}/{{ formatVanType }} </text>
          </view>
        </view>
        <view class="info-line">
          <view class="address">
            <view class="text">{{ item.startProvinceName || '' }}-{{ item.startCityName || '' }}</view>
          </view>
          <view class="way">
            <view class="w-text">{{ item.distance || 0 }}km</view>
            <view class="img">
              <image src="@/static/xl.png" />
            </view>
          </view>
          <view class="address">
            <view class="text">{{ item.endProvinceName || '' }}-{{ item.endCityName || '' }}</view>
          </view>
        </view>
        <view class="info-task">
          <view class="task">
            <text v-if="item.startTime">{{ item.startTime.slice(0, -3) }} 开始</text>
          </view>
          <view class="task">
            <text v-if="item.endTime">{{ item.endTime.slice(0, -3) }} 结束</text>
          </view>
        </view>
        <view v-if="!onlyShow" class="info-operate">
          <view class="task">
            <text>
              已抢单<text class="color-blue">{{ item.biddingCount }}</text> /已指派<text class="color-green">{{ item.assignedCount }}</text> /待指派<text class="color-red">{{
                item.waitAssignCount
              }}</text>
            </text>
          </view>
          <view v-if="item.priceType === 'TON'" class="task-2"> 剩余{{ item.remainGoodsWeight }}吨 </view>
          <view v-if="item.priceType === 'VEHICLE'" class="task-2"> 还需要{{ item.remainVehicleNumber }}车 </view>
        </view>
      </view>
      <view v-if="!onlyShow" class="cc-operate">
        <view class="price-box" style="white-space: nowrap">
          <template v-if="item.priceType === 'TON'">
            <text class="com-price">{{ item.weightUnitPrice }}</text>
            元/吨
          </template>
          <template v-if="item.priceType === 'VEHICLE'">
            <text class="com-price">{{ item.vehicleUnitPrice }}</text>
            元
          </template>
        </view>
        <view class="but-box">
          <zb-tooltip placement="bottom" :visible="visible" @update:visible="e => (visible = e)">
            <template #content>
              <view class="more-action">
                <view v-if="$permission('/freightGoodsSource/modify') && ['MATCHING'].includes(item.status)" @click="modifyGoodSource"> 修改货源 </view>
                <view v-if="$permission('/freightGoodsSource/cancel') && ['MATCHING', 'COMPLETED'].includes(item.status)" @click="cancelGoodSource"> 取消货源 </view>
                <view v-if="$permission('/freightGoodsSource/complete') && ['MATCHING'].includes(item.status)" @click="endGoodSource"> 结束找车 </view>
                <view v-if="$permission('/freightGoodsSource/delete') && ['CANCELLED'].includes(item.status)" @click="deleteGoodSource"> 删除货源 </view>
              </view>
            </template>
            <view class="button">
              更多操作
              <view class="sx-img">
                <image class="sx-image" :src="formatImagePath('down')"></image>
              </view>
            </view>
          </zb-tooltip>
          <view class="button plain" @click.stop="qrShow">分享</view>
          <view class="button primary" @click.stop="toGrabPage">抢单管理</view>
        </view>
      </view>
    </view>
  </view>
</template>
<script>
import { mapGetters } from 'vuex';
import FieldCopy from '@/components/field/field-copy.vue';
import ZbTooltip from '../../uni_modules/zb-tooltip/components/zb-tooltip/zb-tooltip.vue';
import page from '@/mixins/page';
export default {
  name: 'bulk-order-card',
  mixins: [page],
  components: { ZbTooltip, FieldCopy },
  props: {
    onlyShow: Boolean,
    item: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    return {
      visible: false,
      colorMap: {
        MATCHING: '#2673fb',
        COMPLETED: '#2b2a27',
        CANCELLED: '#999999',
      },
    };
  },
  computed: {
    ...mapGetters(['dictValue']),
    formatVanType() {
      let res = [];
      for (let v of this.item.vanType.split(',')) {
        if (v === 'ALL') {
          res.push('不限');
        } else {
          res.push(this.dictValue('VEHICLE_COMPARTMENT_TYPE', v));
        }
      }
      return res.join(',');
    },
    formatSpecification() {
      let res = [];
      for (let v of this.item.specification.split(',')) {
        if (v === 'ALL') {
          res.push('不限');
        } else {
          res.push(this.dictValue('VEHICLE_SPECIFICATION', v));
        }
      }
      return res.join(',');
    },
  },
  methods: {
    qrShow() {
      this.$emit('qrShow', this.item.code, this.item);
    },
    // 抢单记录
    toGrabPage() {
      uni.navigateTo({ url: `/pages/goodSource/grab-record?goodsSourceCode=${this.item.code}` });
    },
    modifyGoodSource() {
      this.visible = false;
      this.$emit('modify', this.item.code);
    },
    cancelGoodSource() {
      this.visible = false;
      this.$emit('cancel', this.item.code);
    },
    endGoodSource() {
      this.visible = false;
      this.$emit('end', this.item.code);
    },
    deleteGoodSource() {
      this.visible = false;
      this.$emit('delete', this.item.code);
    },
  },
};
</script>

<style scoped lang="scss">
.card {
  background-color: $color-white;
  color: $color-text;
  padding: $padding-sm;
  margin-bottom: $padding-sm;
  border-radius: $radius-md;
  box-shadow: $shadow-normal;
  font-size: $font-md;
  .card-header {
    display: flex;
    align-items: center;
    border-bottom: 1px solid $color-border;
    padding-bottom: $padding-sm;
    margin-bottom: $padding-sm;
    .title {
      width: 100%;
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
      padding: 0 16rpx;
      .order-no {
        display: flex;
        align-items: center;
        .image {
          width: 30upx;
          height: 30upx;
          margin-left: 20upx;
        }
      }
      .status {
        color: $color-primary;
        font-weight: bold;
      }
    }
  }
  .card-content {
    padding: 0;
    .cc-info {
      padding: 0 16rpx;
      .info-v {
        display: flex;
        justify-content: space-between;
        margin-bottom: 20rpx;
        margin-top: 20rpx;
        .v-t {
          color: #575c69;
          font-size: 26rpx;
          display: flex;
          overflow: hidden;
          .v-t-img {
            width: 27rpx;
            height: 26rpx;
            margin-right: 10rpx;
            image {
              width: 100%;
              height: 100%;
            }
          }
          text {
            text-overflow: ellipsis;
            overflow: hidden;
            white-space: nowrap;
          }
        }
      }
      .info-line {
        display: flex;
        justify-content: space-between;
        .address {
          display: flex;
          flex-direction: column;
          align-items: flex-end;
          .text {
            font-size: 30rpx;
            color: #2b2a27;
            font-weight: 600;
            margin-bottom: 10rpx;
          }
          .time {
            font-size: 22rpx;
            color: #575c69;
          }
        }
        .address:nth-child(1) {
          align-items: flex-start;
        }
        .way {
          width: 122rpx;
          margin-top: -10rpx;
          .img {
            width: 122rpx;
            height: 15rpx;
            margin-top: -20rpx;
            image {
              width: 100%;
              height: 100%;
            }
          }
          .w-text {
            color: #575c69;
            font-size: 24rpx;
            text-align: center;
            margin-right: 5rpx;
          }
          .w-point {
            color: #2673fb;
            font-size: 22rpx;
            margin-top: 22rpx;
            margin-left: 2rpx;
            text-align: center;
          }
          .wp-none {
            color: #575c69;
          }
        }
      }
      .info-task {
        display: flex;
        justify-content: space-between;
        font-size: 26rpx;
        color: #2b2a27;
        margin-top: 10rpx;
      }
      .info-operate {
        display: flex;
        justify-content: space-between;
        font-size: 26rpx;
        margin-top: 20rpx;
        color: #999999;
        .task {
          flex: 2;
          text {
            margin-right: 5rpx;
          }
        }
        .task-2 {
          flex: 1;
          text-align: right;
          color: $color-red;
        }
      }
    }
    .cc-operate {
      padding: 0 16rpx;
      margin-top: 26rpx;
      display: flex;
      justify-content: space-between;
      .price-box {
        flex: 1;
        display: flex;
        align-items: baseline;
        .com-price {
          font-size: 50rpx;
          font-weight: 500;
          color: red;
        }
      }
      .but-box {
        flex: 2;
        display: flex;
        justify-content: flex-end;
        .more-action {
          text-align: center;
          color: #666666;
          box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.22);
          view {
            padding: $padding-sm;
          }
          view + view {
            border-top: 1px solid #eaeaea;
          }
        }
        .button {
          width: 164rpx;
          height: 56rpx;
          background: #ffffff;
          border-radius: 12rpx;
          border: 2rpx solid #e2e2e3;
          display: flex;
          align-items: center;
          justify-content: center;
          margin-left: $padding-base;
          .sx-img {
            height: 12upx;
            width: 14upx;
            position: relative;
            margin-left: 12upx;
            .sx-image {
              width: 100%;
              height: 100%;
              position: absolute;
              top: 0;
              left: 0;
            }
          }
        }
        .primary {
          border: 2rpx solid $color-primary !important;
          background: $color-primary;
          color: #ffffff;
        }
        .plain {
          width: 90rpx;
          border: 2rpx solid $color-primary !important;
          background: #ffffff;
          color: $color-primary;
        }
      }
    }
  }
}
</style>