订单明细
This commit is contained in:
parent
68d5b3bb14
commit
876358ea28
@ -33,8 +33,31 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-card>
|
<a-card>
|
||||||
<a-table :dataSource="listData" :columns="columns" bordered :pagination="paginationState"
|
<!-- 批量操作区域 -->
|
||||||
@change="onTableChange">
|
<div class="batch-operations" style="margin-bottom: 16px;">
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click="handleBatchInvoice"
|
||||||
|
:disabled="selectedRowKeys.length === 0"
|
||||||
|
>
|
||||||
|
批量去开票
|
||||||
|
</a-button>
|
||||||
|
<span v-if="selectedRowKeys.length > 0">
|
||||||
|
已选择 {{ selectedRowKeys.length }} 条记录
|
||||||
|
</span>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
:dataSource="listData"
|
||||||
|
:columns="columns"
|
||||||
|
bordered
|
||||||
|
:pagination="paginationState"
|
||||||
|
:rowSelection="rowSelection"
|
||||||
|
@change="onTableChange"
|
||||||
|
:rowKey="record => record.id || record.serial_number"
|
||||||
|
>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'created_at'">
|
<template v-if="column.key === 'created_at'">
|
||||||
<div>
|
<div>
|
||||||
@ -46,37 +69,129 @@
|
|||||||
{{ dayjs(record.billing_start).format('YYYY-MM-DD HH:mm') +"~" +dayjs(record.billing_end).format('YYYY-MM-DD HH:mm') }}
|
{{ dayjs(record.billing_start).format('YYYY-MM-DD HH:mm') +"~" +dayjs(record.billing_end).format('YYYY-MM-DD HH:mm') }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="column.key === 'price'">
|
||||||
|
<div>
|
||||||
|
¥{{ record.price || '0.00' }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'real_amount'">
|
||||||
|
<div style="color: #ff4d4f; font-weight: 500;">
|
||||||
|
-¥{{ record.real_amount || '0.00' }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
@click="handleSingleInvoice(record)"
|
||||||
|
>
|
||||||
|
去开票
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
|
<!-- 单个开票确认模态框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="singleInvoiceModalVisible"
|
||||||
|
title="开票确认"
|
||||||
|
@ok="handleSingleInvoiceConfirm"
|
||||||
|
@cancel="singleInvoiceModalVisible = false"
|
||||||
|
:confirm-loading="singleInvoiceLoading"
|
||||||
|
centered
|
||||||
|
>
|
||||||
|
<div class="invoice-confirm-content">
|
||||||
|
<div class="confirm-item">
|
||||||
|
<span class="confirm-label">流水号:</span>
|
||||||
|
<span class="confirm-value">{{ currentInvoiceRecord?.serial_number || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="confirm-item">
|
||||||
|
<span class="confirm-label">交易时间:</span>
|
||||||
|
<span class="confirm-value">{{ currentInvoiceRecord?.created_at ? dayjs(currentInvoiceRecord.created_at).format('YYYY-MM-DD HH:mm') : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="confirm-item">
|
||||||
|
<span class="confirm-label">交易金额:</span>
|
||||||
|
<span class="confirm-value">¥{{ currentInvoiceRecord?.real_amount || '0.00' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="confirm-tips">
|
||||||
|
确认要为该订单申请发票吗?
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
|
<!-- 批量开票确认模态框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="batchInvoiceModalVisible"
|
||||||
|
title="批量开票确认"
|
||||||
|
@ok="handleBatchInvoiceConfirm"
|
||||||
|
@cancel="batchInvoiceModalVisible = false"
|
||||||
|
:confirm-loading="batchInvoiceLoading"
|
||||||
|
centered
|
||||||
|
width="600px"
|
||||||
|
>
|
||||||
|
<div class="batch-invoice-content">
|
||||||
|
<div class="selected-count">
|
||||||
|
已选择 {{ selectedRowKeys.length }} 条记录进行批量开票
|
||||||
|
</div>
|
||||||
|
<div class="total-amount">
|
||||||
|
<span class="total-label">合计金额:</span>
|
||||||
|
<span class="total-value">¥{{ selectedTotalAmount.toFixed(2) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="invoice-list" style="max-height: 300px; overflow-y: auto; margin-top: 16px;">
|
||||||
|
<a-table
|
||||||
|
:dataSource="selectedInvoiceRecords"
|
||||||
|
:columns="selectedColumns"
|
||||||
|
size="small"
|
||||||
|
:pagination="false"
|
||||||
|
bordered
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'created_at'">
|
||||||
|
{{ record.created_at ? dayjs(record.created_at).format('YYYY-MM-DD HH:mm') : '-' }}
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="column.key === 'real_amount'">
|
||||||
|
-¥{{ record.real_amount || '0.00' }}
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
<div class="batch-tips" style="margin-top: 16px; color: #ff4d4f;">
|
||||||
|
注意:批量开票将为所有选中的订单统一生成一张发票。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onBeforeMount } from 'vue'
|
import { ref, onBeforeMount, computed } from 'vue'
|
||||||
import { usePagination } from '@/hooks'
|
import { usePagination } from '@/hooks'
|
||||||
import { useList } from '@/apis/admin'
|
import { useList } from '@/apis/admin'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
// const listData=ref([ {title:1}])
|
import { message } from 'ant-design-vue'
|
||||||
// const paginationState=ref({
|
|
||||||
// total: 0,
|
// 表格数据
|
||||||
// current: 1,
|
|
||||||
// pageSize: 10,
|
|
||||||
// showTotal: (total) => `总 ${total} 条数据`,
|
|
||||||
// pageSizeOptions: ['10', '20', '30', '40'],
|
|
||||||
// })
|
|
||||||
const { listData, paginationState, resetPagination, searchFormData } = usePagination()
|
const { listData, paginationState, resetPagination, searchFormData } = usePagination()
|
||||||
|
|
||||||
|
// 选中的行
|
||||||
|
const selectedRowKeys = ref<string[]>([])
|
||||||
|
const selectedRows = ref<any[]>([])
|
||||||
|
|
||||||
|
// 模态框状态
|
||||||
|
const singleInvoiceModalVisible = ref(false)
|
||||||
|
const batchInvoiceModalVisible = ref(false)
|
||||||
|
const singleInvoiceLoading = ref(false)
|
||||||
|
const batchInvoiceLoading = ref(false)
|
||||||
|
|
||||||
|
// 当前操作的开票记录
|
||||||
|
const currentInvoiceRecord = ref<any>(null)
|
||||||
|
|
||||||
|
// 表格列定义
|
||||||
const columns = ref([
|
const columns = ref([
|
||||||
// { title: '订单号', dataIndex: 'flowNum', key: 'flowNum' },
|
|
||||||
// { title: '订单创建时间', dataIndex: 'transactionTime', key: 'transactionTime' },
|
|
||||||
// { title: '产品名称', dataIndex: 'flowNum', key: 'flowNum' },
|
|
||||||
// { title: '计费方式', dataIndex: 'flowNum', key: 'flowNum' },
|
|
||||||
// { title: '订单类型', dataIndex: 'flowNum', key: 'flowNum' },
|
|
||||||
// { title: '订单状态', dataIndex: 'flowNum', key: 'flowNum' },
|
|
||||||
// { title: '订单金额', dataIndex: 'flowNum', key: 'flowNum' },
|
|
||||||
// { title: '操作', dataIndex: 'flowNum', key: 'flowNum' },
|
|
||||||
{ title: '流水号', dataIndex: 'serial_number', key: 'serial_number' },
|
{ title: '流水号', dataIndex: 'serial_number', key: 'serial_number' },
|
||||||
{ title: '交易时间', dataIndex: 'created_at', key: 'created_at' },
|
{ title: '交易时间', dataIndex: 'created_at', key: 'created_at' },
|
||||||
{ title: '主机ID', dataIndex: 'host_id', key: 'host_id' },
|
{ title: '主机ID', dataIndex: 'host_id', key: 'host_id' },
|
||||||
@ -87,25 +202,62 @@ const columns = ref([
|
|||||||
{ title: '计费时长', dataIndex: 'bill_time', key: 'bill_time' },
|
{ title: '计费时长', dataIndex: 'bill_time', key: 'bill_time' },
|
||||||
{ title: '单价', dataIndex: 'price', key: 'price' },
|
{ title: '单价', dataIndex: 'price', key: 'price' },
|
||||||
{ title: '交易金额', dataIndex: 'real_amount', key: 'real_amount' },
|
{ title: '交易金额', dataIndex: 'real_amount', key: 'real_amount' },
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: 100,
|
||||||
|
align: 'center'
|
||||||
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// 批量开票模态框表格列
|
||||||
|
const selectedColumns = ref([
|
||||||
|
{ title: '流水号', dataIndex: 'serial_number', key: 'serial_number', width: 120 },
|
||||||
|
{ title: '交易时间', dataIndex: 'created_at', key: 'created_at', width: 150 },
|
||||||
|
{ title: '交易金额', dataIndex: 'real_amount', key: 'real_amount', width: 100, align: 'right' }
|
||||||
|
])
|
||||||
|
|
||||||
|
// 行选择配置
|
||||||
|
const rowSelection = computed(() => ({
|
||||||
|
selectedRowKeys: selectedRowKeys.value,
|
||||||
|
onChange: (selectedKeys: string[], selectedRows: any[]) => {
|
||||||
|
selectedRowKeys.value = selectedKeys
|
||||||
|
selectedRows.value = selectedRows
|
||||||
|
},
|
||||||
|
getCheckboxProps: (record: any) => ({
|
||||||
|
disabled: record.status === '已开票' // 可以根据状态禁用已开票的记录
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 计算选中记录的总金额
|
||||||
|
const selectedTotalAmount = computed(() => {
|
||||||
|
return selectedRows.value.reduce((total, record) => {
|
||||||
|
const amount = parseFloat(record.real_amount) || 0
|
||||||
|
return total + amount
|
||||||
|
}, 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取选中记录的数据
|
||||||
|
const selectedInvoiceRecords = computed(() => {
|
||||||
|
return selectedRows.value
|
||||||
|
})
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
getPageList()
|
getPageList()
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const getPageList = async () => {
|
const getPageList = async () => {
|
||||||
try {
|
try {
|
||||||
const { pageSize, current } = paginationState
|
const { pageSize, current } = paginationState
|
||||||
const res: any = await useList({ pageSize: pageSize, pageNum: current });
|
const res: any = await useList({ pageSize: pageSize, pageNum: current })
|
||||||
listData.value = res.list;
|
listData.value = res.list
|
||||||
paginationState.total = res.count;
|
paginationState.total = res.count
|
||||||
console.log('订单列表:', res);
|
console.log('订单列表:', res)
|
||||||
|
|
||||||
// advantageList.value = list;
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('产品优势请求失败:', error);
|
console.error('产品优势请求失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页
|
* 分页
|
||||||
*/
|
*/
|
||||||
@ -114,19 +266,190 @@ function onTableChange({ current, pageSize }) {
|
|||||||
paginationState.pageSize = pageSize
|
paginationState.pageSize = pageSize
|
||||||
getPageList()
|
getPageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索
|
* 搜索
|
||||||
*/
|
*/
|
||||||
function handleSearch() {
|
function handleSearch() {
|
||||||
resetPagination()
|
resetPagination()
|
||||||
|
selectedRowKeys.value = [] // 重置选择
|
||||||
|
selectedRows.value = []
|
||||||
getPageList()
|
getPageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置
|
* 重置
|
||||||
*/
|
*/
|
||||||
function handleResetSearch() {
|
function handleResetSearch() {
|
||||||
searchFormData.value = {}
|
searchFormData.value = {}
|
||||||
resetPagination()
|
resetPagination()
|
||||||
|
selectedRowKeys.value = [] // 重置选择
|
||||||
|
selectedRows.value = []
|
||||||
getPageList()
|
getPageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个去开票
|
||||||
|
*/
|
||||||
|
function handleSingleInvoice(record: any) {
|
||||||
|
currentInvoiceRecord.value = record
|
||||||
|
singleInvoiceModalVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认单个开票
|
||||||
|
*/
|
||||||
|
async function handleSingleInvoiceConfirm() {
|
||||||
|
singleInvoiceLoading.value = true
|
||||||
|
try {
|
||||||
|
// 这里调用开票API
|
||||||
|
// await invoiceApi.createSingleInvoice(currentInvoiceRecord.value.id)
|
||||||
|
|
||||||
|
// 模拟API调用延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
|
|
||||||
|
message.success('开票申请已提交成功!')
|
||||||
|
singleInvoiceModalVisible.value = false
|
||||||
|
|
||||||
|
// 刷新列表
|
||||||
|
getPageList()
|
||||||
|
} catch (error) {
|
||||||
|
message.error('开票申请提交失败,请稍后重试')
|
||||||
|
} finally {
|
||||||
|
singleInvoiceLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量去开票
|
||||||
|
*/
|
||||||
|
function handleBatchInvoice() {
|
||||||
|
if (selectedRowKeys.value.length === 0) {
|
||||||
|
message.warning('请先选择要开票的记录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
batchInvoiceModalVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认批量开票
|
||||||
|
*/
|
||||||
|
async function handleBatchInvoiceConfirm() {
|
||||||
|
batchInvoiceLoading.value = true
|
||||||
|
try {
|
||||||
|
// 这里调用批量开票API
|
||||||
|
// await invoiceApi.createBatchInvoice(selectedRowKeys.value)
|
||||||
|
|
||||||
|
// 模拟API调用延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1500))
|
||||||
|
|
||||||
|
message.success(`批量开票申请已提交成功,共 ${selectedRowKeys.value.length} 条记录`)
|
||||||
|
batchInvoiceModalVisible.value = false
|
||||||
|
|
||||||
|
// 清空选择
|
||||||
|
selectedRowKeys.value = []
|
||||||
|
selectedRows.value = []
|
||||||
|
|
||||||
|
// 刷新列表
|
||||||
|
getPageList()
|
||||||
|
} catch (error) {
|
||||||
|
message.error('批量开票申请提交失败,请稍后重试')
|
||||||
|
} finally {
|
||||||
|
batchInvoiceLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.batch-operations {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice-confirm-content {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-label {
|
||||||
|
color: #666;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-value {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-tips {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #f6ffed;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #52c41a;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-invoice-content .selected-count {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-amount {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-label {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-value {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-tips {
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 适配响应式 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.batch-operations {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-amount {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user