|
|
@@ -0,0 +1,502 @@
|
|
|
+<template>
|
|
|
+ <!--
|
|
|
+ H5 余额变动明细页
|
|
|
+ 用途:扫码付款场景查看与供货商的余额流水;与小程序共用 /ghs-balance-change/list
|
|
|
+ 调用方:admin/ghs/pay 的「查看余额明细」
|
|
|
+ -->
|
|
|
+ <view class="bc-page">
|
|
|
+ <view class="nav-bar">
|
|
|
+ <view class="nav-back" @click="goBack">
|
|
|
+ <text class="back-arrow"><</text>
|
|
|
+ </view>
|
|
|
+ <view class="nav-title">余额变动</view>
|
|
|
+ <view class="nav-placeholder"></view>
|
|
|
+ </view>
|
|
|
+ <view class="nav-bar-placeholder"></view>
|
|
|
+
|
|
|
+ <view v-if="loading && page === 1" class="bc-status">加载中...</view>
|
|
|
+ <view v-else-if="loadError" class="bc-status bc-status--error">{{ loadError }}</view>
|
|
|
+ <template v-else>
|
|
|
+ <view v-if="list.length > 0" class="bc-sheet">
|
|
|
+ <view class="bc-head">
|
|
|
+ <text class="bc-th bc-th--time">时间</text>
|
|
|
+ <text class="bc-th bc-th--event">事项</text>
|
|
|
+ <text class="bc-th bc-th--amt">变动</text>
|
|
|
+ <text class="bc-th bc-th--bal">余额</text>
|
|
|
+ </view>
|
|
|
+ <view class="bc-body">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in list"
|
|
|
+ :key="index"
|
|
|
+ class="bc-item"
|
|
|
+ :class="{ 'bc-item--alt': index % 2 === 1 }"
|
|
|
+ >
|
|
|
+ <view
|
|
|
+ class="bc-row-main"
|
|
|
+ :class="{ 'bc-row-main--with-extra': item.showExtraRow }"
|
|
|
+ >
|
|
|
+ <view class="bc-td bc-td--time">
|
|
|
+ <text class="bc-date">{{ item.dateText }}</text>
|
|
|
+ <text class="bc-clock">{{ item.timeLine }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="bc-td bc-td--event">
|
|
|
+ <text class="bc-event">{{ item.event }}</text>
|
|
|
+ <text v-if="item.showStaff" class="bc-meta">{{ item.staffName }}</text>
|
|
|
+ <text v-if="item.showRemark" class="bc-meta bc-meta--remark">{{ item.remark }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="bc-td bc-td--amt">
|
|
|
+ <text class="bc-amount" :class="item.amountClassName">{{ item.amount }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="bc-td bc-td--bal">
|
|
|
+ <text class="bc-balance">{{ item.balanceText }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view v-if="item.showExtraRow" class="bc-row-extra">
|
|
|
+ <view class="bc-tags-row">
|
|
|
+ <text
|
|
|
+ v-if="item.showRefundTag"
|
|
|
+ class="bc-tag bc-tag--refund"
|
|
|
+ >{{ item.refundTagText }}</text>
|
|
|
+ <text
|
|
|
+ v-if="item.showClearLink"
|
|
|
+ class="bc-tag bc-tag--link"
|
|
|
+ >{{ item.clearLinkText }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view v-if="loadingMore" class="bc-status bc-status--more">加载更多...</view>
|
|
|
+ <view v-else-if="finished" class="bc-status bc-status--more">没有更多了</view>
|
|
|
+ </view>
|
|
|
+ <view v-else class="bc-empty">
|
|
|
+ <text class="bc-empty__text">暂无余额变动记录</text>
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { balanceChangeList } from '@/api/ghs'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'ghsBalanceChangeH5',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ ghsId: 0,
|
|
|
+ salt: '',
|
|
|
+ list: [],
|
|
|
+ page: 1,
|
|
|
+ pageSize: 20,
|
|
|
+ loading: false,
|
|
|
+ loadingMore: false,
|
|
|
+ finished: false,
|
|
|
+ loadError: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad(options) {
|
|
|
+ this.ghsId = options.ghsId || options.id || 0
|
|
|
+ this.salt = options.salt || ''
|
|
|
+ if (!this.ghsId) {
|
|
|
+ this.loadError = '参数错误,缺少供货商信息'
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.fetchList(true)
|
|
|
+ },
|
|
|
+ onReachBottom() {
|
|
|
+ if (!this.finished && !this.loading && !this.loadingMore) {
|
|
|
+ this.fetchList(false)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onPullDownRefresh() {
|
|
|
+ this.fetchList(true).finally(() => {
|
|
|
+ uni.stopPullDownRefresh()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ goBack() {
|
|
|
+ uni.navigateBack({ delta: 1 })
|
|
|
+ },
|
|
|
+ formatMoney(val) {
|
|
|
+ const n = parseFloat(val)
|
|
|
+ return isNaN(n) ? '0' : String(n)
|
|
|
+ },
|
|
|
+ hasText(val) {
|
|
|
+ return val !== undefined && val !== null && String(val).trim() !== ''
|
|
|
+ },
|
|
|
+ /** 结账类支出行不展示(与小程序一致) */
|
|
|
+ shouldHideRow(item) {
|
|
|
+ return item.io == 0 && item.event && String(item.event).indexOf('结账') === 0
|
|
|
+ },
|
|
|
+ /** 映射列表行展示字段 */
|
|
|
+ mapListItem(item, amountDisplay) {
|
|
|
+ const row = Object.assign({}, item)
|
|
|
+ row.amount = amountDisplay
|
|
|
+ const text = String(amountDisplay || '')
|
|
|
+ row.amountClassName = (text.indexOf('+') === 0 || Number(row.io) === 1) ? 'bc-amount--in' : 'bc-amount--out'
|
|
|
+ const addTime = row.addTime || ''
|
|
|
+ if (addTime.length >= 16) {
|
|
|
+ row.dateText = addTime.substr(5, 5)
|
|
|
+ row.timeLine = addTime.substr(11, 5)
|
|
|
+ } else if (addTime.length >= 11) {
|
|
|
+ row.dateText = addTime.substr(0, 10)
|
|
|
+ row.timeLine = addTime.substr(11)
|
|
|
+ } else {
|
|
|
+ row.dateText = addTime
|
|
|
+ row.timeLine = ''
|
|
|
+ }
|
|
|
+ row.balanceText = this.formatMoney(row.balance)
|
|
|
+ const clearSn = row.clearSn || ''
|
|
|
+ const clearAmt = this.formatMoney(row.clearAmount)
|
|
|
+ row.showClearLink = Number(row.clearId) > 0 || this.hasText(clearSn)
|
|
|
+ row.clearLinkText = '结账单 ' + clearSn + ' · 本单销' + clearAmt + '元'
|
|
|
+ row.showStaff = this.hasText(row.staffName)
|
|
|
+ row.showRemark = this.hasText(row.remark)
|
|
|
+ const eventText = String(row.event || '')
|
|
|
+ row.showRefundTag = Number(row.capitalType) === 82 || eventText.indexOf('充值退款') >= 0
|
|
|
+ row.refundTagText = row.showStaff
|
|
|
+ ? '充值退款 · 操作人 ' + row.staffName
|
|
|
+ : '充值退款'
|
|
|
+ row.showExtraRow = row.showClearLink || row.showRefundTag
|
|
|
+ return row
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 拉取余额变动列表
|
|
|
+ * @param {boolean} reset 是否从第一页刷新
|
|
|
+ */
|
|
|
+ async fetchList(reset) {
|
|
|
+ if (reset) {
|
|
|
+ this.page = 1
|
|
|
+ this.finished = false
|
|
|
+ this.loadError = ''
|
|
|
+ this.loading = true
|
|
|
+ } else {
|
|
|
+ this.loadingMore = true
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ const res = await balanceChangeList({
|
|
|
+ page: this.page,
|
|
|
+ pageSize: this.pageSize,
|
|
|
+ ghsId: this.ghsId,
|
|
|
+ salt: this.salt
|
|
|
+ })
|
|
|
+ if (!res || res.code !== 1) {
|
|
|
+ if (reset) {
|
|
|
+ this.loadError = (res && res.msg) || '加载失败'
|
|
|
+ this.list = []
|
|
|
+ }
|
|
|
+ this.finished = true
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const rawList = (res.data && res.data.list) ? res.data.list : []
|
|
|
+ const rows = []
|
|
|
+ rawList.forEach((item) => {
|
|
|
+ if (this.shouldHideRow(item)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const amountDisplay = item.io == 0
|
|
|
+ ? '-' + parseFloat(item.amount)
|
|
|
+ : '+' + parseFloat(item.amount)
|
|
|
+ rows.push(this.mapListItem(item, amountDisplay))
|
|
|
+ })
|
|
|
+ this.list = reset ? rows : this.list.concat(rows)
|
|
|
+ const moreData = res.data && res.data.moreData
|
|
|
+ if (!moreData) {
|
|
|
+ this.finished = true
|
|
|
+ } else {
|
|
|
+ this.page += 1
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ if (reset) {
|
|
|
+ this.loadError = '网络异常,请稍后重试'
|
|
|
+ this.list = []
|
|
|
+ }
|
|
|
+ this.finished = true
|
|
|
+ } finally {
|
|
|
+ this.loading = false
|
|
|
+ this.loadingMore = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.bc-page {
|
|
|
+ min-height: 100vh;
|
|
|
+ background: #fff;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.nav-bar {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ z-index: 100;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 20upx 24upx;
|
|
|
+ padding-top: calc(20upx + env(safe-area-inset-top));
|
|
|
+ background: #fff;
|
|
|
+ border-bottom: 1upx solid #f0f0f0;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.nav-back,
|
|
|
+.nav-placeholder {
|
|
|
+ width: 72upx;
|
|
|
+ height: 72upx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.back-arrow {
|
|
|
+ font-size: 40upx;
|
|
|
+ color: #333;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.nav-title {
|
|
|
+ flex: 1;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 34upx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #222;
|
|
|
+}
|
|
|
+
|
|
|
+.nav-bar-placeholder {
|
|
|
+ height: calc(112upx + env(safe-area-inset-top));
|
|
|
+}
|
|
|
+
|
|
|
+.bc-status {
|
|
|
+ padding: 80upx 30upx;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 28upx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-status--error {
|
|
|
+ color: #e64340;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-status--more {
|
|
|
+ padding: 30upx;
|
|
|
+ font-size: 24upx;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-empty {
|
|
|
+ padding: 160upx 30upx;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-empty__text {
|
|
|
+ font-size: 28upx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-sheet {
|
|
|
+ width: 100%;
|
|
|
+ background: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-head {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 22upx 0;
|
|
|
+ background: #f8f9fb;
|
|
|
+ border-bottom: 1upx solid #eceef2;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-th {
|
|
|
+ font-size: 28upx;
|
|
|
+ color: #8c8c8c;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 1.2;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-th--time {
|
|
|
+ width: 100upx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ padding-left: 8upx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-th--event {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+ padding-right: 12upx;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-th--amt {
|
|
|
+ width: 118upx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-th--bal {
|
|
|
+ width: 140upx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ padding-right: 8upx;
|
|
|
+ text-align: right;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-item {
|
|
|
+ border-bottom: 1upx solid #f2f3f5;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-item:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-item--alt {
|
|
|
+ background: #fafbfc;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-row-main {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ padding: 24upx 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-row-main--with-extra {
|
|
|
+ padding-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-row-extra {
|
|
|
+ width: 100%;
|
|
|
+ padding: 12upx 0 20upx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-tags-row {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ align-items: flex-start;
|
|
|
+ width: 100%;
|
|
|
+ padding-left: 8upx;
|
|
|
+ padding-right: 8upx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-td--time {
|
|
|
+ width: 100upx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ padding-left: 8upx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: flex-start;
|
|
|
+ justify-content: center;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-td--event {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+ padding-right: 12upx;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-td--amt {
|
|
|
+ width: 118upx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ padding-right: 8upx;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-td--bal {
|
|
|
+ width: 140upx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ padding-right: 8upx;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-date,
|
|
|
+.bc-clock {
|
|
|
+ font-size: 28upx;
|
|
|
+ color: #2c2c2c;
|
|
|
+ line-height: 1.35;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-clock {
|
|
|
+ margin-top: 4upx;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-event {
|
|
|
+ display: block;
|
|
|
+ font-size: 28upx;
|
|
|
+ color: #1a1a1a;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 1.45;
|
|
|
+ word-break: break-all;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-meta {
|
|
|
+ display: block;
|
|
|
+ margin-top: 8upx;
|
|
|
+ font-size: 22upx;
|
|
|
+ color: #999;
|
|
|
+ line-height: 1.4;
|
|
|
+ word-break: break-all;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-meta--remark {
|
|
|
+ color: #b3b3b3;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-tag {
|
|
|
+ display: block;
|
|
|
+ max-width: 100%;
|
|
|
+ padding: 6upx 14upx;
|
|
|
+ margin-top: 10upx;
|
|
|
+ margin-right: 12upx;
|
|
|
+ font-size: 28upx;
|
|
|
+ line-height: 1.4;
|
|
|
+ border-radius: 8upx;
|
|
|
+ word-break: break-all;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-tags-row .bc-tag:first-child {
|
|
|
+ margin-top: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-tag--link {
|
|
|
+ color: #969aa0;
|
|
|
+ background: #eef4ff;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-tag--refund {
|
|
|
+ color: #cf1322;
|
|
|
+ background: #fff1f0;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-amount {
|
|
|
+ font-size: 28upx;
|
|
|
+ font-weight: 600;
|
|
|
+ line-height: 1.35;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-amount--in {
|
|
|
+ color: #07a84c;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-amount--out {
|
|
|
+ color: #e62e45;
|
|
|
+}
|
|
|
+
|
|
|
+.bc-balance {
|
|
|
+ font-size: 28upx;
|
|
|
+ color: #131212;
|
|
|
+ line-height: 1.35;
|
|
|
+}
|
|
|
+</style>
|