doum
2026-06-17 ea689dd91eaa72425dc01759042c3b4eb2186512
h5/pages/customer/bill/list.vue
@@ -4,27 +4,77 @@
    <view class="cu-bill-page__header">
      <view class="cu-tabs cu-bill-tabs">
      <view class="cu-bill-page__toolbar">
        <view
        <view class="cu-tabs cu-bill-tabs cu-bill-tabs--toolbar">
          v-for="(t, i) in tabs"
          <view
          :key="i"
            v-for="(t, i) in tabs"
          :class="['cu-tab', tabIdx === i ? 'cu-tab--active' : '']"
            :key="i"
          @click="tabIdx = i; load()"
            :class="['cu-tab', tabIdx === i ? 'cu-tab--active' : '']"
        >{{ t }}</view>
            @click="switchPayTab(i)"
          >{{ t }}</view>
        </view>
        <picker :range="costTypeFilters" range-key="label" @change="onCostTypeChange">
          <view :class="['cu-bill-cost-picker', costTypeIdx > 0 ? 'cu-bill-cost-picker--active' : '', costTypePickerClass]">
            <text class="cu-bill-cost-picker__label">{{ costTypeLabel }}</text>
            <text class="cu-bill-cost-picker__arrow">▾</text>
          </view>
        </picker>
      </view>
      <view class="cu-bill-summary">
        <text class="cu-bill-summary__count">{{ list.length }}</text>
        <view class="cu-bill-summary__main">
        <text class="cu-bill-summary__label">笔账单</text>
          <text class="cu-bill-summary__count">{{ list.length }}</text>
          <text class="cu-bill-summary__label">笔账单</text>
        </view>
        <view v-if="overdueCount > 0" class="cu-bill-summary__overdue-group">
          <text class="cu-bill-summary__chip cu-bill-summary__chip--stat">{{ overdueCount }}笔逾期</text>
          <view
            :class="['cu-bill-summary__chip', 'cu-bill-summary__chip--filter', onlyOverdue ? 'cu-bill-summary__chip--filter-on' : '']"
            @click="toggleOnlyOverdue"
          >
            <view :class="['cu-bill-summary__check', onlyOverdue ? 'cu-bill-summary__check--on' : '']">
              <text v-if="onlyOverdue" class="cu-bill-summary__check-icon">✓</text>
            </view>
            <text class="cu-bill-summary__chip-text">仅看逾期</text>
          </view>
        </view>
      </view>
@@ -36,7 +86,7 @@
      <view
        v-for="item in list"
        v-for="item in displayList"
        :key="item.id"
@@ -52,19 +102,21 @@
        <view class="cu-bill-card__body">
          <view class="cu-bill-card__head">
          <view class="cu-bill-card__type-row">
            <view class="cu-bill-card__head-main">
            <view :class="['cu-bill-type-tag', costTypeBadgeClass(item.costType)]">
              <text class="cu-bill-card__type">{{ costTypeText(item.costType) }}</text>
              <text class="cu-bill-card__code">{{ item.code }}</text>
              <text class="cu-bill-type-tag__text">{{ costTypeText(item.costType) }}</text>
            </view>
            <text :class="['cu-status', payStatusClass(item.payStatus)]">{{ payText(item.payStatus) }}</text>
          </view>
          <view class="cu-bill-card__code">{{ item.code }}</view>
@@ -117,10 +169,15 @@
          <view class="cu-bill-card__meta">
            <view class="cu-bill-card__meta-item cu-bill-card__meta-item--full">
              <text class="cu-bill-card__meta-label">计费周期</text>
              <text class="cu-bill-card__meta-value">{{ item.startDate }} ~ {{ item.endDate }}</text>
            </view>
          </view>
@@ -137,7 +194,7 @@
      </view>
      <u-empty v-if="!list.length" text="暂无账单" margin-top="80" />
      <u-empty v-if="!displayList.length" :text="onlyOverdue ? '暂无逾期账单' : '暂无账单'" margin-top="80" />
    </view>
@@ -175,9 +232,105 @@
const COST_TYPE_FILTERS = [
  { label: '费用类型', value: null },
  { label: '租赁费', value: 0 },
  { label: '物业费', value: 1 },
  { label: '租赁押金', value: 2 },
  { label: '物业押金', value: 3 },
  { label: '水电费', value: 4 },
  { label: '杂项费', value: 5 },
  { label: '其他', value: 6 },
  { label: '保证金', value: 7 }
]
export default {
  data () { return { list: [], tabIdx: 0, tabs: ['全部', '待支付', '已支付'] } },
  data () {
    return {
      list: [],
      tabIdx: 0,
      costTypeIdx: 0,
      tabs: ['全部', '待支付', '已支付'],
      costTypeFilters: COST_TYPE_FILTERS,
      onlyOverdue: false
    }
  },
  computed: {
    costTypeLabel () {
      return this.costTypeFilters[this.costTypeIdx].label
    },
    costTypePickerClass () {
      const value = this.costTypeFilters[this.costTypeIdx].value
      if (value == null) return ''
      const map = {
        0: 'cu-bill-cost-picker--rent',
        1: 'cu-bill-cost-picker--property',
        2: 'cu-bill-cost-picker--deposit',
        3: 'cu-bill-cost-picker--deposit',
        4: 'cu-bill-cost-picker--utility',
        5: 'cu-bill-cost-picker--misc',
        6: 'cu-bill-cost-picker--misc',
        7: 'cu-bill-cost-picker--deposit'
      }
      return map[value] || ''
    },
    overdueCount () {
      return this.list.filter(item => this.isOverdue(item)).length
    },
    displayList () {
      if (!this.onlyOverdue) return this.list
      return this.list.filter(item => this.isOverdue(item))
    }
  },
  onShow () { this.load() },
@@ -187,13 +340,79 @@
      const payTab = this.tabIdx === 0 ? null : (this.tabIdx === 1 ? 0 : 1)
      customerBillPage({ page: 1, capacity: 50, model: { payTab } })
      const costType = this.costTypeFilters[this.costTypeIdx].value
        .then(res => { this.list = (res.data && res.data.records) || [] })
      const model = { payTab }
      if (costType != null) model.costType = costType
      customerBillPage({ page: 1, capacity: 50, model })
        .then(res => {
          this.list = (res.data && res.data.records) || []
          if (!this.list.some(item => this.isOverdue(item))) this.onlyOverdue = false
        })
    },
    toggleOnlyOverdue () {
      this.onlyOverdue = !this.onlyOverdue
    },
    switchPayTab (i) {
      if (this.tabIdx === i) return
      this.tabIdx = i
      this.load()
    },
    onCostTypeChange (e) {
      const idx = Number(e.detail.value)
      if (this.costTypeIdx === idx) return
      this.costTypeIdx = idx
      this.load()
    },
    costTypeText (type) { return COST_TYPE_MAP[type] || '账单' },
    costTypeBadgeClass (type) {
      const map = {
        0: 'cu-bill-type-tag--rent',
        1: 'cu-bill-type-tag--property',
        2: 'cu-bill-type-tag--deposit',
        3: 'cu-bill-type-tag--deposit',
        4: 'cu-bill-type-tag--utility',
        5: 'cu-bill-type-tag--misc',
        6: 'cu-bill-type-tag--misc',
        7: 'cu-bill-type-tag--deposit'
      }
      return map[type] || 'cu-bill-type-tag--default'
    },
    formatMoney (val) {
@@ -242,16 +461,27 @@
    },
    contractPeriod (item) {
      if (!item) return '-'
      const start = this.formatDate(item.contractStartDate)
      const end = this.formatDate(item.contractEndDate)
      if (!start && !end) return '-'
      return `${start || '-'} ~ ${end || '-'}`
    },
    formatDate (val) {
      if (!val) return ''
      return String(val).replace('T', ' ').substring(0, 10)
    },
    goDetail (id) { uni.navigateTo({ url: `/pages/customer/bill/detail?id=${id}` }) }
  }
@@ -259,5 +489,3 @@
}
</script>