chuangte_bike_newxcx/page_shanghu/guanli/invoice_list.vue

386 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="pages">
<u-navbar title="电子发票" :border-bottom="false" :background="bgc" title-color='#fff' back-icon-color="#fff"
height='44'></u-navbar>
<!-- 搜索栏 -->
<view class="search-section">
<view class="search-bar">
<view class="search-input">
<u-icon name="search" color="#333" size="28" style="margin-right: 20rpx;"></u-icon>
<input type="text" placeholder="搜索发票编号、订单号" v-model="searchKeyword" @confirm="handleSearch" />
</view>
<view class="search-btn" @click="handleSearch">搜索</view>
</view>
</view>
<!-- 标签页导航 -->
<view class="tab-navigation">
<view
class="tab-item"
:class="{ active: activeTab === 'all' }"
@click="switchTab('all')"
>
全部
</view>
<view
class="tab-item"
:class="{ active: activeTab === 'pending' }"
@click="switchTab('pending')"
>
待审核
</view>
<view
class="tab-item"
:class="{ active: activeTab === 'submitted' }"
@click="switchTab('submitted')"
>
待上传
</view>
<view
class="tab-item"
:class="{ active: activeTab === 'success' }"
@click="switchTab('success')"
>
已审核
</view>
<view
class="tab-item"
:class="{ active: activeTab === 'rejected' }"
@click="switchTab('rejected')"
>
驳回
</view>
</view>
<!-- 发票列表 -->
<scroll-view class="invoice-list" @scrolltolower="loadMore" scroll-y refresher-enabled @refresherrefresh="onRefresh" :refresher-triggered="isRefreshing">
<view class="invoice-item" v-for="(item, index) in list" :key="index" @click="btnDetail(item)">
<view class="item-header">
<view class="invoice-no">发票编号:{{item.invoiceNo || item.no || '--'}}</view>
<view class="status-tag" :class="{
// WAIT_AUDIT待审核 => 橙色
'status-pending': item.status === 'WAIT_AUDIT',
// WAIT_UPLOAD待上传 => 蓝色
'status-submitted': item.status === 'WAIT_UPLOAD',
// REJECT已驳回 => 红色
'status-rejected': item.status === 'REJECT',
// SUCCESS已成功 => 绿色
'status-approved': item.status === 'SUCCESS',
'status-default': ['WAIT_AUDIT','WAIT_UPLOAD','REJECT','SUCCESS'].indexOf(item.status) === -1
}">
{{getStatusText(item.status)}}
</view>
</view>
<view class="item-content">
<view class="row">
<view class="label">发票金额</view>
<view class="value amount">¥{{item.requiredAmount || '0.00'}}</view>
</view>
<view class="row">
<view class="label">创建时间</view>
<view class="value">{{item.createTime || item.applyTime || '--'}}</view>
</view>
<view class="row" v-if="item.requiredRemark">
<view class="label">备注</view>
<view class="value">{{item.requiredRemark}}</view>
</view>
<view class="row" v-if="item.status === 'rejected' && item.rejectReason">
<view class="label">驳回原因</view>
<view class="value reject-reason">{{item.rejectReason}}</view>
</view>
</view>
</view>
<view class="no-more">
暂无更多发票记录...
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#4C97E7",
},
activeTab: 'all',
searchKeyword: '',
pageNum: 1,
pageSize: 20,
total: 0,
list: [],
loading: false,
finished: false,
statusParam: '',
areaId: '',
isRefreshing: false,
userId:'',
}
},
onLoad(option) {
this.userId = option.userId
this.getlist()
},
methods: {
// 下拉刷新
onRefresh() {
this.isRefreshing = true;
this.pageNum = 1;
this.finished = false;
this.getlist();
},
// 切换tab
switchTab(tab) {
this.activeTab = tab;
// 根据后端枚举WAIT_UPLOAD(待上传)、WAIT_AUDIT(待审核)、SUCCESS(已成功)、REJECT(已驳回)
if (tab === 'all') {
this.statusParam = '';
} else if (tab === 'pending') {
// 待审核
this.statusParam = 'WAIT_AUDIT';
} else if (tab === 'submitted') {
// 待上传
this.statusParam = 'WAIT_UPLOAD';
} else if (tab === 'rejected') {
// 已驳回
this.statusParam = 'REJECT';
} else if (tab === 'success') {
// 已审核(已成功)
this.statusParam = 'SUCCESS';
}
this.pageNum = 1;
this.finished = false;
this.searchKeyword = ''; // 切换tab时清空搜索
this.getlist();
},
// 获取状态文本(兼容新老枚举)
getStatusText(status) {
// 后端状态WAIT_UPLOAD(待上传)、WAIT_AUDIT(待审核)、SUCCESS(已成功)、REJECT(已驳回)
const statusMap = {
WAIT_UPLOAD: '待上传',
WAIT_AUDIT: '待审核',
SUCCESS: '已审核',
REJECT: '已驳回',
// 兼容旧枚举
pending: '待审核',
submitted: '待上传',
rejected: '已驳回',
approved: '已审核',
completed: '已审核'
};
return statusMap[status] || status || '未知';
},
// 点击查看详情
btnDetail(item) {
uni.navigateTo({
url: '/page_shanghu/guanli/invoice_detail?id=' + item.id
})
},
// 搜索
handleSearch() {
this.pageNum = 1;
this.finished = false;
this.getlist();
},
// 触底加载
loadMore() {
if (this.loading || this.finished) return;
this.pageNum += 1;
this.getlist();
},
// 请求发票列表
getlist() {
if (this.loading) return
this.loading = true
// 组装查询参数status 在“全部”时不传,其余传后端枚举
let url = `/bst/userInvoice/list?pageNum=${this.pageNum}&pageSize=${this.pageSize}&userId=${this.userId}&Keyword=${this.searchKeyword}`;
if (this.statusParam) {
url += `&status=${this.statusParam}`
}
this.$u.get(url).then(res => {
if (res.code === 200) {
this.total = res.total
if(this.pageNum == 1){
this.list = res.rows
this.pageNum ++
}else{
this.list = this.list.concat(res.rows)
}
}
}).finally(() => {
this.loading = false;
this.isRefreshing = false;
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #f7f7f7;
}
.pages {
min-height: 100vh;
background-color: #f7f7f7;
}
.search-section {
background-color: #fff;
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f0f0f0;
.search-bar {
display: flex;
align-items: center;
.search-input {
flex: 1;
display: flex;
align-items: center;
border: 1rpx solid #d8e8d8;
border-radius: 40rpx;
padding: 0 20rpx;
background-color: #fff;
height: 68rpx;
input {
flex: 1;
font-size: 26rpx;
color: #333;
}
}
.search-btn {
margin-left: 16rpx;
background-color: #4C97E7;
color: #fff;
padding: 16rpx 28rpx;
border-radius: 12rpx;
font-size: 26rpx;
}
}
}
.tab-navigation {
background-color: #fff;
display: flex;
border-bottom: 1rpx solid #eee;
.tab-item {
flex: 1;
text-align: center;
padding: 26rpx 0;
font-size: 28rpx;
color: #444;
position: relative;
&.active {
color: #4C97E7;
font-weight: 600;
}
&.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 80rpx;
height: 4rpx;
background-color: #4C97E7;
border-radius: 2rpx;
}
}
}
.invoice-list {
height: 76vh;
background-color: #f7f7f7;
.invoice-item {
background-color: #fff;
border-radius: 16rpx;
margin-bottom: 20rpx;
padding: 24rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
width: 710rpx;
margin: auto;
margin-top: 20rpx;
.item-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
.invoice-no {
font-size: 28rpx;
font-weight: 600;
color: #333;
}
.status-tag {
padding: 8rpx 20rpx;
border-radius: 20rpx;
font-size: 24rpx;
&.status-pending {
background-color: #fff7e6;
color: #fa8c16;
}
&.status-submitted {
background-color: #e6f7ff;
color: #1890ff;
}
&.status-rejected {
background-color: #fff1f0;
color: #ff4d4f;
}
&.status-approved {
background-color: #f6ffed;
color: #52c41a;
}
&.status-default {
background-color: #f5f5f5;
color: #666;
}
}
}
.item-content {
padding-top: 20rpx;
.row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
&:last-child {
margin-bottom: 0;
}
.label {
font-size: 26rpx;
color: #999;
width: 160rpx;
}
.value {
flex: 1;
font-size: 28rpx;
color: #333;
text-align: right;
&.amount {
color: #ff4d4f;
font-weight: 600;
font-size: 32rpx;
}
&.reject-reason {
color: #ff4d4f;
font-size: 26rpx;
}
}
}
}
}
.no-more {
text-align: center;
color: #999;
font-size: 26rpx;
padding: 40rpx 0;
}
.loading-more {
text-align: center;
color: #999;
font-size: 26rpx;
padding: 20rpx 0;
}
}
</style>