grab-record.vue 9.83 KB
<template>
  <Page name="grab-record" flank>
    <template #header>
      <u-tabs :current="currentTab" :list="navbarList" @click="onScrollCheckChange" :scrollable="false" :disabled="loading" :activeStyle="{ color: '#1E7B6B' }"> </u-tabs>
      <view class="line"></view>
      <view class="quick-tag">
        <view class="quick-tag-group">
          <view class="quick-tag-item" :class="searchForm.projectCode ? 'active' : ''" @click="selectQuickTag({ key: 'projectCode', value: searchForm.projectCode })">
            <text>{{ searchForm.projectName || '车牌号' }}</text>
            <view class="sx-img">
              <image v-if="searchForm.projectCode" class="sx-image" :src="formatImagePath('active-down')"></image>
              <image v-else class="sx-image" :src="formatImagePath('down')"></image>
            </view>
            <view style="position: absolute; top: 0; right: 0">
              <u-icon name="close"></u-icon>
            </view>
          </view>
          <view class="quick-tag-item" :class="searchForm.startCityCode ? 'active' : ''" @click="selectQuickTag({ key: 'startCityCode', value: searchForm.startCityCode })">
            <text>{{ searchForm.startCityName || '司机姓名' }}</text>
            <view class="sx-img">
              <image v-if="searchForm.startCityCode" class="sx-image" :src="formatImagePath('active-down')"></image>
              <image v-else class="sx-image" :src="formatImagePath('down')"></image>
            </view>
          </view>
          <view class="quick-tag-item" :class="searchForm.endCityCode ? 'active' : ''" @click="selectQuickTag({ key: 'endCityCode', value: searchForm.endCityCode })">
            <text>{{ searchForm.endCityName || '司机手机' }}</text>
            <view class="sx-img">
              <image v-if="searchForm.endCityCode" class="sx-image" :src="formatImagePath('active-down')"></image>
              <image v-else class="sx-image" :src="formatImagePath('down')"></image>
            </view>
          </view>
          <view>抢单时间<zui-icon name="enter"></zui-icon></view>
        </view>
      </view>
    </template>
    <template #content>
      <List ref="list" v-model="list" :loading.sync="loading" :api="searchAPI">
        <view v-for="(form, index) in list" :key="index">
          <view class="card">
            <view-item title="订单号" :value="form.code">
              <view style="flex: 1; display: flex; justify-content: space-between">
                <view>{{ form.code }}</view>
                <view :style="{ color: statusMap[form.status], display: 'flex' }">
                  <render-dict :value="form.status" dict="FREIGHT_GOODS_SOURCE_BIDDING_STATUS"></render-dict>
                </view>
              </view>
            </view-item>
            <view-item title="抢单司机">
              <field-call :value="form.driverMobile">
                <text>{{ form.driverName || '' }}{{ form.driverMobile || '' }}</text>
              </field-call>
            </view-item>
            <view-item title="抢单车辆">
              <text>
                <render-dict :value="form.specification" dict="VEHICLE_SPECIFICATION"></render-dict>
              </text>
              <text>
                <render-dict :value="form.vanType" dict="VEHICLE_COMPARTMENT_TYPE"></render-dict>
              </text>
              <text>/{{ form.vehicleLicenseNum }}</text>
              <text v-if="form.trailerLicenseNum">/{{ form.trailerLicenseNum }}</text>
            </view-item>
            <view-item title="抢单时间" :value="form.biddingTime"></view-item>
            <view-item title="装卸吨位">
              <text>{{ form.biddingWeight || '--' }}吨</text>
            </view-item>
            <view class="buts">
              <view>总运费:{{ form.paidAmount }}</view>
              <template v-if="form.status === 'WAIT_ASSIGN'">
                <zui-button class="zui-button" @click="(cancelCode = form.code), (cancelRemark = ''), (cancelShow = true)">取消</zui-button>
                <zui-button class="zui-button" type="ghost" theme="primary" @click="() => toSubmit(form)">确认</zui-button>
              </template>
            </view>
          </view>
        </view>
      </List>
      <u-modal :show="cancelShow" title="取消原因" @cancel="cancelShow = false" @confirm="confirmCancel" showConfirmButton>
        <u-input v-model="cancelRemark" placeholder="取消原因"></u-input>
      </u-modal>
      <popup-platenumber v-model="platenumberVisible" :plate="searchForm.vehicleCode" @cancel="platenumberVisible = false" @confirm="onPlatenumberSelect" />
    </template>
  </Page>
</template>

<script>
import MIX_ORIGIN from '@/mixins/origin';
import { mapGetters } from 'vuex';

export default {
  mixins: [MIX_ORIGIN],
  data() {
    return {
      cancelShow: false,
      cancelCode: '',
      cancelRemark: '',
      currentTab: 0,
      loading: false,
      list: [],
      countMap: {
        waitAssignCount: 0,
        assignedCount: 0,
        cancelledCount: 0,
      },
      orderStatus: 'WAIT_ASSIGN',
      goodsSourceCode: '',
      statusMap: {
        WAIT_ASSIGN: '#F25643',
        ASSIGNED: '#3296FA',
        CANCELLED: '#999999',
      },
      platenumberVisible: false,
      searchForm: {
        vehicleCode: '',
        loadFlag: '',
        unloadFlag: '',
        waybillCode: '',
        waybillStatus: '',
      },
    };
  },
  onShow() {
    this.onSearch({ showLoading: true });
  },
  onLoad(options) {
    this.goodsSourceCode = options.goodsSourceCode;
  },
  computed: {
    ...mapGetters(['dictList']),
    navbarList() {
      return [
        { name: `待指派(${this.countMap.waitAssignCount || 0})`, prop: 'WAIT_ASSIGN' },
        { name: `已指派(${this.countMap.assignedCount || 0})`, prop: 'ASSIGNED' },
        { name: `已取消(${this.countMap.cancelledCount || 0})`, prop: 'CANCELLED' },
      ];
    },
  },
  methods: {
    // 打开车牌选择
    onSelectPlate() {
      this.platenumberVisible = true;
    },
    // 选中车牌
    onPlatenumberSelect(value) {
      this.platenumberVisible = false;
      this.searchForm.vehicleCode = value;
      this.onSearch({ showLoading: true });
    },
    // 查询数据
    searchAPI(params) {
      this.getCount();
      return uni.$u.api.freightGoodsSourceV2.biddingPage({
        ...params,
        status: this.orderStatus,
        goodsSourceCode: this.goodsSourceCode,
      });
    },
    // 获取统计数量
    getCount() {
      uni.$u.api.freightGoodsSourceV2.biddingCount({ goodsSourceCode: this.goodsSourceCode }).then(res => {
        let result = res?.result || {};
        Object.keys(this.countMap).forEach(item => {
          this.countMap[item] = result[item] ? result[item] : 0;
        });
      });
    },
    onScrollCheckChange(e) {
      this.currentTab = e.index;
      this.orderStatus = this.navbarList[e.index].prop;
      this.onSearch({ showLoading: true });
    },
    // 确认-发布需求
    toSubmit(item) {
      uni.navigateTo({
        url: `/pages/order/add?eventCode=${item.code}`,
        success(res) {
          res.eventChannel.emit('get-item', item);
        },
      });
    },
    // 取消
    confirmCancel() {
      if (this.loading) return;
      uni.$u.api.freightGoodsSourceV2.cancelBidding({ cancelReason: this.cancelRemark, code: this.cancelCode }).then(res => {
        uni.showToast({ title: '取消成功', icon: 'none' });
        this.onSearch({ showLoading: true });
      });
    },
  },
};
</script>

<style lang="scss">
.page-grab-record {
  &__header {
    padding: 0 !important;
    .line {
      height: 1rpx;
      background: #f6f6f6;
      position: relative;
      top: -5rpx;
    }
    .quick-tag {
      display: flex;
      padding: 15upx 22upx;
      box-sizing: border-box;
      position: relative;
      .quick-tag-group {
        flex: 1;
        display: flex;
        align-items: center;
        background-color: #fff;
        padding-left: $padding-xs !important;
        padding-right: $padding-xs !important;
        overflow-y: auto;

        .quick-tag-item {
          flex-shrink: 0;
          min-width: 158upx;
          height: 58upx;
          background: #f6f6f6;
          border-radius: 8upx;
          font-size: 28upx;
          font-weight: 400;
          color: #2b2a27;
          display: flex;
          align-items: center;
          justify-content: center;
          padding: 0 10upx;
          box-sizing: border-box;
          position: relative;
          &:not(:last-child) {
            margin-right: 18upx;
          }

          &.active {
            background: #ffffff;
            border-radius: 8upx;
            border: 2upx solid #2673fb;
            font-size: 28upx;
            font-family:
              PingFangSC,
              PingFang SC;
            font-weight: 400;
            color: #2673fb;
          }

          .sx-img {
            height: 12upx;
            width: 14upx;
            position: relative;
            margin-left: 12upx;

            .sx-image {
              width: 100%;
              height: 100%;
              position: absolute;
              top: 0;
              left: 0;
            }
          }
        }
      }
    }
  }

  &__content {
    padding: 22rpx !important;

    .card {
      padding: 24rpx 12rpx 24rpx 0;
      margin-bottom: 20rpx;
      background: white;
      border-radius: 20rpx;
      .view-item {
        display: flex;
        .view-item__label {
          padding-left: 26rpx;
          color: #999999;
          width: 185rpx;
        }
        .view-item__value {
          flex: 1;
          color: #2b2a27;
          padding-left: 32rpx;
          padding-right: 5rpx;
          display: flex;
          flex-wrap: wrap;
        }
      }
      .view-item:not(:last-child) {
        margin-bottom: 30rpx;
      }
      .buts {
        display: flex;
        justify-content: flex-end;

        .zui-button + .zui-button {
          margin-left: 20rpx;
        }
      }
    }
  }
}
</style>