shish 2 месяцев назад
Родитель
Сommit
b36f598c07
2 измененных файлов с 505 добавлено и 274 удалено
  1. 247 128
      ghsApp/src/admin/custom/balanceChange.vue
  2. 258 146
      hdApp/src/admin/custom/balanceChange.vue

+ 247 - 128
ghsApp/src/admin/custom/balanceChange.vue

@@ -1,114 +1,135 @@
 <template>
-	<view class="balance-change-page">
-		<block v-if="list.data && list.data.length">
-			<view
-				v-for="(item, index) in list.data"
-				:key="index"
-				class="balance-card"
-				@click="goDetail(item)"
-			>
-				<view class="balance-card__head">
-					<text class="balance-card__time">{{ item.timeText }}</text>
-					<view class="balance-card__amounts">
-						<text class="balance-card__change" :class="item.amountClassName">{{ item.amount }}</text>
-						<text class="balance-card__balance">余 {{ item.balanceText }}</text>
-					</view>
-				</view>
-				<view class="balance-card__event">{{ item.event }}</view>
-				<view class="balance-card__meta" v-if="item.staffName">
-					<text class="balance-card__staff">{{ item.staffName }}</text>
-				</view>
-				<view class="balance-card__extras" v-if="item.hasExtra" @click.stop>
+	<view class="bc-page">
+		<view v-if="hasList" 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.data"
+					:key="index"
+					class="bc-item"
+					:class="{ 'bc-item--alt': index % 2 === 1 }"
+				>
 					<view
-						v-if="item.showClearTag"
-						class="balance-card__tag balance-card__tag--link"
-						@click.stop="goClear(item)"
+						class="bc-row-main"
+						:class="{ 'bc-row-main--with-extra': item.showExtraRow }"
+						@click="goDetail(item)"
 					>
-						结账单 {{ item.clearSn || '' }} · 本单销{{ item.clearAmountText }}元
+						<view class="bc-td bc-td--time">
+							<text class="bc-time">{{ item.timeText }}</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.showBecomeBalance"
-						class="balance-card__tag balance-card__tag--hint"
-					>
-						剩余可用 {{ item.becomeBalanceText }}元
+					<view v-if="item.showExtraRow" class="bc-row-extra" @click.stop>
+						<view class="bc-tags-row">
+							<text
+								v-if="item.showClearLink"
+								class="bc-tag bc-tag--link"
+								@click.stop="goClear(item)"
+							>{{ item.clearLinkText }}</text>
+							<text
+								v-if="item.showBecomeBalance"
+								class="bc-tag bc-tag--muted"
+							>{{ item.becomeHintText }}</text>
+						</view>
 					</view>
 				</view>
-				<view class="balance-card__remark" v-if="item.showRemark">{{ item.remark }}</view>
 			</view>
-		</block>
-		<block v-else>
-			<AppWrapperEmpty title="暂无数据" :is-empty="listEmpty" />
-		</block>
+		</view>
+		<AppWrapperEmpty v-else title="暂无数据" :is-empty="listEmpty" />
 	</view>
 </template>
 <script>
-import AppWrapperEmpty from "@/components/app-wrapper-empty";
+import AppWrapperEmpty from '@/components/app-wrapper-empty'
 import { getCustomBalanceChange } from '@/api/custom'
 import list from '@/mixins/list'
+
 export default {
-	name: "balanceChange",
+	name: 'balanceChange',
 	components: {
 		AppWrapperEmpty
 	},
 	mixins: [list],
-	data() {
-		return {};
-	},
 	computed: {
+		hasList() {
+			return this.list.data && this.list.data.length > 0
+		},
 		listEmpty() {
-			return !this.list.data || !this.list.data.length
+			return !this.hasList
 		}
 	},
 	methods: {
 		formatMoney(val) {
 			const n = parseFloat(val)
-			return isNaN(n) ? '0' : n
+			return isNaN(n) ? '0' : String(n)
 		},
 		hasText(val) {
 			return val !== undefined && val !== null && String(val).trim() !== ''
 		},
-		normalizeListItem(item) {
-			const text = String(item.amount || '')
-			item.amountClassName = (text.indexOf('+') === 0 || Number(item.io) === 1) ? 'is-income' : 'is-expense'
-			const addTime = item.addTime || ''
-			item.timeText = addTime.length >= 16 ? addTime.substr(5, 11) : addTime
-			item.balanceText = this.formatMoney(item.balance)
-			item.clearAmountText = this.formatMoney(item.clearAmount)
-			item.becomeBalanceText = this.formatMoney(item.becomeBalance)
-			item.showClearTag = Number(item.clearId) > 0 || this.hasText(item.clearSn)
-			item.showBecomeBalance = Number(item.becomeBalance) > 0
-			item.showRemark = this.hasText(item.remark)
-			item.hasExtra = item.showClearTag || item.showBecomeBalance
-			return item
+		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 || ''
+			row.timeText = addTime.length >= 16 ? addTime.substr(5, 11) : addTime
+			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.showBecomeBalance = Number(row.becomeBalance) > 0
+			row.becomeHintText = '剩余可用 ' + this.formatMoney(row.becomeBalance) + '元'
+			row.showStaff = this.hasText(row.staffName)
+			row.showRemark = this.hasText(row.remark)
+			row.showExtraRow = row.showClearLink || row.showBecomeBalance
+			return row
+		},
+		shouldHideRow(item) {
+			return item.io == 0 && item.event && String(item.event).indexOf('结账') === 0
 		},
 		async init() {
-			const res = await getCustomBalanceChange({ page: this.list.page, customId: this.option.customId })
+			const res = await getCustomBalanceChange({
+				page: this.list.page,
+				customId: this.option.customId
+			})
 			if (this.$util.isEmpty(res.data.list)) {
 				this.completes(res)
 				return
 			}
-			let currentList = res.data.list
-			currentList = currentList.filter(function(item) {
-				if (item.io == 0 && item.event && String(item.event).indexOf('结账') === 0) {
-					return false
+			const rows = []
+			res.data.list.forEach((item) => {
+				if (this.shouldHideRow(item)) {
+					return
 				}
-				return true
-			})
-			currentList.forEach((item, index, array) => {
-				array[index].amount = item.io == 0 ? '-' + parseFloat(item.amount) : '+' + parseFloat(item.amount)
-				array[index] = this.normalizeListItem(array[index])
+				const amountDisplay = item.io == 0 ? '-' + parseFloat(item.amount) : '+' + parseFloat(item.amount)
+				rows.push(this.mapListItem(item, amountDisplay))
 			})
-			res.data.list = currentList
+			res.data.list = rows
 			this.completes(res)
 		},
 		goDetail(item) {
 			if (item.capitalType == 64) {
-				this.$util.pageTo({ url: "/admin/clear/customInfo?id=" + item.relateId })
+				this.$util.pageTo({ url: '/admin/clear/customInfo?id=' + item.relateId })
 			}
 		},
 		goClear(item) {
 			if (Number(item.clearId) > 0) {
-				this.$util.pageTo({ url: "/admin/clear/customInfo?id=" + item.clearId })
+				this.$util.pageTo({ url: '/admin/clear/customInfo?id=' + item.clearId })
 			}
 		}
 	},
@@ -120,117 +141,215 @@ export default {
 	async onReachBottom() {
 		if (!this.list.finished) {
 			await this.init()
-			uni.stopPullDownRefresh()
-		} else {
-			uni.stopPullDownRefresh()
 		}
+		uni.stopPullDownRefresh()
 	}
 }
 </script>
 <style lang="scss" scoped>
-.balance-change-page {
+.bc-page {
 	min-height: 100vh;
-	padding: 24upx;
-	background: #f5f6f8;
+	background: #fff;
 	box-sizing: border-box;
 }
 
-.balance-card {
+.bc-sheet {
+	width: 100%;
 	background: #fff;
-	border-radius: 16upx;
-	padding: 28upx 24upx;
-	margin-bottom: 20upx;
-	box-shadow: 0 2upx 16upx rgba(0, 0, 0, 0.04);
 }
 
-.balance-card__head {
+.bc-head {
 	display: flex;
-	align-items: flex-start;
-	justify-content: space-between;
+	align-items: center;
+	padding: 22upx 0;
+	background: #f8f9fb;
+	border-bottom: 1upx solid #eceef2;
 }
 
-.balance-card__time {
+.bc-th {
 	font-size: 24upx;
-	color: #999;
-	line-height: 1.4;
+	color: #8c8c8c;
+	font-weight: 500;
+	line-height: 1.2;
+}
+
+.bc-th--time {
+	width: 132upx;
 	flex-shrink: 0;
+	padding-left: 8upx;
+	box-sizing: border-box;
+}
+
+.bc-th--event {
+	flex: 1;
+	min-width: 0;
+	padding-right: 12upx;
 }
 
-.balance-card__amounts {
+.bc-th--amt {
+	width: 108upx;
+	flex-shrink: 0;
+	text-align: right;
+}
+
+.bc-th--bal {
+	width: 96upx;
+	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;
-	flex-direction: column;
-	align-items: flex-end;
-	margin-left: 20upx;
+	align-items: flex-start;
+	padding: 24upx 0;
+	box-sizing: border-box;
 }
 
-.balance-card__change {
-	font-size: 32upx;
-	font-weight: 600;
-	line-height: 1.3;
+.bc-row-main--with-extra {
+	padding-bottom: 0;
 }
 
-.balance-card__change.is-income {
-	color: #07c160;
+.bc-item:active .bc-row-main,
+.bc-item:active .bc-row-extra {
+	background: #f0f4ff;
 }
 
-.balance-card__change.is-expense {
-	color: #ff2842;
+.bc-row-extra {
+	width: 100%;
+	padding: 12upx 0 20upx;
+	border-top: 1upx solid #f0f2f5;
+	box-sizing: border-box;
 }
 
-.balance-card__balance {
-	font-size: 24upx;
-	color: #666;
-	margin-top: 6upx;
+.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: 132upx;
+	flex-shrink: 0;
+	padding-left: 8upx;
+	box-sizing: border-box;
+}
+
+.bc-td--event {
+	flex: 1;
+	min-width: 0;
+	padding-right: 12upx;
+}
+
+.bc-td--amt {
+	width: 108upx;
+	flex-shrink: 0;
+	display: flex;
+	justify-content: flex-end;
 }
 
-.balance-card__event {
-	margin-top: 16upx;
+.bc-td--bal {
+	width: 96upx;
+	flex-shrink: 0;
+	padding-right: 8upx;
+	display: flex;
+	justify-content: flex-end;
+	box-sizing: border-box;
+}
+
+.bc-time {
+	font-size: 22upx;
+	color: #2c2c2c;
+	line-height: 1.5;
+}
+
+.bc-event {
+	display: block;
 	font-size: 28upx;
-	color: #333;
+	color: #1a1a1a;
 	font-weight: 500;
 	line-height: 1.45;
 	word-break: break-all;
 }
 
-.balance-card__meta {
-	margin-top: 10upx;
-}
-
-.balance-card__staff {
-	font-size: 24upx;
+.bc-meta {
+	display: block;
+	margin-top: 8upx;
+	font-size: 22upx;
 	color: #999;
+	line-height: 1.4;
+	word-break: break-all;
 }
 
-.balance-card__extras {
-	margin-top: 16upx;
-	padding-top: 16upx;
-	border-top: 1upx solid #f0f0f0;
+.bc-meta--remark {
+	color: #b3b3b3;
 }
 
-.balance-card__tag {
-	font-size: 24upx;
-	line-height: 1.5;
+.bc-tag {
+	display: block;
+	max-width: 100%;
+	padding: 6upx 14upx;
 	margin-top: 10upx;
+	margin-right: 12upx;
+	font-size: 22upx;
+	line-height: 1.4;
+	border-radius: 8upx;
+	word-break: break-all;
+	box-sizing: border-box;
 }
 
-.balance-card__tag:first-child {
+.bc-tags-row .bc-tag:first-child {
 	margin-top: 0;
 }
 
-.balance-card__tag--link {
-	color: #3385ff;
-	font-weight: 500;
+.bc-tag--link {
+	color: #85888d;
+	background: #eef4ff;
 }
 
-.balance-card__tag--hint {
-	color: #999;
+.bc-tag--muted {
+	color: #666;
+	background: #f3f4f6;
 }
 
-.balance-card__remark {
-	margin-top: 12upx;
-	font-size: 24upx;
-	color: #999;
-	line-height: 1.4;
-	word-break: break-all;
+.bc-amount {
+	font-size: 28upx;
+	font-weight: 600;
+	line-height: 1.35;
+	font-variant-numeric: tabular-nums;
+}
+
+.bc-amount--in {
+	color: #07a84c;
+}
+
+.bc-amount--out {
+	color: #e62e45;
+}
+
+.bc-balance {
+	font-size: 26upx;
+	color: #131212;
+	line-height: 1.35;
+	font-variant-numeric: tabular-nums;
 }
 </style>

+ 258 - 146
hdApp/src/admin/custom/balanceChange.vue

@@ -1,101 +1,130 @@
 <template>
-	<view class="balance-change-page">
-		<block v-if="list.data && list.data.length">
-			<view
-				v-for="(item, index) in list.data"
-				:key="index"
-				class="balance-card"
-				@click="goDetail(item)"
-			>
-				<view class="balance-card__head">
-					<text class="balance-card__time">{{ item.timeText }}</text>
-					<view class="balance-card__amounts">
-						<text class="balance-card__change" :class="item.amountClassName">{{ item.amount }}</text>
-						<text class="balance-card__balance">余 {{ item.balanceText }}</text>
-					</view>
-				</view>
-				<view class="balance-card__event">{{ item.event }}</view>
-				<view class="balance-card__meta" v-if="item.staffName">
-					<text class="balance-card__staff">{{ item.staffName }}</text>
-				</view>
-				<view class="balance-card__extras" v-if="item.hasExtra" @click.stop>
-					<view
-						v-if="item.showSettle"
-						class="balance-card__tag balance-card__tag--link"
-						@click.stop="goSettle(item)"
-					>
-						结账单 {{ item.settleNo || '' }} · {{ item.settleAmountText }}元
-					</view>
-					<view
-						v-if="item.showBecomeBalance"
-						class="balance-card__tag balance-card__tag--hint"
-					>
-						剩余可用 {{ item.becomeBalanceText }}元
-					</view>
+	<view class="bc-page">
+		<view v-if="hasList" 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.data"
+					:key="index"
+					class="bc-item"
+					:class="{ 'bc-item--alt': index % 2 === 1 }"
+				>
 					<view
-						v-if="item.showShOrder"
-						class="balance-card__tag balance-card__tag--link"
-						@click.stop="goShPayOrder(item)"
+						class="bc-row-main"
+						:class="{ 'bc-row-main--with-extra': item.showExtraRow }"
+						@click="goDetail(item)"
 					>
-						红冲单 {{ item.shOrderSn }}
+						<view class="bc-td bc-td--time">
+							<text class="bc-time">{{ item.timeText }}</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.showRefundOrder"
-						class="balance-card__tag balance-card__tag--link"
-						@click.stop="goRefundOrder(item)"
-					>
-						订单 {{ item.refundOrderSn }}
+					<view v-if="item.showExtraRow" class="bc-row-extra" @click.stop>
+						<view class="bc-tags-row">
+							<text
+								v-if="item.showSettleLink"
+								class="bc-tag bc-tag--link"
+								@click.stop="goSettle(item)"
+							>{{ item.settleLinkText }}</text>
+							<text
+								v-if="item.showBecomeBalance"
+								class="bc-tag bc-tag--muted"
+							>{{ item.becomeHintText }}</text>
+							<text
+								v-if="item.showShOrderLink"
+								class="bc-tag bc-tag--link"
+								@click.stop="goShPayOrder(item)"
+							>{{ item.shOrderLinkText }}</text>
+							<text
+								v-if="item.showRefundLink"
+								class="bc-tag bc-tag--link"
+								@click.stop="goRefundOrder(item)"
+							>{{ item.refundLinkText }}</text>
+						</view>
 					</view>
 				</view>
-				<view class="balance-card__remark" v-if="item.showRemark">{{ item.remark }}</view>
 			</view>
-		</block>
-		<block v-else>
-			<AppWrapperEmpty title="暂无数据" :is-empty="listEmpty" />
-		</block>
+		</view>
+		<AppWrapperEmpty v-else title="暂无数据" :is-empty="listEmpty" />
 	</view>
 </template>
 <script>
-import AppWrapperEmpty from "@/components/app-wrapper-empty";
+import AppWrapperEmpty from '@/components/app-wrapper-empty'
 import { getBalanceChangeList } from '@/api/custom'
 import list from '@/mixins/list'
+
 export default {
-	name: "balanceChange",
+	name: 'balanceChange',
 	components: {
 		AppWrapperEmpty
 	},
 	mixins: [list],
-	data() {
-		return {};
-	},
 	computed: {
+		hasList() {
+			return this.list.data && this.list.data.length > 0
+		},
 		listEmpty() {
-			return !this.list.data || !this.list.data.length
+			return !this.hasList
 		}
 	},
 	methods: {
 		formatMoney(val) {
 			const n = parseFloat(val)
-			return isNaN(n) ? '0' : n
+			return isNaN(n) ? '0' : String(n)
 		},
 		hasText(val) {
 			return val !== undefined && val !== null && String(val).trim() !== ''
 		},
-		normalizeListItem(item) {
-			const text = String(item.amount || '')
-			item.amountClassName = (text.indexOf('+') === 0 || Number(item.io) === 1) ? 'is-income' : 'is-expense'
-			const addTime = item.addTime || ''
-			item.timeText = addTime.length >= 16 ? addTime.substr(5, 11) : addTime
-			item.balanceText = this.formatMoney(item.balance)
-			item.settleAmountText = this.formatMoney(item.settleAmount)
-			item.becomeBalanceText = this.formatMoney(item.becomeBalance)
-			item.showSettle = Number(item.settleId) > 0
-			item.showBecomeBalance = Number(item.settleAmount) > 0 && Number(item.becomeBalance) > 0
-			item.showShOrder = Number(item.shOrderId) > 0
-			item.showRefundOrder = Number(item.refundOrderId) > 0
-			item.showRemark = this.hasText(item.remark)
-			item.hasExtra = item.showSettle || item.showBecomeBalance || item.showShOrder || item.showRefundOrder
-			return item
+		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 || ''
+			row.timeText = addTime.length >= 16 ? addTime.substr(5, 11) : addTime
+			row.balanceText = this.formatMoney(row.balance)
+			row.showSettleLink = Number(row.settleId) > 0
+			row.settleLinkText = '结账单 ' + (row.settleNo || '') + ' · ' + this.formatMoney(row.settleAmount) + '元'
+			row.showBecomeBalance = Number(row.settleAmount) > 0 && Number(row.becomeBalance) > 0
+			row.becomeHintText = '剩余可用 ' + this.formatMoney(row.becomeBalance) + '元'
+			row.showShOrderLink = Number(row.shOrderId) > 0
+			row.shOrderLinkText = '红冲单 ' + (row.shOrderSn || '')
+			row.showRefundLink = Number(row.refundOrderId) > 0
+			row.refundLinkText = '订单 ' + (row.refundOrderSn || '')
+			row.showStaff = this.hasText(row.staffName)
+			row.showRemark = this.hasText(row.remark)
+			row.showExtraRow = row.showSettleLink || row.showBecomeBalance || row.showShOrderLink || row.showRefundLink
+			return row
+		},
+		async init() {
+			const id = this.option.id ? this.option.id : 0
+			const res = await getBalanceChangeList({ page: this.list.page, customId: id })
+			if (this.$util.isEmpty(res.data.list)) {
+				this.completes(res)
+				return
+			}
+			const rows = []
+			res.data.list.forEach((item) => {
+				const amountDisplay = item.io == 0 ? '-' + parseFloat(item.amount) : '+' + parseFloat(item.amount)
+				rows.push(this.mapListItem(item, amountDisplay))
+			})
+			res.data.list = rows
+			this.completes(res)
 		},
 		goRefundOrder(item) {
 			this.$util.pageTo({ url: '/admin/order/detail?id=' + item.refundOrderId })
@@ -113,21 +142,6 @@ export default {
 			if (item.capitalType == 59) {
 				this.$util.pageTo({ url: '/admin/order/refundDetail?id=' + item.relateId })
 			}
-		},
-		async init() {
-			const id = this.option.id ? this.option.id : 0
-			const res = await getBalanceChangeList({ page: this.list.page, customId: id })
-			if (this.$util.isEmpty(res.data.list)) {
-				this.completes(res)
-				return
-			}
-			const currentList = res.data.list
-			currentList.forEach((item, index, array) => {
-				array[index].amount = item.io == 0 ? '-' + parseFloat(item.amount) : '+' + parseFloat(item.amount)
-				array[index] = this.normalizeListItem(array[index])
-			})
-			res.data.list = currentList
-			this.completes(res)
 		}
 	},
 	async onPullDownRefresh() {
@@ -138,117 +152,215 @@ export default {
 	async onReachBottom() {
 		if (!this.list.finished) {
 			await this.init()
-			uni.stopPullDownRefresh()
-		} else {
-			uni.stopPullDownRefresh()
 		}
+		uni.stopPullDownRefresh()
 	}
 }
 </script>
 <style lang="scss" scoped>
-.balance-change-page {
+.bc-page {
 	min-height: 100vh;
-	padding: 24upx;
-	background: #f5f6f8;
+	background: #fff;
 	box-sizing: border-box;
 }
 
-.balance-card {
+.bc-sheet {
+	width: 100%;
 	background: #fff;
-	border-radius: 16upx;
-	padding: 28upx 24upx;
-	margin-bottom: 20upx;
-	box-shadow: 0 2upx 16upx rgba(0, 0, 0, 0.04);
 }
 
-.balance-card__head {
+.bc-head {
 	display: flex;
-	align-items: flex-start;
-	justify-content: space-between;
+	align-items: center;
+	padding: 22upx 0;
+	background: #f8f9fb;
+	border-bottom: 1upx solid #eceef2;
 }
 
-.balance-card__time {
+.bc-th {
 	font-size: 24upx;
-	color: #999;
-	line-height: 1.4;
+	color: #8c8c8c;
+	font-weight: 500;
+	line-height: 1.2;
+}
+
+.bc-th--time {
+	width: 132upx;
 	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: 108upx;
+	flex-shrink: 0;
+	text-align: right;
+}
+
+.bc-th--bal {
+	width: 96upx;
+	flex-shrink: 0;
+	padding-right: 8upx;
+	text-align: right;
+	box-sizing: border-box;
 }
 
-.balance-card__amounts {
+.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;
-	flex-direction: column;
-	align-items: flex-end;
-	margin-left: 20upx;
+	align-items: flex-start;
+	padding: 24upx 0;
+	box-sizing: border-box;
 }
 
-.balance-card__change {
-	font-size: 32upx;
-	font-weight: 600;
-	line-height: 1.3;
+.bc-row-main--with-extra {
+	padding-bottom: 0;
+}
+
+.bc-item:active .bc-row-main,
+.bc-item:active .bc-row-extra {
+	background: #f0f4ff;
 }
 
-.balance-card__change.is-income {
-	color: #07c160;
+.bc-row-extra {
+	width: 100%;
+	padding: 12upx 0 20upx;
+	border-top: 1upx solid #f0f2f5;
+	box-sizing: border-box;
 }
 
-.balance-card__change.is-expense {
-	color: #ff2842;
+.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;
 }
 
-.balance-card__balance {
-	font-size: 24upx;
-	color: #666;
-	margin-top: 6upx;
+.bc-td--time {
+	width: 132upx;
+	flex-shrink: 0;
+	padding-left: 8upx;
+	box-sizing: border-box;
+}
+
+.bc-td--event {
+	flex: 1;
+	min-width: 0;
+	padding-right: 12upx;
+}
+
+.bc-td--amt {
+	width: 108upx;
+	flex-shrink: 0;
+	display: flex;
+	justify-content: flex-end;
+}
+
+.bc-td--bal {
+	width: 96upx;
+	flex-shrink: 0;
+	padding-right: 8upx;
+	display: flex;
+	justify-content: flex-end;
+	box-sizing: border-box;
+}
+
+.bc-time {
+	font-size: 22upx;
+	color: #2c2c2c;
+	line-height: 1.5;
 }
 
-.balance-card__event {
-	margin-top: 16upx;
+.bc-event {
+	display: block;
 	font-size: 28upx;
-	color: #333;
+	color: #1a1a1a;
 	font-weight: 500;
 	line-height: 1.45;
 	word-break: break-all;
 }
 
-.balance-card__meta {
-	margin-top: 10upx;
-}
-
-.balance-card__staff {
-	font-size: 24upx;
+.bc-meta {
+	display: block;
+	margin-top: 8upx;
+	font-size: 22upx;
 	color: #999;
+	line-height: 1.4;
+	word-break: break-all;
 }
 
-.balance-card__extras {
-	margin-top: 16upx;
-	padding-top: 16upx;
-	border-top: 1upx solid #f0f0f0;
+.bc-meta--remark {
+	color: #b3b3b3;
 }
 
-.balance-card__tag {
-	font-size: 24upx;
-	line-height: 1.5;
+.bc-tag {
+	display: block;
+	max-width: 100%;
+	padding: 6upx 14upx;
 	margin-top: 10upx;
+	margin-right: 12upx;
+	font-size: 22upx;
+	line-height: 1.4;
+	border-radius: 8upx;
+	word-break: break-all;
+	box-sizing: border-box;
 }
 
-.balance-card__tag:first-child {
+.bc-tags-row .bc-tag:first-child {
 	margin-top: 0;
 }
 
-.balance-card__tag--link {
-	color: #3385ff;
-	font-weight: 500;
+.bc-tag--link {
+	color: #85888d;
+	background: #eef4ff;
 }
 
-.balance-card__tag--hint {
-	color: #999;
+.bc-tag--muted {
+	color: #666;
+	background: #f3f4f6;
 }
 
-.balance-card__remark {
-	margin-top: 12upx;
-	font-size: 24upx;
-	color: #999;
-	line-height: 1.4;
-	word-break: break-all;
+.bc-amount {
+	font-size: 28upx;
+	font-weight: 600;
+	line-height: 1.35;
+	font-variant-numeric: tabular-nums;
+}
+
+.bc-amount--in {
+	color: #07a84c;
+}
+
+.bc-amount--out {
+	color: #e62e45;
+}
+
+.bc-balance {
+	font-size: 26upx;
+	color: #131212;
+	line-height: 1.35;
+	font-variant-numeric: tabular-nums;
 }
 </style>