缴费列表
UI

组件
vue
<template>
<div class="page">
<template v-if="isop === '1'">
<van-list
v-model="loading"
finished-text="列表只能显示最近200条记录"
offset="200"
:finished="finished"
:immediate-check="false"
@load="onLoad"
>
<div v-for="(hist, index) in formattedHistory" :key="index">
<div v-if="hist.sign" class="pay-tab">{{ hist.sign }}</div>
<div v-else style="background-color: #fff;">
<div class="ite" @click="toDetail(hist)">
<div class="Icon ite-icon" :class="fnImg(hist.bizType)" />
<div class="ite-center">
<div class="ite-name">{{ hist.payFeeDesc }}</div>
<div class="ite-no">
<span>{{ hist.billNo }}</span>
<span> 丨 </span>
<span class="date">{{hist.createDate.substr(5,11)}}</span>
</div>
</div>
<div class="ite-money">
<div class="money"><span class="money-icon">¥</span>{{ hist.orderAmount | fen2yuan }}</div>
<div v-show="hist.orderStatusCH != '缴费成功'" class="orderStatus" :class="{ active: hist.orderStatusCH === '交易处理中' }">{{ hist.orderStatusCH }}</div>
</div>
</div>
</div>
</div>
</van-list>
</template>
<!-- 没有数据 0 或是 2 -->
<template v-else>
<div class="nullbox">
<img src="~@/assets/img/failToLoad.svg" alt="" />
<p>{{ isop === '0' ? '暂无缴费记录' : isop === '2' ? '网络异常' : '' }}</p>
</div>
</template>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
import { List } from 'vant';
import {ORDER_STATUS} from '@/utils/common/order-status';
import filter from '@/utils/filter';
export default {
components: {
VanList: List
},
filters: filter,
data() {
return {
currentPage: 1,
// 正在加载数据中
loading: false,
// 数据已加载完
finished: false,
// 区分状态 0 - 没有数据 1 - 有数据 2 - 接口失败
isop: '1',
// 缴费记录
history: [],
}
},
activated () {
if (!this.fromPaymentDetail) {
this.resetData()
this.init();
}
},
methods: {
...mapActions('payment', ['queryHistory']),
fnImg (type) {
switch (type) {
case '2':
return 'electric';
case '4': // 应该是电视费,但在缴费列表显示燃气 icon(只在这里特殊处理,因为后端接口是两个写的出了点问题)
case '3': // 燃气
return 'gas';
case 'C':
return 'tv';
case '1':
return 'water';
case '6':
return 'heat';
}
},
resetData () {
this.currentPage = 1
// 正在加载数据中
this.loading = false
// 数据已加载完
this.finished = false,
// 区分状态 0 - 没有数据 1 - 有数据 2 - 接口失败
this.isop = '1'
// 缴费记录
this.history = []
},
toDetail (detail) {
this.$store.commit('payment/setHistoryDetailObj', detail)
this.$router.push({
name: 'paymentDetail'
});
},
onLoad () {
this.loading = true;
this.currentPage += 1;
this.init();
},
async init () {
const params = {
currentPage: `${this.currentPage}`,
pageSize: '20'
};
try {
const result = await this.queryHistory(params)
if (!result.success) {
return this.$Toast(result.errorMsg)
}
if (result?.result.length > 0) {
// 请求到列表数据
this.isop = '1';
this.loading = false;
// this.recordList = [...this.recordList, ...result.result];
// this.handleResult(this.recordList);
this.history = [...this.history, ...result.result]
if (result.result.length < 20) {
// 结束加载
this.finished = true;
}
} else if (result?.result.length == 0) {
this.isop = '0'; // 第一页就没有数据 显示骨架图
this.finished = true;
} else {
this.finished = true; // 列表数据为整数 结束加载
this.loading = false;
}
} catch (err) {
this.$Toast(err.errorMsg || '网络异常');
this.loading = false;
}
}
},
computed: {
...mapState('common', ['productNo']),
...mapGetters('businessType', ['getBusTypeByKey']),
formattedHistory () {
// 当前时间对象
const date = new Date();
// 当前月份
let mon = (date.getMonth() + 1);
mon = mon < 10 ? ('0' + mon) : mon;
// date = date.getFullYear() + "-" + mon;
// 当前时间的年月份
const yearMon = date.getFullYear() + "-" + mon;
// 经过处理后的 history 数组是一个包含对象的数组
// sign 属性表示该对象所代表的时间段,比如 "本月" 或者 "2023年3月"。
// 没有 sign 属性的对象里面存放了在该时间段内的所有交易记录,每个交易记录包括订单号、交易时间、订单状态、交易金额等信息。
// 下面是一个简单的示例,以展示这个数组的结构:
// [
// { sign: '本月' },
// {
// orderNo: '1234567890',
// createTime: '2023-03-01 14:23:56',
// orderStatus: 'S0C',
// amount: '100.00'
// },
// {
// orderNo: '0987654321',
// createTime: '2023-03-08 09:15:27',
// orderStatus: 'S0F',
// amount: '50.00'
// }
// ]
const history = [];
// 用来判断是否往 history 数组推入表示年月份时间的数组
let lastSign = "";
for (const value of this.history) {
// if (value.orderStatus === "S0A") {
// continue
// }
const createDate = value.createDate;
const valueDate = new Date(createDate.substr(0, 4), createDate.substr(5, 2) - 1, createDate.substr(8, 2));
// 往 value 上添加一个 weekDate 属性
value.weekDate = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"][valueDate.getDay()]
// 往 value 上添加一个 orderStatusCH 属性
value.orderStatusCH = ORDER_STATUS?.[value.orderStatus]?.desc;
// 循环项年月份
const valueYearMon = createDate.substr(0, 7);
if (lastSign !== valueYearMon) {
if (yearMon === valueYearMon) {
history.push({
sign: "本月"
});
} else {
// 循环项的月份
let valueMon = (valueDate.getMonth() + 1);
valueMon = valueMon < 10 ? ('0' + valueMon) : valueMon;
// 循环项的年月
let signYearMon = valueDate.getFullYear() + "年" + valueMon + "月";
// 如果当前时间的年份和循环项的年份相同,只显示月即可
if (date.getFullYear() == valueDate.getFullYear()) {
signYearMon = valueMon + "月";
}
history.push({
sign: signYearMon
});
}
lastSign = valueYearMon;
}
history.push(value);
}
return history
}
},
beforeRouteEnter (to , from, next) {
if (from.name === 'paymentDetail') {
next(vm => {
vm.fromPaymentDetail = true
})
} else {
next(vm => {
vm.fromPaymentDetail = false
})
}
}
}
</script>
<style lang="scss" scoped>
.page {
background-color: #fff;
height: 100%;
.pay-tab {
width: 100%;
box-sizing: border-box;
height: 46px;
background-color: #f5f5f5;
font-size: 16px;
font-weight: 600;
padding-left: 15px;
line-height: 46px;
color: #242424;
}
.ite {
width: 345px;
padding: 15px 0;
overflow: hidden;
margin: 0 15px;
display: flex;
align-items: center;
.ite-icon {
width: 28px;
height: 28px;
align-self: self-start;
}
.ite-center {
margin-left: 12px;
width: 240px;
.ite-name {
font-size: 16px;
color: #242424;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-bottom: 5px;
}
.ite-no {
color: #808080;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 13px;
}
}
.ite-money {
margin-left: auto;
text-align: right;
.money {
font-size: 18px;
color: #242424;
font-weight: 700;
.money-icon {
font-size: 15px;
color: $color-46;
}
}
.orderStatus {
font-size: 13px;
color: $color-c7;
margin-top: 5px;
}
.active{
color: #4A7BFF;
}
}
}
.no-data-tip {
text-align: center;
font-size: 30px;
}
.nullbox {
font-size: 14px;
text-align: center;
color: #808080;
margin: 0 auto;
padding: 240px 0;
img {
width: 130px;
height: 130px;
margin-bottom: 16px;
}
}
}
</style>ORDER_STATUS
js
// 注意:"S0C" 中间的字符是数字 0,不是字母 O
export const ORDER_STATUS = {
S0C: {
desc: "交易成功",
key: "S0C"
},
S0F: {
desc: "交易失败,正在退款",
key: "S0F"
},
S0R: {
desc: "已退款",
key: "S0R"
},
S0D: {
desc: "交易进行中",
key: "S0D"
},
S0B: {
desc: "交易进行中",
key: "S0B"
},
S0A: {
desc: "待付款",
key: "S0A"
}
}