chuangte_bike_newxcx/page_shanghu/guanli/area_ability_log.vue

393 lines
9.0 KiB
Vue
Raw Permalink Normal View History

2026-05-29 17:26:45 +08:00
<template>
<view class="page">
<u-navbar :title="navTitle" :border-bottom="false" :background="bgc" back-icon-color="#111827" title-color="#111827" title-size="34" height="44"></u-navbar>
<view class="log-summary" v-if="total > 0">
<text> {{ total }} 条记录</text>
<text class="log-summary-tip">下拉可刷新</text>
</view>
<scroll-view
class=""
scroll-y
:refresher-enabled="true"
:refresher-triggered="refreshing"
refresher-default-style="black"
@refresherrefresh="onRefresherRefresh"
@scrolltolower="loadMore"
>
<view class="log-loading" v-if="loading && !logList.length">加载中...</view>
<view class="log-empty" v-else-if="!logList.length">暂无流水记录</view>
<view class="log-list" v-else>
<view class="log-item" v-for="(item, index) in logList" :key="item.id || index">
<view class="log-item-meta">
<text class="log-meta-text">{{ item.abilityName || '--' }}</text>
<text class="log-time">{{ item.createTime || '--' }}</text>
</view>
<view class="log-item-top">
<view class="log-item-top-left">
<text class="log-reason">{{ item.reason || '--' }}</text>
</view>
</view>
<view class="log-item-bottom">
<view class="log-count-inline">
<text class="log-count-label">变化</text>
<text class="log-count-val" :class="{ 'log-count-val--up': item.changeUp, 'log-count-val--down': item.changeDown }">{{ item.changeCountText }}</text>
</view>
<view class="log-count-inline">
<text class="log-count-label"></text>
<text class="log-count-val">{{ item.changeBeforeText }}</text>
</view>
<view class="log-count-inline">
<text class="log-count-label"></text>
<text class="log-count-val">{{ item.changeAfterText }}</text>
</view>
</view>
</view>
</view>
<view class="log-footer-tip" v-if="logList.length && loadingMore">加载中...</view>
<view class="log-footer-tip" v-else-if="logList.length && noMore"> 没有更多了 </view>
<view class="scroll-bottom-space"></view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: { backgroundColor: '#fff' },
areaId: '',
areaName: '',
areaAbilityId: '',
abilityName: '',
logList: [],
loading: false,
loadingMore: false,
refreshing: false,
noMore: false,
pageNum: 1,
pageSize: 15,
total: 0
}
},
computed: {
navTitle() {
const name = this.abilityName || '拓展能力'
return `${name} · 流水`
}
},
onLoad(e) {
this.areaId = e.areaId || ''
this.areaName = e.areaName ? decodeURIComponent(e.areaName) : ''
this.areaAbilityId = e.areaAbilityId || ''
this.abilityName = e.abilityName ? decodeURIComponent(e.abilityName) : ''
this.resetAndFetch()
},
onPullDownRefresh() {
this.onRefresherRefresh()
},
onReachBottom() {
this.loadMore()
},
methods: {
formatCount(val) {
const n = Number(val)
return Number.isFinite(n) ? n : 0
},
bstTypeLabel(item) {
const type = (item && item.bstType) || ''
const map = {
RECHARGE: '充值',
CONSUME: '消费',
DEDUCT: '扣减',
GIFT: '赠送',
BUY: '购买',
REFUND: '退款',
ADJUST: '调整'
}
if (map[type]) return map[type]
if (type) return type
const reason = (item && item.reason) || ''
if (reason.indexOf('充值') !== -1) return '充值'
if (reason.indexOf('购买') !== -1) return '购买'
if (reason.indexOf('赠送') !== -1) return '赠送'
return ''
},
mapLogItem(item) {
const changeCount = Number(item && item.changeCount)
const changeUp = Number.isFinite(changeCount) && changeCount > 0
const changeDown = Number.isFinite(changeCount) && changeCount < 0
let changeCountText = '0'
if (Number.isFinite(changeCount)) {
changeCountText = changeCount > 0 ? '+' + changeCount : String(changeCount)
}
return {
...item,
typeLabel: this.bstTypeLabel(item),
changeUp,
changeDown,
changeCountText,
changeBeforeText: this.formatCount(item && item.changeBefore),
changeAfterText: this.formatCount(item && item.changeAfter)
}
},
normalizeRows(res) {
if (res.code != 200) return []
const rows = res.rows != null ? res.rows : (Array.isArray(res.data) ? res.data : [])
return rows.map((item) => this.mapLogItem(item))
},
onRefresherRefresh() {
this.refreshing = true
this.resetAndFetch()
},
resetAndFetch() {
this.pageNum = 1
this.logList = []
this.noMore = false
this.fetchList(true)
},
fetchList(reset) {
if (!this.areaAbilityId && !this.areaId) {
this.logList = []
this.finishRefresh()
return
}
if (reset) {
this.loading = true
} else {
this.loadingMore = true
}
const params = {
pageNum: this.pageNum,
pageSize: this.pageSize,
orderByColumn: 'createTime',
isAsc: 'desc'
}
if (this.areaAbilityId) {
params.areaAbilityId = this.areaAbilityId
}
if (this.areaId) {
params.areaId = this.areaId
}
this.$u
.get('/bst/areaAbilityLog/list', params)
.then((res) => {
if (res.code == 200) {
const rows = this.normalizeRows(res)
this.total = res.total != null ? res.total : 0
if (reset) {
this.logList = rows
} else {
this.logList = this.logList.concat(rows)
}
if (rows.length < this.pageSize) {
this.noMore = true
} else {
this.pageNum += 1
}
} else {
if (reset) {
this.logList = []
this.total = 0
}
uni.showToast({ title: res.msg || '加载失败', icon: 'none' })
}
})
.catch(() => {
if (reset) {
this.logList = []
this.total = 0
}
uni.showToast({ title: '加载失败', icon: 'none' })
})
.finally(() => {
this.loading = false
this.loadingMore = false
this.finishRefresh()
})
},
finishRefresh() {
this.refreshing = false
uni.stopPullDownRefresh()
},
loadMore() {
if (this.loading || this.loadingMore || this.noMore) return
this.fetchList(false)
}
}
}
</script>
<style lang="scss">
page {
background: #f6f8fa;
height: 100%;
}
.page {
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.log-summary {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: space-between;
padding: 12rpx 24rpx;
font-size: 22rpx;
color: #6b7280;
background: #fff;
border-bottom: 1rpx solid #eef2f7;
}
.log-summary-tip {
color: #9ca3af;
font-size: 20rpx;
}
.log-scroll {
height: 85vh;
}
.log-loading,
.log-empty {
margin: 16rpx;
padding: 48rpx 0;
text-align: center;
font-size: 26rpx;
color: #9ca3af;
background: #fff;
border-radius: 12rpx;
}
.log-list {
background: #fff;
margin: 12rpx 16rpx 0;
border-radius: 12rpx;
overflow: hidden;
border: 1rpx solid #eef2f7;
}
.log-item {
padding: 16rpx 20rpx;
border-bottom: 1rpx solid #f3f4f6;
&:last-child {
border-bottom: none;
}
}
.log-item-top {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12rpx;
}
.log-item-top-left {
flex: 1;
min-width: 0;
display: flex;
align-items: flex-start;
gap: 8rpx;
}
.log-tag {
flex-shrink: 0;
margin-top: 2rpx;
padding: 2rpx 10rpx;
font-size: 20rpx;
line-height: 1.3;
color: #4297F3;
background: #eff6ff;
border-radius: 6rpx;
}
.log-reason {
flex: 1;
font-size: 24rpx;
color: #374151;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.log-time {
flex-shrink: 0;
font-size: 20rpx;
color: #9ca3af;
line-height: 1.4;
max-width: 200rpx;
text-align: right;
}
.log-item-meta {
margin-top: 8rpx;
font-size: 22rpx;
line-height: 1.35;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.log-meta-text {
color: #111827;
font-weight: 600;
font-size: 28rpx;
}
.log-meta-link {
color: #4297F3;
}
.log-meta-sub {
color: #9ca3af;
}
.log-meta-dot,
.log-meta-split {
margin: 0 6rpx;
color: #d1d5db;
}
.log-item-bottom {
margin-top: 10rpx;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 16rpx 20rpx;
}
.log-count-inline {
display: flex;
align-items: baseline;
gap: 4rpx;
}
.log-count-label {
font-size: 20rpx;
color: #9ca3af;
}
.log-count-val {
font-size: 24rpx;
font-weight: 600;
color: #111827;
}
.log-count-val--up {
color: #16a34a;
}
.log-count-val--down {
color: #ef4444;
}
.log-operator {
margin-left: auto;
font-size: 22rpx;
color: #4297F3;
max-width: 160rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.log-footer-tip {
padding: 20rpx;
text-align: center;
font-size: 22rpx;
color: #9ca3af;
}
.scroll-bottom-space {
height: 24rpx;
}
</style>