180 lines
6.6 KiB
Vue

<script setup>
import { h, onMounted, ref } from 'vue'
import dayjs from 'dayjs'
import { NTag, NButton, NInput, NSelect, NDatePicker } from 'naive-ui'
import CommonPage from '@/components/page/CommonPage.vue'
import QueryBarItem from '@/components/query-bar/QueryBarItem.vue'
import CrudTable from '@/components/table/CrudTable.vue'
import { formatDate, formatDateTime } from '@/utils'
import api from '@/api'
defineOptions({ name: '交易记录' })
const $table = ref(null)
const queryItems = ref({})
const submittedDateRange = ref(null)
const handleDateRangeChange = (val) => {
if (val && val.length === 2) {
queryItems.value.submitted_start = dayjs(val[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss')
queryItems.value.submitted_end = dayjs(val[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss')
} else {
queryItems.value.submitted_start = null
queryItems.value.submitted_end = null
}
$table.value?.handleSearch()
}
const statusOptions = [
{ label: '全部', value: '' },
{ label: '未开票', value: 'pending' },
{ label: '已开票', value: 'invoiced' },
{ label: '已退款', value: 'refunded' },
{ label: '已拒绝', value: 'rejected' },
]
const invoiceTypeOptions = [
{ label: '增值税普通发票', value: 'normal' },
{ label: '增值税专用发票', value: 'special' },
]
const ticketTypeOptions = [
{ label: '纸质发票', value: 'paper' },
{ label: '电子发票', value: 'electronic' },
]
onMounted(() => {
$table.value?.handleSearch()
})
const renderStatus = (status) => {
const statusMap = {
pending: { type: 'warning', text: '未开票' },
invoiced: { type: 'success', text: '已开票' },
refunded: { type: 'info', text: '已退款' },
rejected: { type: 'error', text: '已拒绝' },
}
const config = statusMap[status] || { type: 'default', text: '未知' }
return h(NTag, { type: config.type }, { default: () => config.text })
}
const renderInvoiceType = (type) => {
const typeMap = { normal: '增值税普通发票', special: '增值税专用发票' }
return typeMap[type] || type
}
const renderTicketType = (type) => {
const typeMap = { paper: '纸质发票', electronic: '电子发票' }
return typeMap[type] || type
}
const columns = [
{ title: 'ID', key: 'id', width: 60, align: 'center', render(row) { return row?.receipt?.id || '' } },
{ title: '凭证时间', key: 'submitted_at', width: 120, align: 'center', render(row) { return formatDate(row.submitted_at) } },
{ title: '公司名称', key: 'company_name', width: 160, align: 'center', ellipsis: { tooltip: true } },
{ title: '公司税号', key: 'tax_number', width: 160, align: 'center', ellipsis: { tooltip: true } },
{ title: '手机号', key: 'phone', width: 120, align: 'center' },
{ title: '微信号', key: 'wechat', width: 120, align: 'center' },
{ title: '开票类型', key: 'invoice_type', width: 120, align: 'center', render(row) { return renderInvoiceType(row.invoice_type) } },
{ title: '供票类型', key: 'ticket_type', width: 100, align: 'center', render(row) { return renderTicketType(row.ticket_type) } },
{ title: '备注', key: 'note', width: 140, align: 'center', render(row) { return row?.receipt?.note || '' } },
{ title: '核验', key: 'verified', width: 80, align: 'center', render(row) { return h(NTag, { type: row?.receipt?.verified ? 'success' : 'warning' }, { default: () => (row?.receipt?.verified ? '已核验' : '待核验') }) } },
{ title: '凭证', key: 'url', width: 100, align: 'center', render(row) { return h(NButton, { text: true, type: 'info', onClick: () => window.open(row?.receipt?.url, '_blank') }, { default: () => '打开' }) } },
]
</script>
<template>
<CommonPage show-footer title="交易记录">
<CrudTable
ref="$table"
v-model:query-items="queryItems"
:columns="columns"
:get-data="api.getReceiptList"
>
<template #queryBar>
<QueryBarItem label="凭证时间" :label-width="80">
<NDatePicker
v-model:value="submittedDateRange"
type="daterange"
clearable
placeholder="请选择凭证时间"
style="width: 280px"
@update:value="handleDateRangeChange"
/>
</QueryBarItem>
<QueryBarItem label="手机号" :label-width="80">
<NInput
v-model:value="queryItems.phone"
clearable
type="text"
placeholder="请输入手机号"
style="width: 200px"
@keypress.enter="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="微信号" :label-width="80">
<NInput
v-model:value="queryItems.wechat"
clearable
type="text"
placeholder="请输入微信号"
style="width: 200px"
@keypress.enter="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="公司名称" :label-width="80">
<NInput
v-model:value="queryItems.company_name"
clearable
type="text"
placeholder="请输入公司名称"
style="width: 200px"
@keypress.enter="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="公司税号" :label-width="80">
<NInput
v-model:value="queryItems.tax_number"
clearable
type="text"
placeholder="请输入公司税号"
style="width: 200px"
@keypress.enter="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="状态" :label-width="80">
<NSelect
v-model:value="queryItems.status"
:options="statusOptions"
placeholder="请选择状态"
clearable
style="width: 200px"
@update:value="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="开票类型" :label-width="80">
<NSelect
v-model:value="queryItems.invoice_type"
:options="invoiceTypeOptions"
placeholder="请选择开票类型"
clearable
style="width: 200px"
@update:value="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="供票类型" :label-width="80">
<NSelect
v-model:value="queryItems.ticket_type"
:options="ticketTypeOptions"
placeholder="请选择供票类型"
clearable
style="width: 200px"
@update:value="$table?.handleSearch()"
/>
</QueryBarItem>
</template>
</CrudTable>
</CommonPage>
</template>