<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">&lt;</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>
