代码修改

This commit is contained in:
qiuyuan 2026-01-12 17:09:05 +08:00
parent 4094d1d227
commit 4330584af3
4 changed files with 583 additions and 191 deletions

View File

@ -44,3 +44,12 @@ export const getBankCardInfo = (params:any) => request.get('/v1/bank_card/bank_c
// 银行卡管理 - 解绑银行卡
export const delBankCard = (params:any) => request.post('/v1/bank_card/delete_bank_card',params)
// 发票管理-开票记录
export const invoiceList = (params:any) => request.get('/v1/order/invoice_list',{params})
// 发票管理-开发记录详情
export const invoiceDetail = (id:any) => request.delete(`/v1/order/invoice_detail/${id}`)
// 获取订单列表
export const getOrderList = (params:any) => request.get('/v1/order/order_list',{params})

View File

@ -76,9 +76,14 @@
</a-modal>
</template>
<script setup>
<script lang="ts" setup>
import { ref, onBeforeMount, computed } from 'vue'
import { usePagination } from '@/hooks'
import {
invoiceList,
invoiceDetail
} from '@/apis/admin'
// const listData=ref([ {title:1}])
// const paginationState=ref({
// total: 0,
@ -134,25 +139,41 @@ const rules = computed(() => ({
]
}))
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: 'invoiceDate', key: 'invoiceDate' },
{ title: '开票内容', dataIndex: 'invoiceContent', key: 'invoiceContent' },
{ title: '发票抬头', dataIndex: 'invoiceTitle', key: 'invoiceTitle' },
{ title: '发票总额', dataIndex: 'invoiceAmount', key: 'invoiceAmount' },
{ title: '开票方式', dataIndex: 'invoiceMethod', key: 'invoiceMethod' },
{ title: '发票类型', dataIndex: 'invoiceType', key: 'invoiceType' },
{ title: '发票状态', dataIndex: 'invoiceStatus', key: 'invoiceStatus' },
{ title: '驳回原因', dataIndex: 'rejectReason', key: 'rejectReason' },
{ title: '操作', dataIndex: 'flowNum', key: 'flowNum' },
])
onBeforeMount(() => {
getPageList()
})
const getPageList = () => {
listData.value = [
{ flowNum: 1 }
]
}
const getPageList = async () => {
try {
const params = {
page_num: 1,
page_size: 10, //
};
const response: any = await invoiceList(params);
if (response.data && Array.isArray(response.data)) {
listData.value = response.data
console.log('发票列表:', response.data);
}
} catch (error) {
console.error('获取全部消息失败:', error);
listData.value = [];
}
};
/**
* 分页
*/

View File

@ -36,10 +36,11 @@
<!-- 批量操作区域 -->
<div class="batch-operations" style="margin-bottom: 16px;">
<a-space>
<!-- :disabled="selectedRowKeys.length === 0" -->
<a-button
type="primary"
@click="handleBatchInvoice"
:disabled="selectedRowKeys.length === 0"
>
批量去开票
</a-button>
@ -56,7 +57,7 @@
:pagination="paginationState"
:rowSelection="rowSelection"
@change="onTableChange"
:rowKey="record => record.id || record.serial_number"
:rowKey="record => record.id || record.order_number"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'created_at'">
@ -66,7 +67,9 @@
</template>
<template v-if="column.key === 'billing_end'">
<div>
{{ dayjs(record.billing_start).format('YYYY-MM-DD HH:mm') +"~" +dayjs(record.billing_end).format('YYYY-MM-DD HH:mm') }}
{{ record.billing_start ? dayjs(record.billing_start).format('YYYY-MM-DD HH:mm') : '' }}
{{ record.billing_start && record.billing_end ? '~' : '' }}
{{ record.billing_end ? dayjs(record.billing_end).format('YYYY-MM-DD HH:mm') : '' }}
</div>
</template>
<template v-if="column.key === 'price'">
@ -76,15 +79,29 @@
</template>
<template v-if="column.key === 'real_amount'">
<div style="color: #ff4d4f; font-weight: 500;">
-¥{{ record.real_amount || '0.00' }}
-¥{{ record.real_amount || record.amount || '0.00' }}
</div>
</template>
<!-- 计费方式列 -->
<template v-if="column.key === 'billing_method'">
<a-tag :color="getBillingMethodColor(record.billing_method)">
{{ getBillingMethodText(record.billing_method) }}
</a-tag>
</template>
<!-- 支付状态列 -->
<template v-if="column.key === 'pay_status'">
<a-tag :color="getPayStatusColor(record.pay_status)">
{{ getPayStatusText(record.pay_status) }}
</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<!-- :disabled="!canApplyInvoice(record)" -->
<a-button
type="link"
size="small"
@click="handleSingleInvoice(record)"
>
去开票
</a-button>
@ -129,8 +146,8 @@
<div class="preview-title">订单列表</div>
<div class="order-list">
<div v-for="(order, index) in selectedRows.slice(0, 3)" :key="order.id" class="order-item">
<span>{{ order.serial_number }}</span>
<span>-¥{{ order.real_amount || '0.00' }}</span>
<span>{{ order.order_number }}</span>
<span>-¥{{ order.amount || order.real_amount || '0.00' }}</span>
</div>
<div v-if="selectedRows.length > 3" class="order-more">
{{ selectedRows.length }} 个订单
@ -142,11 +159,19 @@
<!-- 单个开票显示单个订单 -->
<div class="order-info-item">
<span class="info-label">订单编号</span>
<span class="info-value">{{ currentInvoiceRecord?.serial_number || '-' }}</span>
<span class="info-value">{{ currentInvoiceRecord?.order_number || '-' }}</span>
</div>
<div class="order-info-item">
<span class="info-label">计费方式</span>
<span class="info-value">{{ getBillingMethodText(currentInvoiceRecord?.billing_method) }}</span>
</div>
<div class="order-info-item">
<span class="info-label">支付状态</span>
<span class="info-value">{{ getPayStatusText(currentInvoiceRecord?.pay_status) }}</span>
</div>
<div class="order-info-item">
<span class="info-label">开票金额</span>
<span class="info-value">¥{{ currentInvoiceRecord?.real_amount || '0.00' }}</span>
<span class="info-value">¥{{ currentInvoiceRecord?.amount || currentInvoiceRecord?.real_amount || '0.00' }}</span>
</div>
</template>
</div>
@ -307,90 +332,11 @@
<script setup lang="ts">
import { ref, onBeforeMount, computed, reactive, nextTick } from 'vue'
import { usePagination } from '@/hooks'
import { useList } from '@/apis/admin'
import { getOrderList } from '@/apis/admin'
import dayjs from 'dayjs'
import { message, FormInstance } from 'ant-design-vue'
import type { Rule } from 'ant-design-vue/es/form'
//
const mockData = [
{
id: '1',
serial_number: 'SN202312270001',
created_at: '2023-12-27 10:30:00',
host_id: 'HOST-001',
host_case_id: 'CASE-001',
computing_power_model: 'RTX 4090',
gpu_count: 2,
billing_start: '2023-12-27 10:00:00',
billing_end: '2023-12-27 11:00:00',
bill_time: '1小时',
price: '50.00',
real_amount: '100.00',
status: '待开票'
},
{
id: '2',
serial_number: 'SN202312270002',
created_at: '2023-12-27 11:45:00',
host_id: 'HOST-002',
host_case_id: 'CASE-002',
computing_power_model: 'RTX 4080',
gpu_count: 1,
billing_start: '2023-12-27 11:30:00',
billing_end: '2023-12-27 12:30:00',
bill_time: '1小时',
price: '40.00',
real_amount: '40.00',
status: '待开票'
},
{
id: '3',
serial_number: 'SN202312270003',
created_at: '2023-12-27 14:20:00',
host_id: 'HOST-003',
host_case_id: 'CASE-003',
computing_power_model: 'RTX 3090',
gpu_count: 4,
billing_start: '2023-12-27 14:00:00',
billing_end: '2023-12-27 15:00:00',
bill_time: '1小时',
price: '30.00',
real_amount: '120.00',
status: '已开票'
},
{
id: '4',
serial_number: 'SN202312270004',
created_at: '2023-12-27 16:15:00',
host_id: 'HOST-004',
host_case_id: 'CASE-004',
computing_power_model: 'A100',
gpu_count: 2,
billing_start: '2023-12-27 16:00:00',
billing_end: '2023-12-27 17:00:00',
bill_time: '1小时',
price: '80.00',
real_amount: '160.00',
status: '待开票'
},
{
id: '5',
serial_number: 'SN202312270005',
created_at: '2023-12-27 18:30:00',
host_id: 'HOST-005',
host_case_id: 'CASE-005',
computing_power_model: 'H100',
gpu_count: 1,
billing_start: '2023-12-27 18:00:00',
billing_end: '2023-12-27 19:00:00',
bill_time: '1小时',
price: '100.00',
real_amount: '100.00',
status: '待开票'
}
]
//
const { listData, paginationState, resetPagination, searchFormData } = usePagination()
@ -438,6 +384,59 @@ const invoiceFormData = reactive({
remark: ''
})
//
const billingMethodMap = {
'PayOnTime': { text: '按小时计费', color: 'blue' },
'PayOnDay': { text: '按天计费', color: 'green' },
'PayOnWeek': { text: '按周计费', color: 'orange' },
'PayOnMonth': { text: '按月计费', color: 'purple' },
'PayOnYear': { text: '按年计费', color: 'red' },
//
'hourly': { text: '按小时计费', color: 'blue' },
'daily': { text: '按天计费', color: 'green' },
'weekly': { text: '按周计费', color: 'orange' },
'monthly': { text: '按月计费', color: 'purple' },
'yearly': { text: '按年计费', color: 'red' }
}
//
const payStatusMap = {
0: { text: '未支付', color: 'red' },
1: { text: '已支付', color: 'green' },
2: { text: '支付中', color: 'orange' },
3: { text: '支付失败', color: 'volcano' },
4: { text: '已退款', color: 'gray' }
}
//
const getBillingMethodText = (method: string) => {
if (!method) return '未知'
return billingMethodMap[method as keyof typeof billingMethodMap]?.text || method
}
//
const getBillingMethodColor = (method: string) => {
if (!method) return 'default'
return billingMethodMap[method as keyof typeof billingMethodMap]?.color || 'default'
}
//
const getPayStatusText = (status: number) => {
if (status === undefined || status === null) return '未知'
return payStatusMap[status as keyof typeof payStatusMap]?.text || '未知'
}
//
const getPayStatusColor = (status: number) => {
if (status === undefined || status === null) return 'default'
return payStatusMap[status as keyof typeof payStatusMap]?.color || 'default'
}
//
const canApplyInvoice = (record: any) => {
return record.pay_status === 1
}
//
const invoiceFormRules = reactive<Record<string, Rule[]>>({
invoiceType: [
@ -463,17 +462,27 @@ const invoiceFormRules = reactive<Record<string, Rule[]>>({
//
const columns = ref([
{ title: '流水号', dataIndex: 'serial_number', key: 'serial_number' },
{ title: '流水号', dataIndex: 'order_number', key: 'order_number' },
{ title: '交易时间', dataIndex: 'created_at', key: 'created_at' },
{ title: '主机ID', dataIndex: 'host_id', key: 'host_id' },
{ title: '实例ID', dataIndex: 'host_case_id', key: 'host_case_id' },
{ title: '算力型号', dataIndex: 'computing_power_model', key: 'computing_power_model' },
{ title: '算力数量', dataIndex: 'gpu_count', key: 'gpu_count' },
{ title: '计费时间范围', dataIndex: 'billing_end', key: 'billing_end' },
{ title: '计费时长', dataIndex: 'bill_time', key: 'bill_time' },
{ title: '单价', dataIndex: 'price', key: 'price' },
{ title: '交易金额', dataIndex: 'real_amount', key: 'real_amount' },
{ title: '状态', dataIndex: 'status', key: 'status' },
{
title: '计费方式',
dataIndex: 'billing_method',
key: 'billing_method',
width: 120
},
{
title: '支付状态',
dataIndex: 'pay_status',
key: 'pay_status',
width: 100
},
{ title: '产品名称', dataIndex: 'product_name', key: 'product_name' },
{
title: '交易金额',
dataIndex: 'amount',
key: 'amount',
width: 120
},
{
title: '操作',
key: 'action',
@ -484,54 +493,64 @@ const columns = ref([
//
const rowSelection = computed(() => ({
selectedRowKeys: selectedRowKeys.value,
onChange: (selectedKeys: string[], selectedRows: any[]) => {
selectedRowKeys.value = selectedKeys
selectedRows.value = selectedRows
},
getCheckboxProps: (record: any) => ({
disabled: record.status === '已开票'
})
// selectedRowKeys: selectedRowKeys.value,
// onChange: (selectedKeys: string[], selectedRows: any[]) => {
// selectedRowKeys.value = selectedKeys
// selectedRows.value = selectedRows
// },
// getCheckboxProps: (record: any) => ({
// //
// disabled: !canApplyInvoice(record)
// }),
// //
// type: 'checkbox'
}))
//
const selectedTotalAmount = computed(() => {
return selectedRows.value.reduce((total, record) => {
const amount = parseFloat(record.real_amount) || 0
const amount = parseFloat(record.amount || record.real_amount) || 0
return total + amount
}, 0)
})
//
const initMockData = () => {
listData.value = mockData
paginationState.total = mockData.length
}
onBeforeMount(() => {
//
initMockData()
// getPageList()
getPageList();
})
const getPageList = async () => {
try {
const { pageSize, current } = paginationState
const res: any = await useList({ pageSize: pageSize, pageNum: current })
listData.value = res.list
paginationState.total = res.count
const res: any = await getOrderList({
page_size: pageSize,
page_num: current,
start_at: '',
end_at: '',
order_number: ''
})
console.log('订单列表:', res)
if (res.data && Array.isArray(res.data)) {
listData.value = res.data
paginationState.total = res.total || res.data.length
} else {
listData.value = []
paginationState.total = 0
}
console.log('表格数据:', listData.value)
} catch (error: any) {
console.error('产品优势请求失败:', error)
// API使
initMockData()
console.error('订单列表请求失败:', error)
listData.value = []
paginationState.total = 0
}
}
/**
* 分页
*/
function onTableChange({ current, pageSize }) {
function onTableChange({ current, pageSize }: { current: number, pageSize: number }) {
paginationState.current = current
paginationState.pageSize = pageSize
getPageList()
@ -562,6 +581,12 @@ function handleResetSearch() {
* 单个去开票
*/
function handleSingleInvoice(record: any) {
//
if (!canApplyInvoice(record)) {
message.warning('只有已支付的订单可以申请开票')
return
}
currentInvoiceRecord.value = record
isBatch.value = false
resetInvoiceForm()
@ -572,12 +597,20 @@ function handleSingleInvoice(record: any) {
* 批量去开票
*/
function handleBatchInvoice() {
if (selectedRowKeys.value.length === 0) {
message.warning('请先选择要开票的记录')
return
}
isBatch.value = true
resetInvoiceForm()
// if (selectedRowKeys.value.length === 0) {
// message.warning('')
// return
// }
// //
// const unpaidOrders = selectedRows.value.filter(order => !canApplyInvoice(order))
// if (unpaidOrders.length > 0) {
// message.warning(` ${unpaidOrders.length} `)
// return
// }
// isBatch.value = true
// resetInvoiceForm()
singleInvoiceModalVisible.value = true
}
@ -638,13 +671,17 @@ async function handleSingleInvoiceConfirm() {
orders: isBatch.value
? selectedRows.value.map(row => ({
id: row.id,
serialNumber: row.serial_number,
amount: row.real_amount
serialNumber: row.order_number,
amount: row.amount || row.real_amount,
billingMethod: row.billing_method,
payStatus: row.pay_status
}))
: [{
id: currentInvoiceRecord.value.id,
serialNumber: currentInvoiceRecord.value.serial_number,
amount: currentInvoiceRecord.value.real_amount
serialNumber: currentInvoiceRecord.value.order_number,
amount: currentInvoiceRecord.value.amount || currentInvoiceRecord.value.real_amount,
billingMethod: currentInvoiceRecord.value.billing_method,
payStatus: currentInvoiceRecord.value.pay_status
}]
}
@ -879,4 +916,40 @@ function handleAddTitleConfirm() {
:deep(.ant-form-item) {
margin-bottom: 16px;
}
/* 表格样式优化 */
:deep(.ant-table-tbody .ant-table-cell) {
padding: 8px;
}
/* 标签样式 */
:deep(.ant-tag) {
margin-right: 0;
border-radius: 12px;
font-size: 12px;
padding: 2px 8px;
min-width: 60px;
text-align: center;
}
/* 禁用按钮样式 */
:deep(.ant-btn-link[disabled]) {
color: rgba(0, 0, 0, 0.25);
cursor: not-allowed;
}
/* 禁用复选框样式 */
:deep(.ant-checkbox-disabled .ant-checkbox-inner) {
background-color: #f5f5f5;
border-color: #d9d9d9 !important;
}
:deep(.ant-checkbox-disabled .ant-checkbox-inner::after) {
border-color: rgba(0, 0, 0, 0.25);
}
:deep(.ant-checkbox-disabled + span) {
color: rgba(0, 0, 0, 0.25);
cursor: not-allowed;
}
</style>

View File

@ -1,49 +1,191 @@
<template>
<a-card title="我的消息">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="all" tab="全部"></a-tab-pane>
<a-tab-pane key="money" tab="资金消息" force-render></a-tab-pane>
<a-tab-pane key="secure" tab="安全消息"></a-tab-pane>
<a-tab-pane key="active" tab="活动消息"></a-tab-pane>
<!-- 使用customRender来渲染带徽章的标签 -->
<a-tab-pane key="all">
<template #tab>
<span class="tab-label">
全部
<a-badge
v-if="allUnreadCount > 0"
:count="allUnreadCount"
class="tab-badge"
:offset="[5, -2]"
/>
</span>
</template>
</a-tab-pane>
<a-tab-pane key="money">
<template #tab>
<span class="tab-label">
资金消息
<a-badge
v-if="moneyUnreadCount > 0"
:count="moneyUnreadCount"
class="tab-badge"
:offset="[5, -2]"
/>
</span>
</template>
</a-tab-pane>
<a-tab-pane key="secure">
<template #tab>
<span class="tab-label">
安全消息
<a-badge
v-if="secureUnreadCount > 0"
:count="secureUnreadCount"
class="tab-badge"
:offset="[5, -2]"
/>
</span>
</template>
</a-tab-pane>
<a-tab-pane key="active">
<template #tab>
<span class="tab-label">
活动消息
<a-badge
v-if="activeUnreadCount > 0"
:count="activeUnreadCount"
class="tab-badge"
:offset="[5, -2]"
/>
</span>
</template>
</a-tab-pane>
</a-tabs>
<a-table :columns="columns" :data-source="billData" :pagination="pagination" @change="handleTableChange"
:loading="loading" class="bill-table" :scroll="{ x: 1200 }" bordered>
<a-table
:columns="columns"
:data-source="billData"
:pagination="pagination"
@change="handleTableChange"
:loading="loading"
class="bill-table"
:scroll="{ x: 1200 }"
bordered>
<!-- 消息类型列自定义渲染 -->
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'messageType'">
<span :class="{ 'unread-title': !record.is_read }">
{{ getMessageTypeText(record.messageType) }}
</span>
</template>
<template v-else-if="column.dataIndex === 'title'">
<span :class="{ 'unread-title': !record.is_read, 'read-title': record.is_read }">
{{ record.title }}
</span>
</template>
<template v-else-if="column.dataIndex === 'is_read'">
<a-tag :class="record.is_read ? 'status-read' : 'status-unread'">
{{ record.is_read ? '已读' : '未读' }}
</a-tag>
</template>
</template>
</a-table>
</a-card>
</template>
<script lang="ts" setup>
import { ref,onBeforeMount } from 'vue';
import { ref, onBeforeMount, watch, computed } from 'vue';
import { getMessageList } from '@/apis/home';
const activeKey = ref('1');
// Tab
const activeKey = ref('all');
//
const loading = ref(false);
const billData = ref([])
//
const billData = ref<any[]>([]);
//
const allMessages = ref<any[]>([]);
//
const messageType = ref<string>('');
// Tab key messageType
const keyToMessageType: Record<string, string> = {
all: '',
money: 'FinancialMessage',
secure: 'SecurityMessage',
active: 'ActivityMessage'
};
//
const messageTypeMap: Record<string, string> = {
FinancialMessage: '资金消息',
SecurityMessage: '安全消息',
ActivityMessage: '活动消息',
//
};
//
const getMessageTypeText = (type: string) => {
return messageTypeMap[type] || type || '未知类型';
};
//
const allUnreadCount = computed(() => {
return allMessages.value.filter(msg => !msg.is_read).length;
});
const moneyUnreadCount = computed(() => {
return allMessages.value.filter(msg =>
msg.messageType === 'FinancialMessage' && !msg.is_read
).length;
});
const secureUnreadCount = computed(() => {
return allMessages.value.filter(msg =>
msg.messageType === 'SecurityMessage' && !msg.is_read
).length;
});
const activeUnreadCount = computed(() => {
return allMessages.value.filter(msg =>
msg.messageType === 'ActivityMessage' && !msg.is_read
).length;
});
//
const columns = [
{
title: '消息类型',
dataIndex: 'messageType',
key: 'messageType',
width: 200,
width: 200
},
{
title: '消息内容',
dataIndex: 'messageContent',
key: 'messageContent',
width: 400,
title: '消息标题',
dataIndex: 'title',
key: 'title',
width: 400
},
{
title: '发送时间',
dataIndex: 'sendTime',
key: 'sendTime',
width: 200,
dataIndex: 'created_at',
key: 'created_at',
width: 200
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
},
dataIndex: 'is_read',
key: 'is_read',
width: 100
}
];
const messageType=ref("")
//
const pagination = ref({
current: 1,
pageSize: 10,
@ -51,27 +193,174 @@ const pagination = ref({
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total: number) => `${total} 条记录`
})
//
const handleTableChange = () => {}
const getDataList=async()=>{
loading.value = true
});
// //
const handleTableChange = (page: any) => {
pagination.value.current = page.current;
pagination.value.pageSize = page.pageSize;
getDataList();
};
//
const getAllMessages = async () => {
try {
//
const response:any = await getMessageList({
const params = {
page_num: 1,
page_size: 1000, //
Message: '' //
};
const response: any = await getMessageList(params);
if (response.data && Array.isArray(response.data)) {
allMessages.value = response.data;
} else if (response.data?.messages) {
allMessages.value = response.data.messages;
} else if (response.data?.list) {
allMessages.value = response.data.list;
} else {
allMessages.value = [];
}
console.log('全部消息统计:', {
total: allMessages.value.length,
allUnread: allUnreadCount.value,
moneyUnread: moneyUnreadCount.value,
secureUnread: secureUnreadCount.value,
activeUnread: activeUnreadCount.value
});
} catch (error) {
console.error('获取全部消息失败:', error);
allMessages.value = [];
}
};
//
const getDataList = async () => {
loading.value = true;
try {
const params = {
page_num: pagination.value.current,
page_size: pagination.value.pageSize,
Message:messageType.value
Message: messageType.value
};
const response: any = await getMessageList(params);
//
if (response.data && Array.isArray(response.data)) {
billData.value = response.data;
pagination.value.total = response.total || response.data.length;
} else if (response.data?.messages) {
billData.value = response.data.messages;
pagination.value.total = response.data.total || 0;
} else if (response.data?.list) {
billData.value = response.data.list;
pagination.value.total = response.data.total || 0;
} else {
billData.value = [];
pagination.value.total = 0;
}
console.log('当前标签页消息:', {
type: messageType.value,
count: billData.value.length,
data: billData.value
});
billData.value = response.data; // response.data.messages
pagination.value.total = response.total; // response.data.total
} catch (error) {
console.error('获取消息列表失败:', error);
billData.value = [];
pagination.value.total = 0;
} finally {
loading.value = false
loading.value = false;
}
}
};
// Tab
watch(activeKey, (newKey) => {
messageType.value = keyToMessageType[newKey] || '';
pagination.value.current = 1; //
getDataList();
});
//
onBeforeMount(() => {
getDataList()
})
//
getAllMessages();
//
getDataList();
});
//
//
// setInterval(() => {
// getAllMessages();
// }, 30000); // 30
</script>
<style scoped>
.bill-table {
margin-top: 16px;
}
/* Tab标签样式 */
.tab-label {
position: relative;
display: inline-block;
padding-right: 10px;
}
.tab-badge {
position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%);
}
/* 已读/未读标签样式 */
:deep(.status-read) {
background-color: #f6ffed;
border-color: #b7eb8f;
color: #52c41a;
font-weight: normal;
}
:deep(.status-unread) {
background-color: #fff1f0;
border-color: #ffa39e;
color: #f5222d;
font-weight: bold;
}
/* 消息标题样式 */
:deep(.unread-title) {
font-weight: bold;
color: #000000;
}
:deep(.read-title) {
font-weight: normal;
color: #666666;
}
/* 徽章样式优化 */
:deep(.ant-badge-count) {
min-width: 18px;
height: 18px;
line-height: 18px;
font-size: 11px;
padding: 0 5px;
box-shadow: 0 0 0 1px #fff;
}
/* 当前激活的Tab样式 */
:deep(.ant-tabs-tab-active .tab-label) {
color: #1890ff;
}
:deep(.ant-tabs-tab:hover .tab-label) {
color: #40a9ff;
}
</style>