|
@@ -0,0 +1,317 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="credit-box">
|
|
|
|
|
+ <div class="tabs-box">
|
|
|
|
|
+ <a-tabs v-model:activeKey="mainData.tabValue" @change="handleChangeTab">
|
|
|
|
|
+ <a-tab-pane
|
|
|
|
|
+ v-for="item in mainData.tabs"
|
|
|
|
|
+ :key="item.value"
|
|
|
|
|
+ :tab="item.name"
|
|
|
|
|
+ :disabled="mainData.disabled"
|
|
|
|
|
+ />
|
|
|
|
|
+ <template #rightExtra>
|
|
|
|
|
+ <a-select
|
|
|
|
|
+ v-model:value="mainData.year"
|
|
|
|
|
+ style="width: 120px"
|
|
|
|
|
+ :options="mainData.yearOptions"
|
|
|
|
|
+ @change="handleChangeYear"
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </a-tabs>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-list__box">
|
|
|
|
|
+ <a-empty v-if="mainData.list.length === 0" description="我的账单为空" />
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <a-card
|
|
|
|
|
+ v-for="(item, index) in mainData.list"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ class="card-item"
|
|
|
|
|
+ @click="handleDetail(item, index)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="card-item__main-content">
|
|
|
|
|
+ <div class="handle-icon__box">
|
|
|
|
|
+ <DownOutlined v-if="item.showChildren" style="color: #999; font-size: 28px;" />
|
|
|
|
|
+ <RightOutlined v-else style="color: #999; font-size: 28px;" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="main-row__content">
|
|
|
|
|
+ <div class="card-item__content">
|
|
|
|
|
+ <div class="item-label">企业名称</div>
|
|
|
|
|
+ <div class="item-value">{{ item.companyWechatName }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-item__content">
|
|
|
|
|
+ <div class="item-label">账单总金额</div>
|
|
|
|
|
+ <div class="item-value">{{ twoFloatNum(item.amount) }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-item__content">
|
|
|
|
|
+ <div class="item-label">剩余未还金额</div>
|
|
|
|
|
+ <div class="item-value">{{ twoFloatNum(item.remainingAmount) }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-item__content">
|
|
|
|
|
+ <div class="item-label">账单创建日期</div>
|
|
|
|
|
+ <div class="item-value">{{ item.createDate }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-item__content">
|
|
|
|
|
+ <div class="item-label">账单到期日期</div>
|
|
|
|
|
+ <div class="item-value">{{ item.dueDate }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-item__content">
|
|
|
|
|
+ <div class="item-label">是否已还款</div>
|
|
|
|
|
+ <div class="item-value">{{ getStatusText(item.status) }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="item.status === 'REPAID'" class="card-item__content">
|
|
|
|
|
+ <div class="item-label">还款时间</div>
|
|
|
|
|
+ <div class="item-value">{{ item.updateTime }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="item.showChildren" class="child-main__content">
|
|
|
|
|
+ <a-empty v-if="!item.children || item.children.length === 0" description="账单明细为空" />
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <a-card
|
|
|
|
|
+ v-for="(child, index) in item.children"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ class="child-card__item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="child-card__content">
|
|
|
|
|
+ <div class="item-label">企业名称</div>
|
|
|
|
|
+ <div class="item-value">{{ child.companyWechatName }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a-row :gutter="12">
|
|
|
|
|
+ <a-col :span="12">
|
|
|
|
|
+ <div class="child-card__content">
|
|
|
|
|
+ <div class="item-label">交易类型</div>
|
|
|
|
|
+ <div class="item-value">{{ getTypeText(child.transactionType) }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </a-col>
|
|
|
|
|
+ <a-col :span="12">
|
|
|
|
|
+ <div class="child-card__content">
|
|
|
|
|
+ <div class="item-label">交易金额</div>
|
|
|
|
|
+ <div class="item-value">{{ twoFloatNum(child.amount) }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </a-col>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+ <a-row :gutter="12">
|
|
|
|
|
+ <a-col :span="24">
|
|
|
|
|
+ <div class="child-card__content">
|
|
|
|
|
+ <div class="item-label">订单ID</div>
|
|
|
|
|
+ <div class="item-value">{{ child.orderId }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </a-col>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+ <a-row :gutter="12">
|
|
|
|
|
+ <a-col :span="24">
|
|
|
|
|
+ <div class="child-card__content">
|
|
|
|
|
+ <div class="item-label">交易时间</div>
|
|
|
|
|
+ <div class="item-value">{{ child.createTime }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </a-col>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+ </a-card>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </a-card>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <a-flex v-if="mainData.total > 0 && mainData.total > mainData.list.length" align="center" justify="center">
|
|
|
|
|
+ <a-button type="link" @click="handleLoadMore">点击加载更多</a-button>
|
|
|
|
|
+ </a-flex>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="js">
|
|
|
|
|
+import { DownOutlined, RightOutlined } from '@ant-design/icons-vue';
|
|
|
|
|
+import dayjs from 'dayjs';
|
|
|
|
|
+import { reactive, onMounted } from 'vue';
|
|
|
|
|
+import { getCreditBillList, getCreditBillDetail } from '@/api/user';
|
|
|
|
|
+import { useStorageStore } from '@/store/storage';
|
|
|
|
|
+import { twoFloatNum } from '@/utils/index';
|
|
|
|
|
+
|
|
|
|
|
+const storageStore = useStorageStore();
|
|
|
|
|
+const mainData = reactive({
|
|
|
|
|
+ tabValue: '',
|
|
|
|
|
+ tabs: [
|
|
|
|
|
+ {
|
|
|
|
|
+ name: '未还款',
|
|
|
|
|
+ value: 'UNPAID'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: '部分还款',
|
|
|
|
|
+ value: 'REPAYMENT'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: '已还款',
|
|
|
|
|
+ value: 'REPAID'
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ yearOptions: [],
|
|
|
|
|
+ year: '',
|
|
|
|
|
+ companyWechatId: '',
|
|
|
|
|
+ list: [],
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ total: 0,
|
|
|
|
|
+ disabled: false
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const getYearOptions = () => {
|
|
|
|
|
+ const curYear = dayjs().format('YYYY');
|
|
|
|
|
+ mainData.yearOptions = [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: `${curYear}年`,
|
|
|
|
|
+ value: `${curYear}`
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: `${curYear - 1}年`,
|
|
|
|
|
+ value: `${curYear - 1}`
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: `${curYear - 2}年`,
|
|
|
|
|
+ value: `${curYear - 2}`
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const fetchCreditBillList = () => {
|
|
|
|
|
+ const status = mainData.tabs.find(item => item.value === mainData.tabValue)?.value || '';
|
|
|
|
|
+ getCreditBillList({
|
|
|
|
|
+ status: status,
|
|
|
|
|
+ year: mainData.year,
|
|
|
|
|
+ companyWechatId: mainData.companyWechatId,
|
|
|
|
|
+ pageNum: mainData.pageNum,
|
|
|
|
|
+ pageSize: 10
|
|
|
|
|
+ }).then(res => {
|
|
|
|
|
+ mainData.list = mainData.list.concat(res.data?.records || []);
|
|
|
|
|
+ mainData.total = res.data?.total || 0;
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ mainData.disabled = false;
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleDetail = (row, index) => {
|
|
|
|
|
+ if (row.completed) {
|
|
|
|
|
+ mainData.list[index].showChildren = row.showChildren ? false : true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (mainData.list[index].loading) return;
|
|
|
|
|
+ mainData.list[index].loading = true;
|
|
|
|
|
+ getCreditBillDetail({
|
|
|
|
|
+ billId: row.billId,
|
|
|
|
|
+ companyWechatId: mainData.companyWechatId,
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ pageSize: -1
|
|
|
|
|
+ }).then(res => {
|
|
|
|
|
+ mainData.list[index].completed = true;
|
|
|
|
|
+ mainData.list[index].showChildren = true;
|
|
|
|
|
+ mainData.list[index].children = res.data?.records || [];
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ mainData.list[index].loading = false;
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleChangeTab = tabValue => {
|
|
|
|
|
+ mainData.tabValue = tabValue;
|
|
|
|
|
+ mainData.list = [];
|
|
|
|
|
+ mainData.pageNum = 1;
|
|
|
|
|
+ mainData.total = 0;
|
|
|
|
|
+ mainData.disabled = true;
|
|
|
|
|
+ fetchCreditBillList();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleChangeYear = () => {
|
|
|
|
|
+ mainData.list = [];
|
|
|
|
|
+ mainData.pageNum = 1;
|
|
|
|
|
+ mainData.total = 0;
|
|
|
|
|
+ mainData.disabled = true;
|
|
|
|
|
+ fetchCreditBillList();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleLoadMore = () => {
|
|
|
|
|
+ mainData.pageNum += 1;
|
|
|
|
|
+ mainData.disabled = true;
|
|
|
|
|
+ fetchCreditBillList();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getStatusText = status => {
|
|
|
|
|
+ return mainData.tabs.find(item => item.value === status)?.name || '';
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getTypeText = (type) => {
|
|
|
|
|
+ if (type === 'CONSUMPTION') return '消费'
|
|
|
|
|
+ if (type === 'REPAYMENT') return '还款'
|
|
|
|
|
+ if (type === 'REFUND') return '退款'
|
|
|
|
|
+ return ''
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ getYearOptions();
|
|
|
|
|
+ mainData.tabValue = mainData.tabs[0].value;
|
|
|
|
|
+ mainData.companyWechatId = storageStore.list.find(item => item.storageId === storageStore.activedId)?.companyWechatId || '';
|
|
|
|
|
+ mainData.year = mainData.yearOptions[0].value;
|
|
|
|
|
+ fetchCreditBillList();
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="less" scoped>
|
|
|
|
|
+.card-list__box {
|
|
|
|
|
+ .card-item {
|
|
|
|
|
+ margin-bottom: 15px;
|
|
|
|
|
+ .card-item__main-content {
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ width: 100%;;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ .handle-icon__box {
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ width: 40px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card-item__content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ padding: 5px 0;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ .item-label {
|
|
|
|
|
+ flex: 0 0 100px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ color: #666;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .item-value {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ color: #222;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .child-main__content {
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ .child-card__item {
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ &:last-of-type {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ .child-card__content {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ padding: 6px 0;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ .item-label {
|
|
|
|
|
+ flex: 0 0 70px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ color: #666;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .item-value {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ color: #222;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|