diff --git a/src/app/router/index.ts b/src/app/router/index.ts index c27a1d5c..da61bb89 100644 --- a/src/app/router/index.ts +++ b/src/app/router/index.ts @@ -24,6 +24,7 @@ import { truckingRoutes } from '@/modules/trucking/routes' import { feeItemRoutes } from '@/modules/fee-items/routes' import { containerLoadingRoutes } from '@/modules/container-loading/routes' import { loadingListRoutes } from '@/modules/loading-lists/routes' +import { financeRoutes } from '@/modules/finance/routes' const router = createRouter({ history: createWebHistory(), @@ -51,6 +52,7 @@ const router = createRouter({ ...truckingRoutes, ...containerLoadingRoutes, ...loadingListRoutes, + ...financeRoutes, ...customerRoutes, ...warehouseRoutes, ...unifiedOrderRoutes, diff --git a/src/core/navigation/adminNavigation.ts b/src/core/navigation/adminNavigation.ts index 29b828fd..9d9568d9 100644 --- a/src/core/navigation/adminNavigation.ts +++ b/src/core/navigation/adminNavigation.ts @@ -133,14 +133,11 @@ export const adminNavigation: AdminNavigationNode[] = [ key: 'finance', title: '财务管理', icon: CircleDollarSign, - hidden: true, children: [ - { key: 'customer-arap', title: '客户应收应付', icon: Database, path: '/prototype/finance/customer-arap' }, - { key: 'customer-recon-stmt', title: '客户对账单', icon: FileCheck2, path: '/prototype/finance/customer-reconciliation' }, - { key: 'settlement-ar', title: '结算单应收', icon: FileCheck2, path: '/prototype/finance/settlement-ar' }, - { key: 'settlement-ap', title: '结算单应付', icon: FileCheck2, path: '/prototype/finance/settlement-ap' }, - { key: 'finance-cost', title: '费用分析', icon: Database, path: '/prototype/finance/cost-analysis' }, - { key: 'profit', title: '利润表', icon: Database, path: '/prototype/finance/profit-report' }, + { key: 'finance-bills', title: '客户账单', icon: FileCheck2, path: '/finance/bills', permission: 'platform:finance:bill:view' }, + { key: 'finance-receipts', title: '收款登记', icon: CircleDollarSign, path: '/finance/receipts', permission: 'platform:finance:receipt:view' }, + { key: 'finance-costs', title: '成本录入', icon: Database, path: '/finance/costs', permission: 'platform:finance:cost:view' }, + { key: 'finance-reports', title: '财务统计', icon: BarChart3, path: '/finance/reports', permission: 'platform:finance:report:view' }, ], }, { diff --git a/src/modules/finance/api/finance.ts b/src/modules/finance/api/finance.ts new file mode 100644 index 00000000..2e81e5f6 --- /dev/null +++ b/src/modules/finance/api/finance.ts @@ -0,0 +1,46 @@ +import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http' +import type { FinanceBillResource, FinanceCostResource, FinanceReceiptResource, FinanceReportResource } from '../types' + +const basePath = '/platform/v1/finance' +interface PageResult { records: T[]; total: number; page: number; size: number } + +export async function listFinanceBills(params: Record) { + const response = await http.get>, ApiEnvelope>>(`${basePath}/bills`, { params: { ...params, currency: 'CNY' } }) + return unwrapApiResponse(response) +} + +export async function createFinanceBill(payload: Record) { + const response = await http.post, ApiEnvelope>(`${basePath}/bills`, { ...payload, currency: 'CNY' }) + return unwrapApiResponse(response) +} + +export async function listFinanceReceipts(params: Record) { + const response = await http.get>, ApiEnvelope>>(`${basePath}/receipts`, { params: { ...params, currency: 'CNY' } }) + return unwrapApiResponse(response) +} + +export async function createFinanceReceipt(payload: Record, voucher?: File) { + const body = new FormData() + body.append('payload', JSON.stringify({ ...payload, currency: 'CNY' })) + if (voucher) body.append('file', voucher) + const response = await http.post, ApiEnvelope>(`${basePath}/receipts`, body) + return unwrapApiResponse(response) +} + +export async function listFinanceCosts(params: Record) { + const response = await http.get>, ApiEnvelope>>(`${basePath}/costs`, { params: { ...params, currency: 'CNY' } }) + return unwrapApiResponse(response) +} + +export async function createFinanceCost(payload: Record, voucher?: File) { + const body = new FormData() + body.append('payload', JSON.stringify({ ...payload, currency: 'CNY' })) + if (voucher) body.append('file', voucher) + const response = await http.post, ApiEnvelope>(`${basePath}/costs`, body) + return unwrapApiResponse(response) +} + +export async function listFinanceReports(params: Record) { + const response = await http.get, ApiEnvelope>(`${basePath}/reports`, { params: { ...params, currency: 'CNY' } }) + return unwrapApiResponse(response) +} diff --git a/src/modules/finance/index.ts b/src/modules/finance/index.ts new file mode 100644 index 00000000..7eb44320 --- /dev/null +++ b/src/modules/finance/index.ts @@ -0,0 +1 @@ +export { financeRoutes } from './routes' diff --git a/src/modules/finance/pages/FinanceBillsView.vue b/src/modules/finance/pages/FinanceBillsView.vue new file mode 100644 index 00000000..88f42fb0 --- /dev/null +++ b/src/modules/finance/pages/FinanceBillsView.vue @@ -0,0 +1,2 @@ + + diff --git a/src/modules/finance/pages/FinanceCostsView.vue b/src/modules/finance/pages/FinanceCostsView.vue new file mode 100644 index 00000000..2f38b0cd --- /dev/null +++ b/src/modules/finance/pages/FinanceCostsView.vue @@ -0,0 +1,2 @@ + + diff --git a/src/modules/finance/pages/FinanceManualPage.vue b/src/modules/finance/pages/FinanceManualPage.vue new file mode 100644 index 00000000..fba70d2c --- /dev/null +++ b/src/modules/finance/pages/FinanceManualPage.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/src/modules/finance/pages/FinanceReceiptsView.vue b/src/modules/finance/pages/FinanceReceiptsView.vue new file mode 100644 index 00000000..c9cac3f4 --- /dev/null +++ b/src/modules/finance/pages/FinanceReceiptsView.vue @@ -0,0 +1,2 @@ + + diff --git a/src/modules/finance/pages/FinanceReportsView.vue b/src/modules/finance/pages/FinanceReportsView.vue new file mode 100644 index 00000000..af61cb23 --- /dev/null +++ b/src/modules/finance/pages/FinanceReportsView.vue @@ -0,0 +1,2 @@ + + diff --git a/src/modules/finance/routes.ts b/src/modules/finance/routes.ts new file mode 100644 index 00000000..89427e2a --- /dev/null +++ b/src/modules/finance/routes.ts @@ -0,0 +1,8 @@ +import type { RouteRecordRaw } from 'vue-router' + +export const financeRoutes = [ + { path: 'finance/bills', name: 'finance-bills', component: () => import('./pages/FinanceBillsView.vue'), meta: { title: '客户账单', description: '人工维护 CNY 客户账单并在出账后冻结', permission: 'platform:finance:bill:view' } }, + { path: 'finance/receipts', name: 'finance-receipts', component: () => import('./pages/FinanceReceiptsView.vue'), meta: { title: '收款登记', description: '人工登记收款并上传凭证图片', permission: 'platform:finance:receipt:view' } }, + { path: 'finance/costs', name: 'finance-costs', component: () => import('./pages/FinanceCostsView.vue'), meta: { title: '成本录入', description: '人工登记单票成本和整柜公共成本', permission: 'platform:finance:cost:view' } }, + { path: 'finance/reports', name: 'finance-reports', component: () => import('./pages/FinanceReportsView.vue'), meta: { title: '财务统计', description: '按账单统计 CNY 收入、成本和利润', permission: 'platform:finance:report:view' } }, +] satisfies RouteRecordRaw[] diff --git a/src/modules/finance/types.ts b/src/modules/finance/types.ts new file mode 100644 index 00000000..f71c0fee --- /dev/null +++ b/src/modules/finance/types.ts @@ -0,0 +1,48 @@ +export type FinanceBillStatus = 'DRAFT' | 'ISSUED' | 'PARTIALLY_PAID' | 'PAID' | 'VOID' +export type FinanceCostType = 'WAYBILL' | 'CONTAINER' + +export interface FinanceBillResource { + id: string + billNo: string + customerId: string + customerName: string + billDate: string + dueDate: string + currency: 'CNY' + totalAmount: number + paidAmount: number + outstandingAmount: number + status: FinanceBillStatus +} + +export interface FinanceReceiptResource { + id: string + customerId: string + customerName: string + receivedAt: string + amount: number + currency: 'CNY' + paymentMethod: string + voucherFileName: string | null + allocationCount: number +} + +export interface FinanceCostResource { + id: string + costType: FinanceCostType + referenceNo: string + feeName: string + supplierName: string | null + amount: number + currency: 'CNY' + voucherFileName: string | null + createdAt: string +} + +export interface FinanceReportResource { + customerName: string + billedAmount: number + receivedAmount: number + costAmount: number + profitAmount: number +}