Files
cz-app/src/pages/project-center/bill-detail/index.vue
2026-09-15 17:51:59 +08:00

222 lines
6.1 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.
<script setup lang="ts">
import { computed, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getBill } from '@/constants/bill-list'
import { PAYMENT_PLAN_STATUS_LABEL } from '@/constants/project-detail'
import billPendingIcon from '@/static/icon/bill-pending.png'
import notDueIcon from '@/static/icon/not-due.png'
import successIcon from '@/static/icons/icon-register-success.png'
import type { BillItem } from '@/types/bill'
import { navigateBackWithFallback } from '@/utils/navigate-back'
type PaymentMethod = 'wechat' | 'alipay'
const bill = ref<BillItem | null>(null)
const paymentMethod = ref<PaymentMethod>('wechat')
const statusLabel = computed(() => {
if (!bill.value)
return ''
return PAYMENT_PLAN_STATUS_LABEL[bill.value.status] || ''
})
const heroIcon = computed(() => {
if (bill.value?.status === 'paid')
return successIcon
if (bill.value?.status === 'not_due')
return notDueIcon
if (bill.value?.status === 'pending')
return billPendingIcon
return successIcon
})
const paymentMethodLabel = computed(() => {
if (!bill.value)
return ''
if (bill.value.status === 'paid')
return paymentMethod.value === 'wechat' ? '微信支付' : '支付宝'
if (bill.value.status === 'pending' || bill.value.status === 'not_due')
return '微信支付'
return '--'
})
const paymentTime = computed(() => {
if (!bill.value)
return ''
if (bill.value.paidAt)
return bill.value.paidAt
if (bill.value.status === 'pending' || bill.value.status === 'not_due')
return '2026-01-21 15:00:00'
return '--'
})
const orderCardTitle = computed(() => {
if (bill.value?.status === 'paid' || bill.value?.status === 'pending')
return '已支付订单'
if (bill.value?.status === 'not_due')
return '账单订单'
return '账单订单'
})
const showPaymentInfo = computed(() =>
bill.value?.status === 'paid'
|| bill.value?.status === 'not_due'
|| bill.value?.status === 'pending',
)
const showPayFooter = computed(() => bill.value?.status === 'pending')
onLoad((options) => {
const projectId = options?.projectId ? decodeURIComponent(String(options.projectId)) : '1'
const planId = options?.planId ? decodeURIComponent(String(options.planId)) : '1'
const method = options?.method ? decodeURIComponent(String(options.method)) : 'wechat'
paymentMethod.value = method === 'alipay' ? 'alipay' : 'wechat'
bill.value = getBill(projectId, planId)
if (!bill.value) {
uni.showToast({ title: '账单不存在', icon: 'none' })
setTimeout(() => uni.navigateBack(), 1500)
}
})
function handleBack() {
navigateBackWithFallback('/pages/project-center/bill-list/index')
}
function formatAmount(amount: number) {
return `¥ ${amount}`
}
function handlePayNow() {
if (!bill.value)
return
uni.navigateTo({
url: `/pages/project-center/payment/index?projectId=${encodeURIComponent(bill.value.projectId)}&planId=${encodeURIComponent(bill.value.id)}`,
})
}
</script>
<template>
<view
v-if="bill"
class="bill-detail"
:class="{ 'bill-detail--with-footer': showPayFooter }"
>
<view class="bill-detail__navbar">
<view
class="bill-detail__back"
@tap="handleBack"
>
<image
class="bill-detail__back-icon"
src="/static/icons/icon-back.svg"
mode="aspectFit"
/>
</view>
<text class="bill-detail__navbar-title">
账单明细
</text>
<view class="bill-detail__navbar-placeholder" />
</view>
<scroll-view
class="bill-detail__scroll"
scroll-y
:show-scrollbar="false"
>
<view class="bill-detail__content">
<view class="bill-detail__hero-card">
<image
class="bill-detail__icon"
:src="heroIcon"
mode="aspectFit"
/>
<text class="bill-detail__status">
{{ statusLabel }}
</text>
<view class="bill-detail__amount-row">
<text class="bill-detail__amount-label">
付款金额:
</text>
<text class="bill-detail__amount-value">
{{ formatAmount(bill.amount) }}
</text>
</view>
</view>
<view
v-if="showPaymentInfo"
class="bill-detail__card"
>
<text class="bill-detail__card-title">
支付信息
</text>
<view class="bill-detail__info-row">
<text class="bill-detail__info-label">
支付方式
</text>
<text class="bill-detail__info-value">
{{ paymentMethodLabel }}
</text>
</view>
<view class="bill-detail__info-row">
<text class="bill-detail__info-label">
支付时间
</text>
<text class="bill-detail__info-value">
{{ paymentTime }}
</text>
</view>
<view class="bill-detail__info-row">
<text class="bill-detail__info-label">
交易流水号
</text>
<text class="bill-detail__info-value">
{{ bill.transactionNo }}
</text>
</view>
</view>
<view class="bill-detail__card">
<text class="bill-detail__card-title">
{{ orderCardTitle }}
</text>
<view class="bill-detail__order-row">
<text class="bill-detail__order-title">
{{ bill.title }} {{ bill.ratio }}
</text>
<text class="bill-detail__order-amount">
{{ formatAmount(bill.amount) }}
</text>
</view>
<text class="bill-detail__order-meta">
账单号:{{ bill.billNo }}
</text>
<text class="bill-detail__order-meta">
关联项目:{{ bill.relatedProject }}
</text>
</view>
</view>
</scroll-view>
<view
v-if="showPayFooter"
class="bill-detail__footer"
>
<view
class="bill-detail__pay-btn"
@tap="handlePayNow"
>
立即支付
</view>
</view>
</view>
</template>
<style scoped lang="scss">
@import './index.scss';
</style>