<template>
|
<view class="invoice-container">
|
<!-- 发票状态 -->
|
<view class="status-card">
|
<image :src="invoice.qrCode" mode="aspectFit" class="qr-code" />
|
<text class="title">电子发票</text>
|
<text class="desc">可通过微信/支付宝扫码查看</text>
|
</view>
|
|
<!-- 发票信息 -->
|
<view class="info-card">
|
<view class="section-title">发票信息</view>
|
<view class="info-list">
|
<view class="info-item">
|
<text class="label">发票代码</text>
|
<text class="value">{{ invoice.code }}</text>
|
<text class="copy" @tap="copyText(invoice.code)">复制</text>
|
</view>
|
<view class="info-item">
|
<text class="label">发票号码</text>
|
<text class="value">{{ invoice.number }}</text>
|
<text class="copy" @tap="copyText(invoice.number)">复制</text>
|
</view>
|
<view class="info-item">
|
<text class="label">开票日期</text>
|
<text class="value">{{ invoice.date }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">发票金额</text>
|
<text class="value amount">¥{{ invoice.amount }}</text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 开票信息 -->
|
<view class="info-card">
|
<view class="section-title">开票信息</view>
|
<view class="info-list">
|
<view class="info-item">
|
<text class="label">发票抬头</text>
|
<text class="value">{{ invoice.title }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">纳税人识别号</text>
|
<text class="value">{{ invoice.taxNumber }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">开票单位</text>
|
<text class="value">{{ invoice.issuer }}</text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 订单信息 -->
|
<view class="info-card">
|
<view class="section-title">订单信息</view>
|
<view class="info-list">
|
<view class="info-item">
|
<text class="label">医院</text>
|
<text class="value">{{ invoice.hospitalName }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">就诊人</text>
|
<text class="value">{{ invoice.patientName }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">就诊科室</text>
|
<text class="value">{{ invoice.departmentName }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">订单编号</text>
|
<text class="value">{{ invoice.orderNo }}</text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 预览弹窗 -->
|
<uni-popup ref="previewPopup" type="center">
|
<view class="preview-popup">
|
<view class="popup-header">
|
<text class="title">发票预览</text>
|
<text class="close" @tap="closePreview">×</text>
|
</view>
|
<view class="preview-content">
|
<image
|
:src="invoice.previewImage"
|
mode="widthFix"
|
class="preview-image"
|
@tap="previewFullImage"
|
/>
|
</view>
|
</view>
|
</uni-popup>
|
|
<!-- 打印设置弹窗 -->
|
<uni-popup ref="printPopup" type="bottom">
|
<view class="print-popup">
|
<view class="popup-header">
|
<text class="title">打印设置</text>
|
<text class="close" @tap="closePrint">×</text>
|
</view>
|
<view class="print-options">
|
<view class="option-item">
|
<text class="label">打印份数</text>
|
<view class="counter">
|
<text
|
class="minus"
|
:class="{ disabled: printCount <= 1 }"
|
@tap="printCount > 1 && printCount--"
|
>-</text>
|
<text class="count">{{ printCount }}</text>
|
<text
|
class="plus"
|
:class="{ disabled: printCount >= 5 }"
|
@tap="printCount < 5 && printCount++"
|
>+</text>
|
</view>
|
</view>
|
<view class="option-item">
|
<text class="label">打印颜色</text>
|
<view class="color-options">
|
<text
|
v-for="option in colorOptions"
|
:key="option.value"
|
:class="{ active: printColor === option.value }"
|
@tap="printColor = option.value"
|
>{{ option.label }}</text>
|
</view>
|
</view>
|
</view>
|
<button
|
class="confirm-btn primary-btn"
|
@tap="confirmPrint"
|
>确认打印</button>
|
</view>
|
</uni-popup>
|
|
<!-- 底部按钮 -->
|
<view class="bottom-buttons">
|
<button class="action-btn outline" @tap="showPreview">预览发票</button>
|
<button class="action-btn outline" @tap="showPrint">打印发票</button>
|
<button class="action-btn primary" @tap="shareInvoice">分享发票</button>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, onMounted } from 'vue'
|
|
// 发票数据
|
const invoice = ref({
|
code: '044031900111',
|
number: '37164339',
|
date: '2024-03-25',
|
amount: 360.00,
|
title: '个人',
|
taxNumber: '-',
|
issuer: '青岛镜湖医院',
|
hospitalName: '青岛镜湖医院',
|
patientName: '张三',
|
departmentName: '心内科',
|
orderNo: 'P202403250001',
|
qrCode: '/static/payment/invoice-qr.png',
|
previewImage: '/static/payment/invoice-preview.png',
|
})
|
|
// 复制文本
|
const copyText = (text) => {
|
uni.setClipboardData({
|
data: text,
|
success: () => {
|
uni.showToast({
|
title: '复制成功',
|
icon: 'success'
|
})
|
}
|
})
|
}
|
|
// 保存发票
|
const saveInvoice = () => {
|
uni.showLoading({
|
title: '保存中...'
|
})
|
|
// 这里调用保存发票API
|
setTimeout(() => {
|
uni.hideLoading()
|
uni.showToast({
|
title: '保存成功',
|
icon: 'success'
|
})
|
}, 1000)
|
}
|
|
// 分享发票
|
const shareInvoice = () => {
|
uni.share({
|
provider: 'weixin',
|
scene: 'WXSceneSession',
|
type: 2,
|
imageUrl: invoice.value.qrCode,
|
success: (res) => {
|
console.log('分享成功:', res)
|
},
|
fail: (err) => {
|
console.error('分享失败:', err)
|
}
|
})
|
}
|
|
// 预览相关
|
const previewPopup = ref(null)
|
const showPreview = () => {
|
previewPopup.value?.open()
|
}
|
const closePreview = () => {
|
previewPopup.value?.close()
|
}
|
const previewFullImage = () => {
|
uni.previewImage({
|
urls: [invoice.value.previewImage]
|
})
|
}
|
|
// 打印相关
|
const printPopup = ref(null)
|
const printCount = ref(1)
|
const colorOptions = [
|
{ label: '彩色', value: 'color' },
|
{ label: '黑白', value: 'bw' }
|
]
|
const printColor = ref('color')
|
|
const showPrint = () => {
|
printPopup.value?.open()
|
}
|
const closePrint = () => {
|
printPopup.value?.close()
|
}
|
const confirmPrint = () => {
|
uni.showLoading({
|
title: '打印中...'
|
})
|
|
// 这里调用打印API
|
const params = {
|
invoiceId: invoice.value.id,
|
count: printCount.value,
|
color: printColor.value
|
}
|
console.log('打印参数:', params)
|
|
setTimeout(() => {
|
uni.hideLoading()
|
uni.showToast({
|
title: '打印成功',
|
icon: 'success'
|
})
|
closePrint()
|
}, 2000)
|
}
|
|
onMounted(() => {
|
const pages = getCurrentPages()
|
const page = pages[pages.length - 1]
|
const id = page.$page?.options?.id
|
|
// 加载发票数据
|
loadInvoice(id)
|
})
|
|
// 加载发票数据
|
const loadInvoice = (id) => {
|
// 这里调用API获取数据
|
console.log('加载发票:', id)
|
}
|
</script>
|
|
<style lang="scss">
|
.invoice-container {
|
min-height: 100vh;
|
background: $bg-color;
|
padding: 40rpx 20rpx;
|
|
.status-card {
|
background: #fff;
|
border-radius: $radius-lg;
|
padding: 40rpx;
|
text-align: center;
|
margin-bottom: 30rpx;
|
box-shadow: $shadow-sm;
|
|
.qr-code {
|
width: 300rpx;
|
height: 300rpx;
|
margin-bottom: 30rpx;
|
}
|
|
.title {
|
font-size: 36rpx;
|
color: $text-primary;
|
font-weight: bold;
|
margin-bottom: 12rpx;
|
display: block;
|
}
|
|
.desc {
|
font-size: 26rpx;
|
color: $text-secondary;
|
}
|
}
|
|
.info-card {
|
background: #fff;
|
border-radius: $radius-lg;
|
padding: 30rpx;
|
margin-bottom: 30rpx;
|
box-shadow: $shadow-sm;
|
|
.info-list {
|
.info-item {
|
display: flex;
|
align-items: center;
|
margin-bottom: 20rpx;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.label {
|
width: 200rpx;
|
font-size: 28rpx;
|
color: $text-regular;
|
}
|
|
.value {
|
flex: 1;
|
font-size: 28rpx;
|
color: $text-primary;
|
|
&.amount {
|
color: $danger;
|
font-weight: bold;
|
}
|
}
|
|
.copy {
|
font-size: 24rpx;
|
color: $primary-color;
|
margin-left: 20rpx;
|
padding: 4rpx 12rpx;
|
background: $primary-light;
|
border-radius: $radius-sm;
|
|
&:active {
|
opacity: 0.8;
|
}
|
}
|
}
|
}
|
}
|
|
.bottom-buttons {
|
display: flex;
|
gap: 16rpx;
|
padding: 0 20rpx;
|
margin-top: 60rpx;
|
|
.action-btn {
|
flex: 1;
|
height: 80rpx;
|
line-height: 80rpx;
|
font-size: 28rpx;
|
border-radius: $radius-xl;
|
|
&.outline {
|
color: $primary-color;
|
background: #fff;
|
border: 2rpx solid $primary-color;
|
}
|
|
&.primary {
|
color: #fff;
|
background: $primary-gradient;
|
}
|
|
&:active {
|
transform: scale(0.98);
|
}
|
}
|
}
|
}
|
|
/* 预览弹窗样式 */
|
.preview-popup {
|
width: 600rpx;
|
background: #fff;
|
border-radius: $radius-lg;
|
overflow: hidden;
|
|
.popup-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 30rpx;
|
border-bottom: 1rpx solid #eee;
|
|
.title {
|
font-size: 32rpx;
|
color: $text-primary;
|
font-weight: bold;
|
}
|
|
.close {
|
font-size: 40rpx;
|
color: $text-secondary;
|
padding: 0 20rpx;
|
}
|
}
|
|
.preview-content {
|
padding: 30rpx;
|
max-height: 800rpx;
|
overflow-y: auto;
|
|
.preview-image {
|
width: 100%;
|
border-radius: $radius-sm;
|
}
|
}
|
}
|
|
/* 打印设置弹窗样式 */
|
.print-popup {
|
background: #fff;
|
border-radius: $radius-lg $radius-lg 0 0;
|
overflow: hidden;
|
|
.popup-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 30rpx;
|
border-bottom: 1rpx solid #eee;
|
|
.title {
|
font-size: 32rpx;
|
color: $text-primary;
|
font-weight: bold;
|
}
|
|
.close {
|
font-size: 40rpx;
|
color: $text-secondary;
|
padding: 0 20rpx;
|
}
|
}
|
|
.print-options {
|
padding: 30rpx;
|
|
.option-item {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 30rpx;
|
|
.label {
|
font-size: 28rpx;
|
color: $text-primary;
|
}
|
|
.counter {
|
display: flex;
|
align-items: center;
|
background: $bg-color;
|
border-radius: $radius-lg;
|
overflow: hidden;
|
|
text {
|
width: 80rpx;
|
height: 60rpx;
|
line-height: 60rpx;
|
text-align: center;
|
font-size: 28rpx;
|
|
&.minus,
|
&.plus {
|
color: $primary-color;
|
background: $primary-light;
|
|
&.disabled {
|
opacity: 0.5;
|
}
|
}
|
|
&.count {
|
color: $text-primary;
|
background: #fff;
|
font-weight: bold;
|
}
|
}
|
}
|
|
.color-options {
|
display: flex;
|
gap: 20rpx;
|
|
text {
|
padding: 10rpx 30rpx;
|
font-size: 28rpx;
|
color: $text-regular;
|
background: $bg-color;
|
border-radius: $radius-lg;
|
|
&.active {
|
color: #fff;
|
background: $primary-gradient;
|
}
|
}
|
}
|
}
|
}
|
|
.confirm-btn {
|
margin: 0 30rpx 30rpx;
|
}
|
}
|
</style>
|