| | |
| | | <template> |
| | | <view class="cu-page"> |
| | | <view class="cu-filters"> |
| | | <picker :range="statusOptions" range-key="label" @change="onStatusChange"> |
| | | <view class="cu-filter">{{ statusLabel }} ▾</view> |
| | | </picker> |
| | | <picker mode="date" fields="month" @change="onMonthChange"> |
| | | <view class="cu-filter">{{ month || '充值月份' }} ▾</view> |
| | | </picker> |
| | | </view> |
| | | <view class="cu-page cu-page--with-fab cu-recharge-record-page"> |
| | | <view class="cu-recharge-record-page__header"> |
| | | <view class="cu-recharge-filter-panel"> |
| | | <view class="cu-recharge-filter-panel__section"> |
| | | <text class="cu-recharge-filter-panel__label">充值状态</text> |
| | | <scroll-view scroll-x class="cu-recharge-status-tabs" :show-scrollbar="false"> |
| | | <view |
| | | v-for="(opt, i) in statusOptions" |
| | | :key="opt.value == null ? 'all' : opt.value" |
| | | :class="['cu-recharge-status-tab', statusIdx === i ? 'cu-recharge-status-tab--active' : '', opt.tabClass]" |
| | | @click="switchStatus(i)" |
| | | >{{ opt.label }}</view> |
| | | </scroll-view> |
| | | </view> |
| | | |
| | | <view class="cu-list-header"> |
| | | <text class="cu-list-header__count">共 {{ list.length }} 条记录</text> |
| | | <view class="cu-recharge-filter-panel__divider" /> |
| | | |
| | | <view class="cu-recharge-filter-panel__section"> |
| | | <view class="cu-recharge-filter-panel__row"> |
| | | <text class="cu-recharge-filter-panel__label">时间筛选</text> |
| | | <view class="cu-recharge-date-mode"> |
| | | <view |
| | | :class="['cu-recharge-date-mode__item', dateMode === 'month' ? 'cu-recharge-date-mode__item--active' : '']" |
| | | @click="switchDateMode('month')" |
| | | >按月</view> |
| | | <view |
| | | :class="['cu-recharge-date-mode__item', dateMode === 'range' ? 'cu-recharge-date-mode__item--active' : '']" |
| | | @click="switchDateMode('range')" |
| | | >按时间段</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="cu-recharge-filter-panel__dates"> |
| | | <template v-if="dateMode === 'month'"> |
| | | <picker mode="date" fields="month" :value="monthPickerValue" @change="onMonthChange"> |
| | | <view :class="['cu-recharge-date-field', month ? 'cu-recharge-date-field--active' : '']"> |
| | | <text class="cu-recharge-date-field__text">{{ monthLabel }}</text> |
| | | <text class="cu-recharge-date-field__arrow">▾</text> |
| | | </view> |
| | | </picker> |
| | | <text v-if="month" class="cu-recharge-date-clear" @click="clearMonth">重置</text> |
| | | </template> |
| | | |
| | | <template v-else> |
| | | <view class="cu-recharge-date-range"> |
| | | <picker mode="date" fields="day" :value="dateStart || today" @change="onDateStartChange"> |
| | | <view :class="['cu-recharge-date-field', dateStart ? 'cu-recharge-date-field--active' : '']"> |
| | | <text class="cu-recharge-date-field__text">{{ dateStart || '开始日期' }}</text> |
| | | <text class="cu-recharge-date-field__arrow">▾</text> |
| | | </view> |
| | | </picker> |
| | | <text class="cu-recharge-date-sep">至</text> |
| | | <picker mode="date" fields="day" :value="dateEnd || today" @change="onDateEndChange"> |
| | | <view :class="['cu-recharge-date-field', dateEnd ? 'cu-recharge-date-field--active' : '']"> |
| | | <text class="cu-recharge-date-field__text">{{ dateEnd || '结束日期' }}</text> |
| | | <text class="cu-recharge-date-field__arrow">▾</text> |
| | | </view> |
| | | </picker> |
| | | </view> |
| | | <text v-if="dateStart || dateEnd" class="cu-recharge-date-clear" @click="clearRange">重置</text> |
| | | </template> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="cu-recharge-summary"> |
| | | <text class="cu-recharge-summary__count">{{ list.length }}</text> |
| | | <text class="cu-recharge-summary__label">条充值记录</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="cu-list-wrap"> |
| | | <view v-for="item in list" :key="item.id" class="cu-list-card"> |
| | | <view class="cu-list-card__head"> |
| | | <view class="cu-list-card__icon cu-list-card__icon--record">📋</view> |
| | | <view class="cu-list-card__main"> |
| | | <view class="cu-list-card__title-row"> |
| | | <text class="cu-list-card__title">{{ item.deviceInfo || item.name || '充值记录' }}</text> |
| | | <text :class="['cu-status', statusClass(item.status)]">{{ item.statusText }}</text> |
| | | <view v-for="item in list" :key="item.id" class="cu-recharge-card"> |
| | | <view :class="['cu-recharge-card__accent', accentClass(item)]" /> |
| | | <view class="cu-recharge-card__body"> |
| | | <view class="cu-recharge-card__top"> |
| | | <view :class="['cu-recharge-card__type', typeTagClass(item.type)]"> |
| | | <text class="cu-recharge-card__type-icon">{{ item.type === 1 ? '❄' : '⚡' }}</text> |
| | | <text class="cu-recharge-card__type-text">{{ typeText(item.type) }}</text> |
| | | </view> |
| | | <text class="cu-list-card__sub" v-if="item.address">户号 {{ item.address }}</text> |
| | | <text :class="['cu-status', statusClass(item.status)]">{{ item.statusText }}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="cu-info-grid"> |
| | | <view class="cu-info-cell"> |
| | | <text class="cu-info-cell__label">充值金额</text> |
| | | <text class="cu-info-cell__value cu-info-cell__value--primary">¥{{ item.money }}</text> |
| | | <text class="cu-recharge-card__title">{{ item.deviceInfo || item.name || '充值记录' }}</text> |
| | | <text v-if="item.rechargeUserName" class="cu-recharge-card__operator">充值人 {{ item.rechargeUserName }}</text> |
| | | |
| | | <view class="cu-recharge-card__amount-box"> |
| | | <view class="cu-recharge-card__amount-main"> |
| | | <text class="cu-recharge-card__amount-label">充值金额</text> |
| | | <text class="cu-recharge-card__amount-value">¥{{ formatMoney(item.money) }}</text> |
| | | </view> |
| | | <view class="cu-recharge-card__amount-side"> |
| | | <text class="cu-recharge-card__amount-label">充后余额</text> |
| | | <text :class="['cu-recharge-card__amount-side-value', balanceToneClass(item.balanceAfter)]">{{ formatMoney(item.balanceAfter) }}</text> |
| | | </view> |
| | | </view> |
| | | <view class="cu-info-cell"> |
| | | <text class="cu-info-cell__label">充后余额</text> |
| | | <text class="cu-info-cell__value">{{ item.balanceAfter }}</text> |
| | | </view> |
| | | <view class="cu-info-cell cu-info-cell--full"> |
| | | <text class="cu-info-cell__label">充值时间</text> |
| | | <text class="cu-info-cell__value">{{ item.createDate }}</text> |
| | | |
| | | <view class="cu-recharge-card__foot"> |
| | | <text class="cu-recharge-card__time">{{ formatTime(item.createDate) }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <u-empty v-if="!list.length" text="暂无记录" margin-top="80" /> |
| | | </view> |
| | | <cu-workbench-fab /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { customerRechargeRecordPage } from '@/api' |
| | | import { getBalanceTone } from '@/utils/utils.js' |
| | | |
| | | const STATUS_OPTIONS = [ |
| | | { label: '全部', value: null, tabClass: '' }, |
| | | { label: '成功', value: 1, tabClass: 'cu-recharge-status-tab--ok' }, |
| | | { label: '失败', value: 2, tabClass: 'cu-recharge-status-tab--bad' }, |
| | | { label: '充值中', value: 0, tabClass: 'cu-recharge-status-tab--pending' } |
| | | ] |
| | | |
| | | export default { |
| | | data () { |
| | | const now = new Date() |
| | | const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}` |
| | | return { |
| | | list: [], |
| | | dateMode: 'month', |
| | | month: '', |
| | | dateStart: '', |
| | | dateEnd: '', |
| | | today, |
| | | statusIdx: 0, |
| | | statusOptions: [ |
| | | { label: '全部状态', value: null }, |
| | | { label: '充值成功', value: 1 }, |
| | | { label: '充值失败', value: 2 }, |
| | | { label: '充值中', value: 0 } |
| | | ] |
| | | statusOptions: STATUS_OPTIONS |
| | | } |
| | | }, |
| | | computed: { statusLabel () { return this.statusOptions[this.statusIdx].label } }, |
| | | onShow () { this.load() }, |
| | | computed: { |
| | | monthPickerValue () { |
| | | return this.month || this.today.substring(0, 7) |
| | | }, |
| | | monthLabel () { |
| | | if (!this.month) return '选择月份' |
| | | const parts = this.month.split('-') |
| | | if (parts.length >= 2) return `${parts[0]}年${parts[1]}月` |
| | | return this.month |
| | | } |
| | | }, |
| | | onShow () { |
| | | this.load() |
| | | }, |
| | | methods: { |
| | | load () { |
| | | const model = { status: this.statusOptions[this.statusIdx].value } |
| | | if (this.dateMode === 'month') { |
| | | if (this.month) model.month = this.month |
| | | } else { |
| | | if (this.dateStart) model.createTimeBegin = `${this.dateStart} 00:00:00` |
| | | if (this.dateEnd) model.createTimeEnd = `${this.dateEnd} 23:59:59` |
| | | } |
| | | customerRechargeRecordPage({ |
| | | page: 1, |
| | | capacity: 50, |
| | | model: { status: this.statusOptions[this.statusIdx].value, month: this.month || null } |
| | | model |
| | | }).then(res => { this.list = (res.data && res.data.records) || [] }) |
| | | }, |
| | | onStatusChange (e) { this.statusIdx = Number(e.detail.value); this.load() }, |
| | | onMonthChange (e) { this.month = e.detail.value; this.load() }, |
| | | switchStatus (i) { |
| | | if (this.statusIdx === i) return |
| | | this.statusIdx = i |
| | | this.load() |
| | | }, |
| | | switchDateMode (mode) { |
| | | if (this.dateMode === mode) return |
| | | this.dateMode = mode |
| | | if (mode === 'month') { |
| | | this.dateStart = '' |
| | | this.dateEnd = '' |
| | | } else { |
| | | this.month = '' |
| | | } |
| | | this.load() |
| | | }, |
| | | onMonthChange (e) { |
| | | this.month = e.detail.value |
| | | this.load() |
| | | }, |
| | | onDateStartChange (e) { |
| | | this.dateStart = e.detail.value |
| | | if (this.dateEnd && this.dateStart > this.dateEnd) { |
| | | this.dateEnd = this.dateStart |
| | | } |
| | | this.load() |
| | | }, |
| | | onDateEndChange (e) { |
| | | this.dateEnd = e.detail.value |
| | | if (this.dateStart && this.dateEnd < this.dateStart) { |
| | | this.dateStart = this.dateEnd |
| | | } |
| | | this.load() |
| | | }, |
| | | clearMonth () { |
| | | this.month = '' |
| | | this.load() |
| | | }, |
| | | clearRange () { |
| | | this.dateStart = '' |
| | | this.dateEnd = '' |
| | | this.load() |
| | | }, |
| | | typeText (type) { |
| | | return type === 1 ? '空调充值' : '电表充值' |
| | | }, |
| | | typeTagClass (type) { |
| | | return type === 1 ? 'cu-recharge-card__type--conditioner' : 'cu-recharge-card__type--electric' |
| | | }, |
| | | accentClass (item) { |
| | | return item.type === 1 ? 'cu-recharge-card__accent--conditioner' : 'cu-recharge-card__accent--electric' |
| | | }, |
| | | statusClass (s) { |
| | | if (s === 1) return 'cu-status--ok' |
| | | if (s === 2) return 'cu-status--bad' |
| | | return 'cu-status--warn' |
| | | }, |
| | | formatMoney (val) { |
| | | if (val === null || val === undefined || val === '') return '-' |
| | | const n = Number(val) |
| | | return Number.isNaN(n) ? val : n.toFixed(2) |
| | | }, |
| | | formatTime (t) { |
| | | return t ? String(t).replace('T', ' ').substring(0, 19) : '-' |
| | | }, |
| | | balanceToneClass (val) { |
| | | const tone = getBalanceTone(val) |
| | | return tone ? `cu-recharge-card__amount-side-value--${tone}` : '' |
| | | } |
| | | } |
| | | } |