diff --git a/web/src/api/index.js b/web/src/api/index.js index 134468f..ea40b88 100644 --- a/web/src/api/index.js +++ b/web/src/api/index.js @@ -150,13 +150,227 @@ export default { updateAppUser: (data = {}) => request.post('/app-user/update', data), deleteAppUser: (params = {}) => request.delete('/app-user/delete', { params }), // invoice (开票记录) - getInvoiceList: (params = {}) => request.get('/invoice/list', { params }), + getInvoiceList: (params = {}) => { + // Mock 数据 + const mockInvoices = [ + { + id: 1001, + created_at: '2024-11-10T09:30:00Z', + ticket_type: 'electronic', + phone: '13800138001', + email: 'zhangsan@company1.com', + company_name: '北京科技有限公司', + tax_number: '91110000123456789A', + register_address: '北京市朝阳区科技园区A座1001室', + register_phone: '010-12345678', + bank_name: '中国工商银行北京分行', + bank_account: '6222021234567890123', + invoice_type: 'special', + status: 'pending' + }, + { + id: 1002, + created_at: '2024-11-09T14:20:00Z', + ticket_type: 'paper', + phone: '13800138002', + email: 'lisi@company2.com', + company_name: '上海贸易股份有限公司', + tax_number: '91310000987654321B', + register_address: '上海市浦东新区金融街B座2002室', + register_phone: '021-87654321', + bank_name: '中国建设银行上海分行', + bank_account: '6217001234567890124', + invoice_type: 'normal', + status: 'invoiced' + }, + { + id: 1003, + created_at: '2024-11-08T16:45:00Z', + ticket_type: 'electronic', + phone: '13800138003', + email: 'wangwu@company3.com', + company_name: '深圳创新科技有限公司', + tax_number: '91440300456789012C', + register_address: '深圳市南山区高新技术园C座3003室', + register_phone: '0755-23456789', + bank_name: '招商银行深圳分行', + bank_account: '6214851234567890125', + invoice_type: 'special', + status: 'rejected' + }, + { + id: 1004, + created_at: '2024-11-07T11:15:00Z', + ticket_type: 'paper', + phone: '13800138004', + email: 'zhaoliu@company4.com', + company_name: '广州制造业集团有限公司', + tax_number: '91440100789012345D', + register_address: '广州市天河区商务中心D座4004室', + register_phone: '020-34567890', + bank_name: '中国银行广州分行', + bank_account: '6013821234567890126', + invoice_type: 'normal', + status: 'pending' + }, + { + id: 1005, + created_at: '2024-11-06T08:30:00Z', + ticket_type: 'electronic', + phone: '13800138005', + email: 'sunqi@company5.com', + company_name: '杭州互联网科技有限公司', + tax_number: '91330100012345678E', + register_address: '杭州市西湖区互联网小镇E座5005室', + register_phone: '0571-45678901', + bank_name: '浙商银行杭州分行', + bank_account: '6228481234567890127', + invoice_type: 'special', + status: 'invoiced' + }, + { + id: 1006, + created_at: '2024-11-05T13:20:00Z', + ticket_type: 'paper', + phone: '13800138006', + email: 'zhouba@company6.com', + company_name: '成都软件开发有限公司', + tax_number: '91510100345678901F', + register_address: '成都市高新区软件园F座6006室', + register_phone: '028-56789012', + bank_name: '中国农业银行成都分行', + bank_account: '6230521234567890128', + invoice_type: 'normal', + status: 'pending' + }, + { + id: 1007, + created_at: '2024-11-04T15:45:00Z', + ticket_type: 'electronic', + phone: '13800138007', + email: 'wujiu@company7.com', + company_name: '武汉新能源科技有限公司', + tax_number: '91420100678901234G', + register_address: '武汉市江汉区新能源产业园G座7007室', + register_phone: '027-67890123', + bank_name: '交通银行武汉分行', + bank_account: '6222601234567890129', + invoice_type: 'special', + status: 'invoiced' + }, + { + id: 1008, + created_at: '2024-11-03T10:10:00Z', + ticket_type: 'paper', + phone: '13800138008', + email: 'zhengshi@company8.com', + company_name: '西安电子商务有限公司', + tax_number: '91610100901234567H', + register_address: '西安市雁塔区电商产业园H座8008室', + register_phone: '029-78901234', + bank_name: '中信银行西安分行', + bank_account: '6217711234567890130', + invoice_type: 'normal', + status: 'refunded' + }, + { + id: 1009, + created_at: '2024-11-02T14:30:00Z', + ticket_type: 'electronic', + phone: '13800138009', + email: 'wangwu@company9.com', + company_name: '天津物流科技有限公司', + tax_number: '91120000234567890I', + register_address: '天津市滨海新区物流园I座9009室', + register_phone: '022-89012345', + bank_name: '民生银行天津分行', + bank_account: '6226221234567890131', + invoice_type: 'special', + status: 'refunded' + }, + { + id: 1010, + created_at: '2024-11-01T11:45:00Z', + ticket_type: 'paper', + phone: '13800138010', + email: 'liuliu@company10.com', + company_name: '重庆智能制造有限公司', + tax_number: '91500000567890123J', + register_address: '重庆市渝北区智能制造园J座1010室', + register_phone: '023-90123456', + bank_name: '华夏银行重庆分行', + bank_account: '6228881234567890132', + invoice_type: 'normal', + status: 'rejected' + } + ] + + // 模拟分页和搜索 + let filteredInvoices = [...mockInvoices] + + // 手机号搜索 + if (params.phone) { + filteredInvoices = filteredInvoices.filter(invoice => + invoice.phone.includes(params.phone) + ) + } + + // 公司名称搜索 + if (params.company_name) { + filteredInvoices = filteredInvoices.filter(invoice => + invoice.company_name.includes(params.company_name) + ) + } + + // 公司税号搜索 + if (params.tax_number) { + filteredInvoices = filteredInvoices.filter(invoice => + invoice.tax_number.includes(params.tax_number) + ) + } + + // 状态筛选 + if (params.status) { + filteredInvoices = filteredInvoices.filter(invoice => + invoice.status === params.status + ) + } + + // 提交时间筛选 + if (params.created_at && Array.isArray(params.created_at) && params.created_at.length === 2) { + const [startDate, endDate] = params.created_at + filteredInvoices = filteredInvoices.filter(invoice => { + const invoiceDate = new Date(invoice.created_at) + return invoiceDate >= new Date(startDate) && invoiceDate <= new Date(endDate) + }) + } + + // 分页处理 + const page = params.page || 1 + const pageSize = params.page_size || 10 + const startIndex = (page - 1) * pageSize + const endIndex = startIndex + pageSize + const paginatedInvoices = filteredInvoices.slice(startIndex, endIndex) + + // 返回 Promise 模拟异步请求 + return new Promise((resolve) => { + setTimeout(() => { + resolve({ + data: paginatedInvoices, + total: filteredInvoices.length, + page: page, + page_size: pageSize + }) + }, 300) // 模拟网络延迟 + }) + }, getInvoiceById: (params = {}) => request.get('/invoice/detail', { params }), createInvoice: (data = {}) => request.post('/invoice/create', data), updateInvoice: (data = {}) => request.post('/invoice/update', data), deleteInvoice: (params = {}) => request.delete('/invoice/delete', { params }), updateInvoiceStatus: (data = {}) => request.post('/invoice/update-status', data), remindInvoice: (data = {}) => request.post('/invoice/remind', data), + refundInvoice: (data = {}) => request.post('/invoice/refund', data), // valuation (估值评估) getValuationList: (params = {}) => request.get('/valuation', { params }), getValuationById: (params = {}) => request.get(`/valuation/${params.valuation_id}`), diff --git a/web/src/views/transaction/invoice/index.vue b/web/src/views/transaction/invoice/index.vue index 92330a9..bd492ee 100644 --- a/web/src/views/transaction/invoice/index.vue +++ b/web/src/views/transaction/invoice/index.vue @@ -32,6 +32,7 @@ const statusOptions = [ { label: '全部', value: '' }, { label: '未开票', value: 'pending' }, { label: '已开票', value: 'invoiced' }, + { label: '已退款', value: 'refunded' }, { label: '已拒绝', value: 'rejected' }, ] @@ -76,6 +77,7 @@ 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: '未知' } @@ -202,27 +204,12 @@ const columns = [ { title: '操作', key: 'actions', - width: 200, + width: 180, align: 'center', fixed: 'right', render(row) { return [ - // 开票提醒按钮 - row.status === 'pending' && - h( - NButton, - { - size: 'small', - type: 'info', - style: 'margin-right: 8px;', - onClick: () => handleRemind(row), - }, - { - default: () => '开票提醒', - icon: renderIcon('mdi:bell-outline', { size: 16 }), - } - ), - // 已开票按钮 + // 开票按钮 - 未开票状态显示 row.status === 'pending' && h( NPopconfirm, @@ -239,19 +226,19 @@ const columns = [ style: 'margin-right: 8px;', }, { - default: () => '已开票', - icon: renderIcon('mdi:check-circle-outline', { size: 16 }), + default: () => '开票', + // icon: renderIcon('mdi:receipt-text-outline', { size: 16 }), } ), - default: () => h('div', {}, '确认已开票?'), + default: () => h('div', {}, '确认开票?'), } ), - // 已拒绝按钮 + // 退款按钮 - 未开票状态显示 row.status === 'pending' && h( NPopconfirm, { - onPositiveClick: () => handleUpdateStatus(row, 'rejected'), + onPositiveClick: () => handleRefund(row), }, { trigger: () => @@ -259,15 +246,30 @@ const columns = [ NButton, { size: 'small', - type: 'error', + type: 'primary', style: 'margin-right: 8px;', }, { - default: () => '已拒绝', - icon: renderIcon('mdi:close-circle-outline', { size: 16 }), + default: () => '退款', + // icon: renderIcon('mdi:cash-refund', { size: 16 }), } ), - default: () => h('div', {}, '确认拒绝开票?'), + default: () => h('div', {}, '确认退款?'), + } + ), + // 查看按钮 - 已开票状态显示 + row.status === 'invoiced' && + h( + NButton, + { + size: 'small', + type: 'warning', + style: 'margin-right: 8px;', + onClick: () => handleView(row), + }, + { + default: () => '查看', + // icon: renderIcon('mdi:eye-outline', { size: 16 }), } ), ] @@ -275,27 +277,44 @@ const columns = [ }, ] -// 开票提醒 -async function handleRemind(row) { - try { - await api.remindInvoice({ id: row.id }) - $message.success('提醒发送成功') - } catch (error) { - $message.error('提醒发送失败: ' + error.message) - } -} - // 更新状态 async function handleUpdateStatus(row, status) { try { await api.updateInvoiceStatus({ id: row.id, status }) - $message.success('状态更新成功') + $message.success('开票成功') $table.value?.handleSearch() } catch (error) { - $message.error('状态更新失败: ' + error.message) + $message.error('开票失败: ' + error.message) } } +// 退款处理 +async function handleRefund(row) { + try { + // 如果是pending状态,直接退款并更新状态为refunded + if (row.status === 'pending') { + await api.updateInvoiceStatus({ id: row.id, status: 'refunded' }) + $message.success('退款成功') + } else { + await api.refundInvoice({ id: row.id }) + $message.success('退款成功') + } + $table.value?.handleSearch() + } catch (error) { + $message.error('退款失败: ' + error.message) + } +} + +// 查看详情 +function handleView(row) { + // 这里可以打开详情弹窗或跳转到详情页面 + $message.info(`查看开票记录详情 - ID: ${row.id}`) + // 实际项目中可以实现为: + // modalVisible.value = true + // modalAction.value = 'view' + // modalForm.value = { ...row } +} + const validateForm = { company_name: [ {