2021-08-16

贴这段代码的原因就是在这次项目中,我不会写这个自定义时间。同时也给大家参考一下

1.效果显示

在这里插入图片描述

2.源代码

search.vue

<template>
  <view class="search">
    <view class="header">
      <x-nav-bar
        back
        title="工单查询"
        input
        placeholder="请输入问题描述"
        @onInputChange="setKeyword"
      ></x-nav-bar>
      <view class="filter" :class="{ hidden: !filterState }">
        <u-dropdown
          font-size="28px"
          font-weight="400"
          color="#333333"
          menu-icon="arrow-down-fill"
          menu-icon-size="16"
          ref="uDropdown"
          @open="filterState = true"
          @close="filterState = false"
          border-bottom
          duration="0"
        >
          <u-dropdown-item :title="filterProjectTitle">
            <view class="list-item" @click="setProject()">全部</view>
            <view
              class="list-item"
              @click="setProject(item)"
              v-for="(item, index) of projects"
              :key="index"
              >{{ item.projectName }}</view
            >
          </u-dropdown-item>
          <u-dropdown-item :title="filterTimeTitle">
            <view class="list-item" @click="setTimeFromDay(TimeType.Unset)"
              >全部</view
            >
            <view class="list-item" @click="setTimeFromDay(TimeType.D7)"
              >近7天</view
            >
            <view class="list-item" @click="setTimeFromDay(TimeType.D30)"
              >近30天</view
            >
            <view class="list-item" @click="setTimeFromDay(TimeType.D90)"
              >近90天</view
            >
            <view class="picker-container">
              <view class="title">自定义</view>
              <view class="picker-date">
                <view class="pickers">
                  <picker
                    mode="date"
                    :value="startDate"
                    @change="startDateChange"
                  >
                    <view class="date-container" v-if="startDate">{{
                      startDate
                    }}</view>
                    <view class="date-container undefined" v-if="!startDate"
                      >初始时间</view
                    >
                  </picker>
                  <view class="text"></view>
                  <picker mode="date" :value="endDate" @change="endDateChange">
                    <view class="date-container" v-if="endDate">{{
                      endDate
                    }}</view>
                    <view class="date-container undefined" v-if="!endDate"
                      >结束时间</view
                    >
                  </picker>
                </view>
                <view class="btn" @click="setTimeFromDay(TimeType.Custom)"
                  >确定</view
                >
              </view>
            </view>
          </u-dropdown-item>
          <u-dropdown-item :title="filterStatusTitle">
            <view class="list-item" @click="setState()">全部</view>
            <view
              class="list-item"
              @click="setState(OrderStatus.OrderPendingReview)"
              >报单待审核</view
            >
            <view class="list-item" @click="setState(OrderStatus.OrderRejected)"
              >报单被驳回</view
            >
            <view class="list-item" @click="setState(OrderStatus.Unclaimed)"
              >待领取</view
            >
            <view class="list-item" @click="setState(OrderStatus.Pending)"
              >待执行</view
            >
            <view class="list-item" @click="setState(OrderStatus.Executing)"
              >执行中</view
            >
            <view
              class="list-item"
              @click="setState(OrderStatus.AcceptanceCheck)"
              >待验收</view
            >
            <view
              class="list-item"
              @click="setState(OrderStatus.AcceptanceCheckRejected)"
              >验收被驳回</view
            >
            <view class="list-item" @click="setState(OrderStatus.Done)"
              >已完成</view
            >
          </u-dropdown-item>
          <u-dropdown-item :title="filterTypeTitle">
            <view class="list-item" @click="setType()">全部</view>
            <view class="list-item" @click="setType(OrderType.Device)"
              >设备设施</view
            >
            <view class="list-item" @click="setType(OrderType.FireSafety)"
              >消防安全</view
            >
            <view
              class="list-item"
              @click="setType(OrderType.EnvironmentalQuality)"
              >环境品质</view
            >
            <view class="list-item" @click="setType(OrderType.Other)"
              >其他问题</view
            >
          </u-dropdown-item>
        </u-dropdown>
      </view>
    </view>

    <scroll-view
      class="wrapper safe-area-inset-bottom"
      refresher-background="transparent"
      :scroll-y="true"
      :refresher-enabled="true"
      :refresher-triggered="refresh"
      @refresherrefresh="refreshData()"
      @scrolltolower="loadNextData()"
    >
      <template v-if="items.length > 0">
        <view class="padding">
          <x-card :list-data="items"></x-card>
        </view>
      </template>
      <template v-else>
        <x-no-data v-if="!loading"></x-no-data>
      </template>

      <template v-if="!loaded && !refresh">
        <view class="loading">
          <u-loading mode="circle"></u-loading>
        </view>
      </template>
    </scroll-view>
  </view>
</template>
<style lang="scss" scoped src="./search.scss"></style>
<script lang="ts" src="./search.ts"></script>

search.scss

.search{
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.header{
  width: 100%;
  box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.08);
  font-size: 32px;
  font-weight: 400;
  color: #333333;
}

.loading{
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 40rpx 0;
}

.filter{
  background-color: #fff;

  &.hidden{
    overflow: hidden;
  }
}

.list-item{
  width: 100%;
  height: 100rpx;
  line-height: 100rpx;
  padding: 0 40rpx;
  background-color: #fff;
  border-bottom: 1px solid #eaeaea;
  font-size: 28rpx;
  color: #333333;
}

.picker-container{
  width: 100%;
  display: flex;
  flex-direction: column;
  padding: 20rpx 40rpx;
  background-color: #fff;

  .title{
    font-size: 32rpx;
    margin: 0 0 20rpx 0;
  }

  .picker-date{
    display: flex;
    align-items: center;
    justify-content: space-between;

    .pickers{
      display: flex;
      align-items: center;
      justify-content: space-between;

      .date-container{
        width: 216rpx;
        height: 68rpx;
        line-height: 68rpx;
        background-color: #F5F5F5;
        text-align: center;
        font-size: 28rpx;
        color: #333333;

        &.undefined{
          color: #999999;
        }
      }
    }

    .text{
      width: 70rpx;
      text-align: center;
      font-size: 28rpx;
    }

    .btn{
      width: 140rpx;
      height: 60rpx;
      line-height: 60rpx;
      border-radius: 140rpx;
      border: 1px solid #3880ff;
      font-size: 28rpx;
      text-align: center;
      color: #3880ff;
    }
  }
}

.wrapper{
  flex: 1;
  overflow: auto;
  background-color: transparent;

  .padding{
    padding-left: 30rpx;
    padding-right: 30rpx;
    box-sizing: border-box;
  }
}

search.js

import { Vue, Component } from 'vue-property-decorator'
import xCard from '@/components/x-card/x-card.vue'
import xNavBar from '@/components/x-nav-bar/x-nav-bar.vue'
import xNoData from '@/components/x-no-data/x-no-data.vue'
import uLoading from 'uview-ui/components/u-loading/u-loading.vue'
import uDropdown from 'uview-ui/components/u-dropdown/u-dropdown.vue'
import uDropdownItem from 'uview-ui/components/u-dropdown-item/u-dropdown-item.vue'
import { OnPageShow, Created, BeforeDestroy } from '@/lib/lifecycle'
import { FindProjectReq, Project, OrderType, OrderStatus, FindOrderConditionalQuery, Order } from '@/services'
import { debounceTime, merge, of, Subject, switchMap, tap } from 'rxjs'
import { map, takeUntil } from 'rxjs/operators'
import { getUnixTime, subDays, parse } from 'date-fns'

enum TimeType {
    Unset,
    D7,
    D30,
    D90,
    Custom,
}

interface Filter {
    project: Project | null
    timeMode: TimeType | null
    status: OrderStatus | null
    type: OrderType | null
    start: number | null
    end: number | null
    keyword: string | null
}

// @ts-ignore
@Component({
    components: {
        xCard,
        xNavBar,
        uDropdown,
        uDropdownItem,
        xNoData,
        uLoading
    }
})
export default class Search extends Vue implements Created, OnPageShow, BeforeDestroy{
    projects: Project[] = []
    OrderType = OrderType
    OrderStatus = OrderStatus
    TimeType = TimeType
    refresh = false
    loading = true
    loaded = false
    refresh$!: Subject<void>
    next$!: Subject<void>
    filter$!: Subject<void>
    unsubscribe!: Subject<void>
    items: Order[] = []
    startDate = ''
    endDate = ''
    filterState: boolean = false
    filterData: Filter = {
        project: null,
        timeMode: null,
        status: null,
        type: null,
        start: null,
        end: null,
        keyword: ''
    }

    get filterProjectTitle(): string{
        return this.filterData.project?.projectName || '项目'
    }

    get filterStatusTitle(): string{
        switch (this.filterData.status) {
            case OrderStatus.OrderPendingReview:
                return '报单待审核'
            case OrderStatus.OrderRejected:
                return '报单被驳回'
            case OrderStatus.Unclaimed:
                return '待领取'
            case OrderStatus.Pending:
                return '待执行'
            case OrderStatus.Executing:
                return '执行中'
            case OrderStatus.AcceptanceCheck:
                return '待验收'
            case OrderStatus.AcceptanceCheckRejected:
                return '验收被驳回'
            case OrderStatus.Done:
                return '已完成'
            default:
                return '工单状态'
        }
    }

    get filterTimeTitle(): string{
        switch (this.filterData.timeMode) {
            case TimeType.Custom:
                return '自定义'
            case TimeType.D7:
                return '近7天'
            case TimeType.D30:
                return '近30天'
            case TimeType.D90:
                return '近90天'
            default:
                return '报单时间'
        }
    }

    get filterTypeTitle(): string{
        switch (this.filterData.type) {
            case OrderType.Device:
                return '设备设施'
            case OrderType.FireSafety:
                return '消防安全'
            case OrderType.EnvironmentalQuality:
                return '环境品质'
            case OrderType.Other:
                return '其他问题'
            default:
                return '工单类型'
        }
    }

    created() {
        this.refresh$ = new Subject()
        this.next$ = new Subject()
        this.filter$ = new Subject()
        this.unsubscribe = new Subject()
    }

    onShow() {
        this.$services.user.findProjectList(new FindProjectReq())
            .pipe(takeUntil(this.unsubscribe))
            .subscribe({
                next: rs => {
                    if (rs.ok && rs.data?.rows) {
                        this.projects = rs.data.rows
                    }
                },
                error: err => {
                    console.log(err)
                }
            })

        of(null).pipe(
            switchMap(() => {
                let req = new FindOrderConditionalQuery()

                return merge(
                    of(null).pipe(
                        switchMap(() => {
                            this.loading = true
                            return this.$services.order.findAllByConditional(req)
                        }),
                        map(rs => {
                            this.loaded = rs.length < req.rowCount
                            return rs
                        })
                    ),
                    this.filter$.pipe(
                        debounceTime(300),
                        switchMap(() => {
                            this.loading = true
                            this.loaded = false
                            this.items = []
                            req.current = 1
                            req.searchPhrase = this.filterData.keyword || undefined
                            req.projectId = this.filterData.project?.projectId || undefined
                            req.reportStartDate = this.filterData.start || undefined
                            req.reportEndDate = this.filterData.end || undefined
                            req.orderStatus = this.filterData.status || undefined
                            req.orderType = this.filterData.type || undefined
                            return this.$services.order.findAllByConditional(req)
                        }),
                        map(rs => {
                            this.loaded = rs.length < req.rowCount
                            return rs
                        })
                    ),
                    this.next$.pipe(
                        switchMap(() => {
                            this.loading = true
                            req.current += 1
                            return this.$services.order.findAllByConditional(req)
                        }),
                        map(rs => {
                            this.loaded = rs.length < req.rowCount
                            return this.items.concat(rs || [])
                        })
                    ),
                    this.refresh$.pipe(
                        switchMap(() => {
                            this.loading = true
                            this.loaded = false
                            this.items = []
                            req = new FindOrderConditionalQuery()
                            return this.$services.order.findAllByConditional(req)
                        }),
                        map(rs => {
                            this.loaded = rs.length < req.rowCount
                            this.refresh = false
                            return rs
                        })
                    )
                )
            })
        ).pipe(takeUntil(this.unsubscribe)).subscribe({
            next: rs => {
                this.items = rs
                this.loading = false
            },
            error: err => {
                console.log(err)
                this.loading = false
            }
        })
    }

    closeDropdown(): void{
        // @ts-ignore
        this.$refs.uDropdown.close()
    }

    setDropdownHighlight(index?: number): void{
        // @ts-ignore
        this.$refs.uDropdown.highlight(index)
    }

    setType(value?: OrderType): void{
        this.filterData.type = value || null
        this.closeDropdown()
        this.filter$.next()
    }

    setState(value?: OrderStatus): void{
        this.filterData.status = value || null
        this.closeDropdown()
        this.filter$.next()
    }

    setProject(value?: Project): void{
        this.filterData.project = value || null
        this.closeDropdown()
        this.filter$.next()
    }

    setKeyword(value: string): void{
        this.filterData.keyword = value
        this.closeDropdown()
        this.filter$.next()
    }

    setTimeFromDay(type: TimeType): void{
        switch (type) {
            case TimeType.Unset:
                this.filterData.start = null
                this.filterData.end = null
                this.startDate = ''
                this.endDate = ''
                this.filterData.timeMode = TimeType.Unset
                break
            case TimeType.D7:
                this.filterData.start = getUnixTime(subDays(new Date(), 7))
                this.filterData.end = getUnixTime(new Date())
                this.filterData.timeMode = TimeType.D7
                break
            case TimeType.D30:
                this.filterData.start = getUnixTime(subDays(new Date(), 30))
                this.filterData.end = getUnixTime(new Date())
                this.filterData.timeMode = TimeType.D30
                break
            case TimeType.D90:
                this.filterData.start = getUnixTime(subDays(new Date(), 90))
                this.filterData.end = getUnixTime(new Date())
                this.filterData.timeMode = TimeType.D90
                break
            case TimeType.Custom:
                if (this.startDate && this.endDate){
                    const sp = parse(this.startDate, 'yyyy-MM-dd', new Date())
                    const ep = parse(this.endDate, 'yyyy-MM-dd', new Date())
                    this.filterData.start = getUnixTime(sp)
                    this.filterData.end = getUnixTime(ep)
                    this.filterData.timeMode = TimeType.Custom
                }else {
                    uni.showToast({
                        title: '参数不完整',
                        duration: 1000
                    })
                    return
                }
                break
        }

        this.closeDropdown()
        this.filter$.next()
    }

    beforeDestroy() {
        this.unsubscribe.next()
        this.unsubscribe.complete()
    }

    startDateChange(e: any): void{
        this.startDate = e.detail.value
    }

    endDateChange(e: any): void{
        this.endDate = e.detail.value
    }

    refreshData(): void{
        this.refresh = true
        this.refresh$.next()
    }

    loadNextData(): void{
        if (!this.loaded && !this.loading){
            this.next$.next()
        }
    }
}

3.我的理解

刚开始我用的是uview里面的u-dorpdown,但是里面的自定义的不会写,以及自定义时间不太会写。后来明白了,自定义就是里面的下拉筛选框自己写。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛夏天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值