ylj20011123 d7aa326d2e update
2025-10-20 18:45:14 +08:00

615 lines
17 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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="invoice-detail-page">
<!-- 头部状态卡片 -->
<view class="header-section">
<view class="status-card" :class="statusClass">
<view class="status-icon">{{ statusIcon }}</view>
<view class="status-info">
<view class="status-text">{{ statusText }}</view>
<view class="status-desc">{{ statusDesc }}</view>
</view>
</view>
</view>
<!-- 主要内容区域 -->
<view class="main-content">
<!-- 发票基本信息卡片 -->
<view class="detail-card">
<view class="card-header">
<view class="card-title">发票基本信息</view>
<view class="card-icon">📋</view>
</view>
<view class="card-content">
<view class="info-row">
<text class="info-label">发票抬头</text>
<text class="info-value">{{ invoice.title }}</text>
</view>
<view class="info-row">
<text class="info-label">发票号码</text>
<text class="info-value">{{ invoice.invoiceNumber }}</text>
</view>
<view class="info-row">
<text class="info-label">发票类型</text>
<text class="info-value">{{ invoice.type }}</text>
</view>
<view class="info-row">
<text class="info-label">开票金额</text>
<text class="info-value amount">¥{{ invoice.amount }}</text>
</view>
<view class="info-row">
<text class="info-label">申请时间</text>
<text class="info-value">{{ invoice.createTime }}</text>
</view>
<view class="info-row" v-if="invoice.status === 'issued' && invoice.issueTime">
<text class="info-label">开票时间</text>
<text class="info-value">{{ invoice.issueTime }}</text>
</view>
</view>
</view>
<!-- 联系信息卡片 -->
<view class="detail-card">
<view class="card-header">
<view class="card-title">联系信息</view>
<view class="card-icon">📞</view>
</view>
<view class="card-content">
<view class="info-row">
<text class="info-label">电子邮箱</text>
<text class="info-value">{{ invoice.email || '未填写' }}</text>
</view>
<view class="info-row">
<text class="info-label">手机号码</text>
<text class="info-value">{{ invoice.phone || '未填写' }}</text>
</view>
</view>
</view>
<!-- 企业信息卡片仅企业发票显示 -->
<view class="detail-card" v-if="invoice.taxNumber">
<view class="card-header">
<view class="card-title">企业信息</view>
<view class="card-icon">🏢</view>
</view>
<view class="card-content">
<view class="info-row">
<text class="info-label">税号</text>
<text class="info-value">{{ invoice.taxNumber }}</text>
</view>
<view class="info-row" v-if="invoice.bankName">
<text class="info-label">开户银行</text>
<text class="info-value">{{ invoice.bankName }}</text>
</view>
<view class="info-row" v-if="invoice.bankAccount">
<text class="info-label">银行账号</text>
<text class="info-value">{{ invoice.bankAccount }}</text>
</view>
</view>
</view>
<!-- 驳回原因卡片仅驳回状态显示 -->
<view class="detail-card reject-card" v-if="invoice.status === 'rejected' && invoice.rejectReason">
<view class="card-header">
<view class="card-title">驳回原因</view>
<view class="card-icon"></view>
</view>
<view class="card-content">
<view class="reject-reason">
{{ invoice.rejectReason }}
</view>
</view>
</view>
<!-- 票据图片卡片 -->
<view class="detail-card" v-if="invoice.status === 'issued' && invoiceImages && invoiceImages.length > 0">
<view class="card-header">
<view class="card-title">票据图片</view>
<view class="card-icon">🖼</view>
</view>
<view class="card-content">
<view class="invoice-images">
<view class="image-item" v-for="(image, index) in invoiceImages" :key="index"
@click="previewImage(index)">
<image class="invoice-image" :src="image.url" mode="aspectFill" />
<view class="image-overlay">
<view class="preview-icon">👁</view>
<text class="preview-text">点击预览</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
menu: {}, // 手机配置信息
invoice: {}, // 发票详情数据
invoiceId: null, // 发票ID
invoiceImages: [] // 票据图片数组
}
},
computed: {
// 状态样式类
statusClass() {
var classMap = {
'issued': 'status-issued',
'applying': 'status-applying',
'rejected': 'status-rejected'
};
return classMap[this.invoice.status] || '';
},
// 状态图标
statusIcon() {
var iconMap = {
'issued': '✅',
'applying': '⏳',
'rejected': '❌'
};
return iconMap[this.invoice.status] || '';
},
// 状态文本
statusText() {
var textMap = {
'issued': '已开票',
'applying': '申请中',
'rejected': '已驳回'
};
return textMap[this.invoice.status] || '未知';
},
// 状态描述
statusDesc() {
var descMap = {
'issued': '您的发票已开具完成',
'applying': '正在为您开具发票,请耐心等待',
'rejected': '申请被驳回,请根据驳回原因修改后重新申请'
};
return descMap[this.invoice.status] || '';
}
},
onLoad(options) {
this.menu = uni.getMenuButtonBoundingClientRect();
if (options.id) {
this.invoiceId = options.id;
}
if (options.invoice) {
try {
this.invoice = JSON.parse(decodeURIComponent(options.invoice));
} catch (error) {
console.error('解析发票数据失败:', error);
}
}
// 如果没有从列表页传数据则根据ID获取详情
if (!this.invoice.id && this.invoiceId) {
this.loadInvoiceDetail();
}
},
methods: {
// 加载发票详情
loadInvoiceDetail() {
var _this = this;
try {
uni.showLoading({
title: '加载中...',
mask: true
});
// 模拟API调用
setTimeout(function () {
// 模拟数据
var mockData = {
id: _this.invoiceId,
title: '云南高速公路服务区有限公司',
invoiceNumber: 'FP202401001',
amount: '1000.00',
status: 'issued',
type: '增值税普通发票',
createTime: '2024-01-15 14:30:00',
issueTime: '2024-01-16 10:00:00',
email: 'zhangsan@example.com',
phone: '13800138000',
taxNumber: '91530100MA6KXXXXXX',
bankName: '中国银行昆明分行',
bankAccount: '6217 9027 0000 1234 567',
downloadUrl: 'https://example.com/invoice/FP202401001.pdf'
};
_this.invoice = mockData;
// 模拟票据图片数据
if (mockData.status === 'issued') {
_this.invoiceImages = [
{
url: 'https://picsum.photos/seed/invoice1/800/600.jpg',
name: '票据正面'
},
{
url: 'https://picsum.photos/seed/invoice2/800/600.jpg',
name: '票据背面'
}
];
}
uni.hideLoading();
}, 1000);
} catch (error) {
console.error('加载发票详情失败:', error);
uni.showToast({
title: '加载失败,请重试',
icon: 'none'
});
uni.hideLoading();
}
},
// 返回列表
goBack() {
uni.navigateBack({
delta: 1
});
},
// 预览图片
previewImage(index) {
var urls = this.invoiceImages.map(function (image) {
return image.url;
});
uni.previewImage({
current: index,
urls: urls
});
}
}
}
</script>
<style lang="less" scoped>
.invoice-detail-page {
min-height: 100vh;
background: linear-gradient(135deg, #E8F5E8 0%, #F8F9FA 50%, #FFFFFF 100%);
padding-bottom: 120rpx;
}
.mainTop {
width: 100%;
background-color: #f8f8f8;
box-sizing: border-box;
position: fixed;
left: 0;
top: 0;
z-index: 999;
.pageTitle {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
}
/* 头部状态卡片 */
.header-section {
padding: 40rpx 24rpx 24rpx;
}
.status-card {
border-radius: 24rpx;
padding: 40rpx;
display: flex;
align-items: center;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1);
&.status-issued {
background: linear-gradient(135deg, #22c55e, #16a34a);
color: white;
}
&.status-applying {
background: linear-gradient(135deg, #f59e0b, #d97706);
color: white;
}
&.status-rejected {
background: linear-gradient(135deg, #ef4444, #dc2626);
color: white;
}
.status-icon {
font-size: 40rpx;
margin-right: 24rpx;
}
.status-info {
flex: 1;
.status-text {
font-size: 28rpx;
font-weight: 600;
margin-bottom: 8rpx;
}
.status-desc {
font-size: 24rpx;
opacity: 0.9;
line-height: 1.4;
}
}
}
/* 主要内容区域 */
.main-content {
padding: 0 24rpx;
}
.detail-card {
background: white;
border-radius: 24rpx;
margin-bottom: 24rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.08);
border: 1rpx solid #f0f0f0;
overflow: hidden;
&.reject-card {
border-left: 8rpx solid #ef4444;
}
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx;
border-bottom: 2rpx solid #f0fdf4;
background: linear-gradient(135deg, rgba(34, 197, 94, 0.03) 0%, rgba(22, 163, 74, 0.03) 100%);
.card-title {
font-size: 30rpx;
font-weight: 600;
color: #15803d;
}
.card-icon {
font-size: 30rpx;
opacity: 0.7;
color: #22c55e;
}
}
.card-content {
padding: 24rpx;
}
.info-row {
display: flex;
align-items: flex-start;
margin-bottom: 12rpx;
&:last-child {
margin-bottom: 0;
}
.info-label {
font-size: 24rpx;
color: #666;
width: 140rpx;
flex-shrink: 0;
margin-top: 4rpx;
}
.info-value {
flex: 1;
font-size: 24rpx;
color: #333;
line-height: 1.5;
word-break: break-all;
&.amount {
color: #22c55e;
font-weight: 600;
font-size: 24rpx;
}
}
}
/* 驳回原因样式 */
.reject-reason {
background: #fef2f2;
border: 1rpx solid #fecaca;
border-radius: 16rpx;
padding: 24rpx;
font-size: 28rpx;
color: #dc2626;
line-height: 1.5;
}
/* 文件下载样式 */
.file-item {
display: flex;
align-items: center;
padding: 24rpx;
background: #f8fafc;
border-radius: 16rpx;
border: 1rpx solid #e2e8f0;
transition: all 0.3s ease;
&:active {
background: #f1f5f9;
transform: scale(0.98);
}
.file-icon {
font-size: 48rpx;
margin-right: 20rpx;
}
.file-info {
flex: 1;
.file-name {
font-size: 28rpx;
color: #333;
margin-bottom: 4rpx;
}
.file-size {
font-size: 24rpx;
color: #666;
}
}
.download-btn {
display: flex;
align-items: center;
padding: 12rpx 20rpx;
background: linear-gradient(135deg, #22c55e, #16a34a);
border-radius: 24rpx;
color: white;
.download-text {
font-size: 26rpx;
margin-right: 8rpx;
}
.download-icon {
font-size: 24rpx;
}
}
}
/* 底部操作区域 */
.bottom-actions {
position: fixed;
left: 0;
right: 0;
bottom: 0;
background: white;
padding: 24rpx;
border-top: 1rpx solid #f0f0f0;
display: flex;
gap: 16rpx;
box-shadow: 0 -8rpx 32rpx rgba(0, 0, 0, 0.1);
}
.action-btn {
flex: 1;
padding: 24rpx;
border-radius: 40rpx;
text-align: center;
font-size: 28rpx;
font-weight: 600;
transition: all 0.3s ease;
&.back-btn {
background: #f5f5f5;
color: #666;
&:active {
background: #e5e5e5;
}
}
&.primary-btn {
background: linear-gradient(135deg, #22c55e, #16a34a);
color: white;
&:active {
transform: scale(0.98);
box-shadow: 0 4rpx 16rpx rgba(34, 197, 94, 0.4);
}
}
&.secondary-btn {
background: linear-gradient(135deg, #3b82f6, #2563eb);
color: white;
&:active {
transform: scale(0.98);
box-shadow: 0 4rpx 16rpx rgba(59, 130, 246, 0.4);
}
}
.btn-text {
font-size: 28rpx;
}
}
/* 票据图片样式 */
.invoice-images {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
}
.image-item {
position: relative;
width: calc(50% - 8rpx);
height: 200rpx;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
}
}
.invoice-image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.6));
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
opacity: 0;
transition: opacity 0.3s ease;
border-radius: 16rpx;
.preview-icon {
font-size: 48rpx;
margin-bottom: 8rpx;
}
.preview-text {
font-size: 24rpx;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);
}
}
.image-item:hover .image-overlay,
.image-item:active .image-overlay {
opacity: 1;
}
</style>