feat: 迭代
This commit is contained in:
@@ -1,69 +1,69 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export function loginByPassword(username: string, password: string) {
|
||||
return request.post('/admin/auth/login', { username, password });
|
||||
return request.post('/api/admin/auth/login', { username, password });
|
||||
}
|
||||
|
||||
export function getAdminProfile() {
|
||||
return request.get('/admin/auth/profile');
|
||||
return request.get('/api/admin/auth/profile');
|
||||
}
|
||||
|
||||
export function changeAdminPassword(data: { oldPassword: string; newPassword: string }) {
|
||||
return request.put('/admin/auth/password', data);
|
||||
return request.put('/api/admin/auth/password', data);
|
||||
}
|
||||
|
||||
// 商家管理
|
||||
export function getMerchantList(params: any) {
|
||||
return request.get('/admin/merchants', { params });
|
||||
return request.get('/api/admin/merchants', { params });
|
||||
}
|
||||
|
||||
export function getMerchantDetail(id: number) {
|
||||
return request.get(`/admin/merchants/${id}`);
|
||||
return request.get(`/api/admin/merchants/${id}`);
|
||||
}
|
||||
|
||||
export function approveMerchant(id: number) {
|
||||
return request.put(`/admin/merchants/${id}/approve`);
|
||||
return request.put(`/api/admin/merchants/${id}/approve`);
|
||||
}
|
||||
|
||||
export function rejectMerchant(id: number, reason: string) {
|
||||
return request.put(`/admin/merchants/${id}/reject`, { reason });
|
||||
return request.put(`/api/admin/merchants/${id}/reject`, { reason });
|
||||
}
|
||||
|
||||
export function freezeMerchant(id: number) {
|
||||
return request.put(`/admin/merchants/${id}/freeze`);
|
||||
return request.put(`/api/admin/merchants/${id}/freeze`);
|
||||
}
|
||||
|
||||
export function unfreezeMerchant(id: number) {
|
||||
return request.put(`/admin/merchants/${id}/unfreeze`);
|
||||
return request.put(`/api/admin/merchants/${id}/unfreeze`);
|
||||
}
|
||||
|
||||
// 用户管理
|
||||
export function getUserList(params: any) {
|
||||
return request.get('/admin/users', { params });
|
||||
return request.get('/api/admin/users', { params });
|
||||
}
|
||||
|
||||
export function freezeUser(id: number) {
|
||||
return request.put(`/admin/users/${id}/freeze`);
|
||||
return request.put(`/api/admin/users/${id}/freeze`);
|
||||
}
|
||||
|
||||
export function unfreezeUser(id: number) {
|
||||
return request.put(`/admin/users/${id}/unfreeze`);
|
||||
return request.put(`/api/admin/users/${id}/unfreeze`);
|
||||
}
|
||||
|
||||
// 订单管理
|
||||
export function getOrderList(params: any) {
|
||||
return request.get('/admin/orders', { params });
|
||||
return request.get('/api/admin/orders', { params });
|
||||
}
|
||||
|
||||
export function getOrderDetail(id: number) {
|
||||
return request.get(`/admin/orders/${id}`);
|
||||
return request.get(`/api/admin/orders/${id}`);
|
||||
}
|
||||
|
||||
// 统计数据
|
||||
export function getPlatformStatistics() {
|
||||
return request.get('/admin/finance/reports/overview');
|
||||
return request.get('/api/admin/finance/reports/overview');
|
||||
}
|
||||
|
||||
export function getOrderTrend(params: { startDate: string; endDate: string }) {
|
||||
return request.get('/admin/finance/reports/trend', { params });
|
||||
return request.get('/api/admin/finance/reports/trend', { params });
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export const getServiceFeeConfig = () => request.get('/admin/config/service-fee');
|
||||
export const getServiceFeeConfig = () => request.get('/api/admin/config/service-fee');
|
||||
|
||||
export const updateServiceFeeConfig = (rate: number) => request.put('/admin/config/service-fee', { rate });
|
||||
export const updateServiceFeeConfig = (rate: number) => request.put('/api/admin/config/service-fee', { rate });
|
||||
|
||||
export const getStorageConfig = () => request.get('/admin/config/storage');
|
||||
export const getStorageConfig = () => request.get('/api/admin/config/storage');
|
||||
|
||||
export const updateStorageConfig = (data: Record<string, string>) => request.put('/admin/config/storage', data);
|
||||
export const updateStorageConfig = (data: Record<string, string>) => request.put('/api/admin/config/storage', data);
|
||||
@@ -1,21 +1,21 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export function getCouponList(params: any) {
|
||||
return request({ url: '/admin/coupons', method: 'GET', params });
|
||||
return request({ url: '/api/admin/coupons', method: 'GET', params });
|
||||
}
|
||||
|
||||
export function getCouponDetail(id: number) {
|
||||
return request({ url: `/admin/coupons/${id}`, method: 'GET' });
|
||||
return request({ url: `/api/admin/coupons/${id}`, method: 'GET' });
|
||||
}
|
||||
|
||||
export function createCoupon(data: any) {
|
||||
return request({ url: '/admin/coupons', method: 'POST', data });
|
||||
return request({ url: '/api/admin/coupons', method: 'POST', data });
|
||||
}
|
||||
|
||||
export function updateCoupon(id: number, data: any) {
|
||||
return request({ url: `/admin/coupons/${id}`, method: 'PUT', data });
|
||||
return request({ url: `/api/admin/coupons/${id}`, method: 'PUT', data });
|
||||
}
|
||||
|
||||
export function deleteCoupon(id: number) {
|
||||
return request({ url: `/admin/coupons/${id}`, method: 'DELETE' });
|
||||
return request({ url: `/api/admin/coupons/${id}`, method: 'DELETE' });
|
||||
}
|
||||
|
||||
@@ -2,126 +2,142 @@ import request from '@/utils/request';
|
||||
|
||||
// 账户管理
|
||||
export function getPlatformAccounts(params: any) {
|
||||
return request.get('/admin/finance/accounts/platform', { params });
|
||||
return request.get('/api/admin/finance/accounts/platform', { params });
|
||||
}
|
||||
|
||||
export function getUserAccounts(params: any) {
|
||||
return request.get('/admin/finance/accounts/users', { params });
|
||||
return request.get('/api/admin/finance/accounts/users', { params });
|
||||
}
|
||||
|
||||
export function getMerchantAccounts(params: any) {
|
||||
return request.get('/admin/finance/accounts/merchants', { params });
|
||||
return request.get('/api/admin/finance/accounts/merchants', { params });
|
||||
}
|
||||
|
||||
export function getAccountDetail(type: string, id: number) {
|
||||
return request.get(`/admin/finance/accounts/${type}/${id}`);
|
||||
return request.get(`/api/admin/finance/accounts/${type}/${id}`);
|
||||
}
|
||||
|
||||
export function getAccountsSummary() {
|
||||
return request.get('/admin/finance/accounts/summary');
|
||||
return request.get('/api/admin/finance/accounts/summary');
|
||||
}
|
||||
|
||||
// 交易流水
|
||||
export function getPlatformTransactions(params: any) {
|
||||
return request.get('/admin/finance/transactions/platform', { params });
|
||||
return request.get('/api/admin/finance/transactions/platform', { params });
|
||||
}
|
||||
|
||||
export function getUserTransactions(params: any) {
|
||||
return request.get('/admin/finance/transactions/users', { params });
|
||||
return request.get('/api/admin/finance/transactions/users', { params });
|
||||
}
|
||||
|
||||
export function getMerchantTransactions(params: any) {
|
||||
return request.get('/admin/finance/transactions/merchants', { params });
|
||||
return request.get('/api/admin/finance/transactions/merchants', { params });
|
||||
}
|
||||
|
||||
export function getTransactionDetail(id: number) {
|
||||
return request.get(`/admin/finance/transactions/${id}`);
|
||||
return request.get(`/api/admin/finance/transactions/${id}`);
|
||||
}
|
||||
|
||||
// 提现管理
|
||||
export function getWithdrawals(params: any) {
|
||||
return request.get('/admin/finance/withdrawals', { params });
|
||||
export function getUserWithdrawals(params: any) {
|
||||
return request.get('/api/admin/finance/withdrawals/users', { params });
|
||||
}
|
||||
|
||||
export function getWithdrawalDetail(id: number) {
|
||||
return request.get(`/admin/finance/withdrawals/${id}`);
|
||||
export function getMerchantWithdrawals(params: any) {
|
||||
return request.get('/api/admin/finance/withdrawals/merchants', { params });
|
||||
}
|
||||
|
||||
export function approveWithdrawal(id: number) {
|
||||
return request.put(`/admin/finance/withdrawals/${id}/approve`);
|
||||
export function getPlatformWithdrawals(params: any) {
|
||||
return request.get('/api/admin/finance/withdrawals/platform', { params });
|
||||
}
|
||||
|
||||
export function rejectWithdrawal(id: number, reason: string) {
|
||||
return request.put(`/admin/finance/withdrawals/${id}/reject`, { reason });
|
||||
export function approveUserWithdrawal(id: number) {
|
||||
return request.put(`/api/admin/finance/withdrawals/users/${id}/approve`);
|
||||
}
|
||||
|
||||
export function confirmWithdrawal(id: number, data: { transactionNo: string; paidAt: string }) {
|
||||
return request.put(`/admin/finance/withdrawals/${id}/confirm`, data);
|
||||
export function rejectUserWithdrawal(id: number, reason: string) {
|
||||
return request.put(`/api/admin/finance/withdrawals/users/${id}/reject`, { rejectReason: reason });
|
||||
}
|
||||
|
||||
export function confirmUserWithdrawal(id: number, transactionNo: string) {
|
||||
return request.put(`/api/admin/finance/withdrawals/users/${id}/confirm`, { paymentNo: transactionNo });
|
||||
}
|
||||
|
||||
export function approveMerchantWithdrawal(id: number) {
|
||||
return request.put(`/api/admin/finance/withdrawals/merchants/${id}/approve`);
|
||||
}
|
||||
|
||||
export function rejectMerchantWithdrawal(id: number, reason: string) {
|
||||
return request.put(`/api/admin/finance/withdrawals/merchants/${id}/reject`, { rejectReason: reason });
|
||||
}
|
||||
|
||||
export function confirmMerchantWithdrawal(id: number, transactionNo: string) {
|
||||
return request.put(`/api/admin/finance/withdrawals/merchants/${id}/confirm`, { paymentNo: transactionNo });
|
||||
}
|
||||
|
||||
// 结算管理
|
||||
export function getSettlements(params: any) {
|
||||
return request.get('/admin/finance/settlements', { params });
|
||||
return request.get('/api/admin/finance/settlements', { params });
|
||||
}
|
||||
|
||||
export function getSettlementDetail(id: number) {
|
||||
return request.get(`/admin/finance/settlements/${id}`);
|
||||
return request.get(`/api/admin/finance/settlements/${id}`);
|
||||
}
|
||||
|
||||
export function getSettlementItems(id: number, params: any) {
|
||||
return request.get(`/admin/finance/settlements/${id}/items`, { params });
|
||||
return request.get(`/api/admin/finance/settlements/${id}/items`, { params });
|
||||
}
|
||||
|
||||
export function generateSettlement(merchantId: number, data: { startDate: string; endDate: string }) {
|
||||
return request.post(`/admin/finance/settlements/generate/${merchantId}`, data);
|
||||
return request.post(`/api/admin/finance/settlements/generate/${merchantId}`, data);
|
||||
}
|
||||
|
||||
// 对账管理
|
||||
export function getReconciliations(params: any) {
|
||||
return request.get('/admin/finance/reconciliations', { params });
|
||||
return request.get('/api/admin/finance/reconciliations', { params });
|
||||
}
|
||||
|
||||
export function getReconciliationDetail(id: number) {
|
||||
return request.get(`/admin/finance/reconciliations/${id}`);
|
||||
return request.get(`/api/admin/finance/reconciliations/${id}`);
|
||||
}
|
||||
|
||||
export function triggerReconciliation(date: string) {
|
||||
return request.post('/admin/finance/reconciliations/trigger', { date });
|
||||
return request.post('/api/admin/finance/reconciliations/trigger', { date });
|
||||
}
|
||||
|
||||
export function getTransactionStats(params: any) {
|
||||
return request.get('/admin/finance/reconciliations/stats', { params });
|
||||
return request.get('/api/admin/finance/reconciliations/stats', { params });
|
||||
}
|
||||
|
||||
export function checkBalanceConsistency() {
|
||||
return request.get('/admin/finance/reconciliations/check-balance');
|
||||
return request.get('/api/admin/finance/reconciliations/check-balance');
|
||||
}
|
||||
|
||||
// 财务报表
|
||||
export function getFinancialOverview(params: any) {
|
||||
return request.get('/admin/finance/reports/overview', { params });
|
||||
return request.get('/api/admin/finance/reports/overview', { params });
|
||||
}
|
||||
|
||||
export function getFinancialTrend(params: any) {
|
||||
return request.get('/admin/finance/reports/trend', { params });
|
||||
return request.get('/api/admin/finance/reports/trend', { params });
|
||||
}
|
||||
|
||||
export function getDailyReport(params: any) {
|
||||
return request.get('/admin/finance/reports/daily', { params });
|
||||
return request.get('/api/admin/finance/reports/daily', { params });
|
||||
}
|
||||
|
||||
export function getWeeklyReport(params: any) {
|
||||
return request.get('/admin/finance/reports/weekly', { params });
|
||||
return request.get('/api/admin/finance/reports/weekly', { params });
|
||||
}
|
||||
|
||||
export function getMonthlyReport(params: any) {
|
||||
return request.get('/admin/finance/reports/monthly', { params });
|
||||
return request.get('/api/admin/finance/reports/monthly', { params });
|
||||
}
|
||||
|
||||
export function getMerchantReport(merchantId: number, params: any) {
|
||||
return request.get(`/admin/finance/reports/merchant/${merchantId}`, { params });
|
||||
return request.get(`/api/admin/finance/reports/merchant/${merchantId}`, { params });
|
||||
}
|
||||
|
||||
export function exportReport(type: string, params: any) {
|
||||
return request.get(`/admin/finance/reports/export/${type}`, { params, responseType: 'blob' });
|
||||
return request.get(`/api/admin/finance/reports/export/${type}`, { params, responseType: 'blob' });
|
||||
}
|
||||
|
||||
@@ -2,35 +2,35 @@ import request from '@/utils/request';
|
||||
|
||||
// 邀请数据总览
|
||||
export const getInviteStats = () =>
|
||||
request.get('/admin/activity/invite/stats');
|
||||
request.get('/api/admin/activity/invite/stats');
|
||||
|
||||
// 邀请记录列表
|
||||
export const getInviteRecords = (params?: { page?: number; pageSize?: number }) =>
|
||||
request.get('/admin/activity/invite/records', { params });
|
||||
request.get('/api/admin/activity/invite/records', { params });
|
||||
|
||||
// 返现记录列表
|
||||
export const getCashbackRecords = (params?: { page?: number; pageSize?: number }) =>
|
||||
request.get('/admin/activity/invite/cashbacks', { params });
|
||||
request.get('/api/admin/activity/invite/cashbacks', { params });
|
||||
|
||||
// 邀请提现列表
|
||||
export const getInviteWithdrawals = (params?: { page?: number; pageSize?: number; status?: string }) =>
|
||||
request.get('/admin/activity/invite/withdrawals', { params });
|
||||
request.get('/api/admin/activity/invite/withdrawals', { params });
|
||||
|
||||
// 审核通过提现
|
||||
export const approveInviteWithdrawal = (id: number) =>
|
||||
request.put(`/admin/activity/invite/withdrawals/${id}/approve`);
|
||||
request.put(`/api/admin/activity/invite/withdrawals/${id}/approve`);
|
||||
|
||||
// 审核拒绝提现
|
||||
export const rejectInviteWithdrawal = (id: number, reason: string) =>
|
||||
request.put(`/admin/activity/invite/withdrawals/${id}/reject`, { reason });
|
||||
request.put(`/api/admin/activity/invite/withdrawals/${id}/reject`, { reason });
|
||||
|
||||
// 确认打款
|
||||
export const payInviteWithdrawal = (id: number) =>
|
||||
request.put(`/admin/activity/invite/withdrawals/${id}/pay`);
|
||||
request.put(`/api/admin/activity/invite/withdrawals/${id}/pay`);
|
||||
|
||||
// 获取邀请活动配置
|
||||
export const getInviteConfig = () =>
|
||||
request.get('/admin/activity/invite/config');
|
||||
request.get('/api/admin/activity/invite/config');
|
||||
|
||||
// 更新邀请活动配置
|
||||
export const updateInviteConfig = (data: {
|
||||
@@ -43,4 +43,4 @@ export const updateInviteConfig = (data: {
|
||||
};
|
||||
enabled?: boolean;
|
||||
}) =>
|
||||
request.put('/admin/activity/invite/config', data);
|
||||
request.put('/api/admin/activity/invite/config', data);
|
||||
@@ -1,5 +1,5 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export function getServiceFees(params: any) {
|
||||
return request.get('/admin/orders/service-fees/list', { params });
|
||||
return request.get('/api/admin/orders/service-fees/list', { params });
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export function getReviews(params: any) {
|
||||
return request.get('/admin/reviews', { params });
|
||||
return request.get('/api/admin/reviews', { params });
|
||||
}
|
||||
|
||||
export function approveReview(id: number) {
|
||||
return request.put(`/admin/reviews/${id}/approve`);
|
||||
return request.put(`/api/admin/reviews/${id}/approve`);
|
||||
}
|
||||
|
||||
export function rejectReview(id: number, reason: string) {
|
||||
return request.put(`/admin/reviews/${id}/reject`, { reason });
|
||||
return request.put(`/api/admin/reviews/${id}/reject`, { reason });
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ import request from '@/utils/request';
|
||||
|
||||
// 房源审核管理
|
||||
export function getAdminRoomList(params: any) {
|
||||
return request.get('/admin/rooms', { params });
|
||||
return request.get('/api/admin/rooms', { params });
|
||||
}
|
||||
|
||||
export function approveRoom(id: number) {
|
||||
return request.put(`/admin/rooms/${id}/approve`);
|
||||
return request.put(`/api/admin/rooms/${id}/approve`);
|
||||
}
|
||||
|
||||
export function rejectRoom(id: number, reason: string) {
|
||||
return request.put(`/admin/rooms/${id}/reject`, { reason });
|
||||
return request.put(`/api/admin/rooms/${id}/reject`, { reason });
|
||||
}
|
||||
|
||||
@@ -52,7 +52,8 @@ export function useTableData<T = any>(
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [fetchFn, params]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [params]);
|
||||
|
||||
useEffect(() => {
|
||||
if (autoLoad) {
|
||||
|
||||
@@ -225,11 +225,11 @@ const InviteManage: React.FC = () => {
|
||||
<Form form={form} layout="vertical" style={{ maxWidth: 500 }}>
|
||||
<Form.Item label="首单返现比例" name="firstOrderRate" rules={[{ required: true }]} extra="好友首次下单,邀请人获得的返现比例">
|
||||
<InputNumber min={0.01} max={0.20} step={0.01} addonAfter="%" style={{ width: '100%' }}
|
||||
formatter={v => `${(Number(v) * 100).toFixed(1)}`} parser={v => Number(v?.replace('%', '')) / 100} />
|
||||
formatter={v => `${(Number(v) * 100).toFixed(1)}`} parser={v => Number(v?.replace('%', '')) / 100 as any} />
|
||||
</Form.Item>
|
||||
<Form.Item label="二单返现比例" name="secondOrderRate" rules={[{ required: true }]} extra="好友再次下单,邀请人获得的返现比例">
|
||||
<InputNumber min={0.001} max={0.05} step={0.001} addonAfter="%" style={{ width: '100%' }}
|
||||
formatter={v => `${(Number(v) * 100).toFixed(2)}`} parser={v => Number(v?.replace('%', '')) / 100} />
|
||||
formatter={v => `${(Number(v) * 100).toFixed(2)}`} parser={v => Number(v?.replace('%', '')) / 100 as any} />
|
||||
</Form.Item>
|
||||
<Form.Item label="最多返现订单数" name="maxOrderIndex" rules={[{ required: true }]} extra="好友最多前几单可以获得返现">
|
||||
<InputNumber min={1} max={10} step={1} addonAfter="单" style={{ width: '100%' }} />
|
||||
|
||||
@@ -60,7 +60,7 @@ const SystemSettings: React.FC = () => {
|
||||
precision={4}
|
||||
style={{ width: '100%' }}
|
||||
formatter={(v) => `${(Number(v) * 100).toFixed(2)}%`}
|
||||
parser={(v) => Number(v?.replace('%', '')) / 100}
|
||||
parser={(v) => Number(v?.replace('%', '')) / 100 as any}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
|
||||
@@ -32,7 +32,7 @@ const Accounts: React.FC = () => {
|
||||
fetchAccounts();
|
||||
}, [activeTab]);
|
||||
|
||||
const fetchAccounts = async (params = {}) => {
|
||||
const fetchAccounts = async (params: any = {}) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const values = form.getFieldsValue();
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Card, Table, DatePicker, Space, Statistic, Row, Col, Tag, message } from 'antd';
|
||||
import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { formatMoney, formatDateTime } from '@rent/shared-utils';
|
||||
import { getFinancialOverview, getWeeklyReport } from '@/api/finance';
|
||||
import type { Dayjs } from 'dayjs';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
interface EarningRecord {
|
||||
id: number;
|
||||
date: string;
|
||||
orderCount: number;
|
||||
totalAmount: number;
|
||||
platformCommission: number;
|
||||
withdrawalFee: number;
|
||||
totalIncome: number;
|
||||
totalExpense: number;
|
||||
profit: number;
|
||||
}
|
||||
|
||||
const Earnings: React.FC = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dataSource, setDataSource] = useState<EarningRecord[]>([]);
|
||||
const [dateRange, setDateRange] = useState<[Dayjs | null, Dayjs | null] | null>(null);
|
||||
const [overview, setOverview] = useState({
|
||||
todayIncome: 0,
|
||||
monthIncome: 0,
|
||||
totalIncome: 0,
|
||||
monthProfit: 0,
|
||||
platformCommission: 0,
|
||||
withdrawalFee: 0,
|
||||
pendingSettlement: 0,
|
||||
balance: 0,
|
||||
growthRate: 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
fetchOverview();
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchOverview = async () => {
|
||||
try {
|
||||
const res = await getFinancialOverview({});
|
||||
if (res?.data) {
|
||||
setOverview({
|
||||
todayIncome: res.data?.todayIncome || 0,
|
||||
monthIncome: res.data?.monthIncome || 0,
|
||||
totalIncome: res.data?.totalIncome || 0,
|
||||
monthProfit: res.data?.monthProfit || 0,
|
||||
platformCommission: res.data?.platformCommission || 0,
|
||||
withdrawalFee: res.data?.withdrawalFee || 0,
|
||||
pendingSettlement: res.data?.pendingSettlement || 0,
|
||||
balance: res.data?.balance || 0,
|
||||
growthRate: res.data?.growthRate || 0,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取财务概览失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const params: any = {};
|
||||
|
||||
if (dateRange && dateRange[0] && dateRange[1]) {
|
||||
params.startDate = dateRange[0].format('YYYY-MM-DD');
|
||||
params.endDate = dateRange[1].format('YYYY-MM-DD');
|
||||
}
|
||||
|
||||
// 使用周报表接口获取数据
|
||||
const res = await getWeeklyReport(params);
|
||||
if (res?.data) {
|
||||
// 将单条数据转换为数组格式
|
||||
const data = res.data;
|
||||
if (data) {
|
||||
setDataSource([{
|
||||
id: 1,
|
||||
date: data.startDate,
|
||||
orderCount: data.orderCount || 0,
|
||||
totalAmount: data.orderAmount || 0,
|
||||
platformCommission: data.serviceFee || 0,
|
||||
withdrawalFee: 0,
|
||||
totalIncome: data.totalIncome || 0,
|
||||
totalExpense: data.totalExpense || 0,
|
||||
profit: data.netAmount || 0,
|
||||
}]);
|
||||
} else {
|
||||
setDataSource([]);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('获取数据失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDateChange = (dates: [Dayjs | null, Dayjs | null] | null) => {
|
||||
setDateRange(dates);
|
||||
if (dates) {
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const columns: ColumnsType<EarningRecord> = [
|
||||
{
|
||||
title: '日期',
|
||||
dataIndex: 'date',
|
||||
key: 'date',
|
||||
render: (date: string) => formatDateTime(date).split(' ')[0],
|
||||
},
|
||||
{
|
||||
title: '订单数',
|
||||
dataIndex: 'orderCount',
|
||||
key: 'orderCount',
|
||||
},
|
||||
{
|
||||
title: '订单总额',
|
||||
dataIndex: 'totalAmount',
|
||||
key: 'totalAmount',
|
||||
render: (amount: number) => `¥${formatMoney(amount)}`,
|
||||
},
|
||||
{
|
||||
title: '平台佣金',
|
||||
dataIndex: 'platformCommission',
|
||||
key: 'platformCommission',
|
||||
render: (commission: number) => (
|
||||
<span style={{ color: '#52c41a', fontWeight: 600 }}>
|
||||
¥{formatMoney(commission)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '提现手续费',
|
||||
dataIndex: 'withdrawalFee',
|
||||
key: 'withdrawalFee',
|
||||
render: (fee: number) => (
|
||||
<span style={{ color: '#52c41a' }}>
|
||||
¥{formatMoney(fee)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '总收入',
|
||||
dataIndex: 'totalIncome',
|
||||
key: 'totalIncome',
|
||||
render: (income: number) => (
|
||||
<span style={{ color: '#52c41a', fontWeight: 600 }}>
|
||||
¥{formatMoney(income)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '总支出',
|
||||
dataIndex: 'totalExpense',
|
||||
key: 'totalExpense',
|
||||
render: (expense: number) => (
|
||||
<span style={{ color: '#ff4d4f' }}>
|
||||
¥{formatMoney(expense)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '净利润',
|
||||
dataIndex: 'profit',
|
||||
key: 'profit',
|
||||
render: (profit: number) => (
|
||||
<span style={{ color: profit >= 0 ? '#52c41a' : '#ff4d4f', fontWeight: 700 }}>
|
||||
{profit >= 0 ? '+' : ''}¥{formatMoney(profit)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card style={{ marginBottom: 16 }} title="平台财务概览">
|
||||
<Row gutter={16}>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="今日收益"
|
||||
value={overview.todayIncome}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
valueStyle={{ color: '#52c41a' }}
|
||||
suffix={
|
||||
<span style={{ fontSize: 14, color: '#999' }}>
|
||||
{overview.growthRate >= 0 ? (
|
||||
<><ArrowUpOutlined style={{ color: '#52c41a' }} /> {overview.growthRate.toFixed(1)}%</>
|
||||
) : (
|
||||
<><ArrowDownOutlined style={{ color: '#ff4d4f' }} /> {Math.abs(overview.growthRate).toFixed(1)}%</>
|
||||
)}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="本月收益"
|
||||
value={overview.monthIncome}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
valueStyle={{ color: '#52c41a' }}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="累计收益"
|
||||
value={overview.totalIncome}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="本月利润"
|
||||
value={overview.monthProfit}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
valueStyle={{ color: '#1890ff' }}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={16} style={{ marginTop: 24 }}>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="平台佣金收入"
|
||||
value={overview.platformCommission}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="提现手续费收入"
|
||||
value={overview.withdrawalFee}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="待结算金额"
|
||||
value={overview.pendingSettlement}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
valueStyle={{ color: '#faad14' }}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="资金池余额"
|
||||
value={overview.balance}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
valueStyle={{ color: '#1890ff' }}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
title="收益明细"
|
||||
extra={
|
||||
<Space>
|
||||
<RangePicker value={dateRange} onChange={handleDateChange} />
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
pagination={false}
|
||||
summary={(pageData) => {
|
||||
if (pageData.length === 0) return null;
|
||||
|
||||
const totalOrders = pageData.reduce((sum, record) => sum + record.orderCount, 0);
|
||||
const totalAmount = pageData.reduce((sum, record) => sum + record.totalAmount, 0);
|
||||
const totalCommission = pageData.reduce((sum, record) => sum + record.platformCommission, 0);
|
||||
const totalFee = pageData.reduce((sum, record) => sum + record.withdrawalFee, 0);
|
||||
const totalIncome = pageData.reduce((sum, record) => sum + record.totalIncome, 0);
|
||||
const totalExpense = pageData.reduce((sum, record) => sum + record.totalExpense, 0);
|
||||
const totalProfit = pageData.reduce((sum, record) => sum + record.profit, 0);
|
||||
|
||||
return (
|
||||
<Table.Summary fixed>
|
||||
<Table.Summary.Row style={{ fontWeight: 600 }}>
|
||||
<Table.Summary.Cell index={0}>合计</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={1}>{totalOrders}</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={2}>¥{formatMoney(totalAmount)}</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={3}>
|
||||
<span style={{ color: '#52c41a' }}>¥{formatMoney(totalCommission)}</span>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={4}>
|
||||
<span style={{ color: '#52c41a' }}>¥{formatMoney(totalFee)}</span>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={5}>
|
||||
<span style={{ color: '#52c41a' }}>¥{formatMoney(totalIncome)}</span>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={6}>
|
||||
<span style={{ color: '#ff4d4f' }}>¥{formatMoney(totalExpense)}</span>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={7}>
|
||||
<span style={{ color: totalProfit >= 0 ? '#52c41a' : '#ff4d4f' }}>
|
||||
{totalProfit >= 0 ? '+' : ''}¥{formatMoney(totalProfit)}
|
||||
</span>
|
||||
</Table.Summary.Cell>
|
||||
</Table.Summary.Row>
|
||||
</Table.Summary>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Earnings;
|
||||
@@ -0,0 +1,272 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Card, Table, DatePicker, Space, Tag, Button, Statistic, Row, Col, message } from 'antd';
|
||||
import { DownloadOutlined } from '@ant-design/icons';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { formatMoney, formatDateTime } from '@rent/shared-utils';
|
||||
import { getFinancialOverview, getMerchantTransactions } from '@/api/finance';
|
||||
import type { Dayjs } from 'dayjs';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
interface ServiceFeeRecord {
|
||||
id: number;
|
||||
orderId: number;
|
||||
orderNo: string;
|
||||
merchantName: string;
|
||||
userName: string;
|
||||
orderAmount: number;
|
||||
commissionRate: number;
|
||||
commissionAmount: number;
|
||||
status: string;
|
||||
settledAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
const ServiceFees: React.FC = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dataSource, setDataSource] = useState<ServiceFeeRecord[]>([]);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
});
|
||||
const [dateRange, setDateRange] = useState<[Dayjs | null, Dayjs | null] | null>(null);
|
||||
const [statistics, setStatistics] = useState({
|
||||
todayCommission: 0,
|
||||
monthCommission: 0,
|
||||
totalCommission: 0,
|
||||
pendingCommission: 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
fetchStatistics();
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchStatistics = async () => {
|
||||
try {
|
||||
const res = await getFinancialOverview({});
|
||||
if (res?.data) {
|
||||
setStatistics({
|
||||
todayCommission: res.data?.todayCommission || 0,
|
||||
monthCommission: res.data?.monthCommission || 0,
|
||||
totalCommission: res.data?.totalCommission || 0,
|
||||
pendingCommission: res.data?.pendingCommission || 0,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取统计数据失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchData = async (page = 1, pageSize = 20) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const params: any = {
|
||||
page,
|
||||
pageSize,
|
||||
};
|
||||
|
||||
if (dateRange && dateRange[0] && dateRange[1]) {
|
||||
params.startDate = dateRange[0].format('YYYY-MM-DD');
|
||||
params.endDate = dateRange[1].format('YYYY-MM-DD');
|
||||
}
|
||||
|
||||
const res = await getMerchantTransactions(params);
|
||||
if (res?.data) {
|
||||
setDataSource(res.data?.list || []);
|
||||
setPagination({
|
||||
current: page,
|
||||
pageSize,
|
||||
total: res.data?.total || 0,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('获取数据失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTableChange = (newPagination: any) => {
|
||||
fetchData(newPagination.current, newPagination.pageSize);
|
||||
};
|
||||
|
||||
const handleDateChange = (dates: [Dayjs | null, Dayjs | null] | null) => {
|
||||
setDateRange(dates);
|
||||
};
|
||||
|
||||
const handleSearch = () => {
|
||||
fetchData(1, pagination.pageSize);
|
||||
};
|
||||
|
||||
const handleExport = () => {
|
||||
message.info('导出功能开发中');
|
||||
};
|
||||
|
||||
const columns: ColumnsType<ServiceFeeRecord> = [
|
||||
{
|
||||
title: '订单号',
|
||||
dataIndex: 'orderNo',
|
||||
key: 'orderNo',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '商家名称',
|
||||
dataIndex: 'merchantName',
|
||||
key: 'merchantName',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '用户',
|
||||
dataIndex: 'userName',
|
||||
key: 'userName',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '订单金额',
|
||||
dataIndex: 'orderAmount',
|
||||
key: 'orderAmount',
|
||||
width: 120,
|
||||
render: (amount: number) => `¥${formatMoney(amount)}`,
|
||||
},
|
||||
{
|
||||
title: '佣金比例',
|
||||
dataIndex: 'commissionRate',
|
||||
key: 'commissionRate',
|
||||
width: 100,
|
||||
render: (rate: number) => `${(rate * 100).toFixed(1)}%`,
|
||||
},
|
||||
{
|
||||
title: '佣金金额',
|
||||
dataIndex: 'commissionAmount',
|
||||
key: 'commissionAmount',
|
||||
width: 120,
|
||||
render: (amount: number) => (
|
||||
<span style={{ color: '#52c41a', fontWeight: 600 }}>
|
||||
¥{formatMoney(amount)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
width: 100,
|
||||
render: (status: string) => {
|
||||
const statusMap: Record<string, { text: string; color: string }> = {
|
||||
pending: { text: '待结算', color: 'orange' },
|
||||
settled: { text: '已结算', color: 'green' },
|
||||
frozen: { text: '已冻结', color: 'red' },
|
||||
};
|
||||
const config = statusMap[status] || { text: status, color: 'default' };
|
||||
return <Tag color={config.color}>{config.text}</Tag>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '结算时间',
|
||||
dataIndex: 'settledAt',
|
||||
key: 'settledAt',
|
||||
width: 160,
|
||||
render: (time: string) => time ? formatDateTime(time) : '-',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createdAt',
|
||||
key: 'createdAt',
|
||||
width: 160,
|
||||
render: (time: string) => formatDateTime(time),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card style={{ marginBottom: 16 }} title="佣金统计">
|
||||
<Row gutter={16}>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="今日佣金"
|
||||
value={statistics.todayCommission}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
valueStyle={{ color: '#52c41a' }}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="本月佣金"
|
||||
value={statistics.monthCommission}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
valueStyle={{ color: '#52c41a' }}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="累计佣金"
|
||||
value={statistics.totalCommission}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="待结算佣金"
|
||||
value={statistics.pendingCommission}
|
||||
prefix="¥"
|
||||
precision={2}
|
||||
valueStyle={{ color: '#faad14' }}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
title="佣金明细"
|
||||
extra={
|
||||
<Space>
|
||||
<RangePicker value={dateRange} onChange={handleDateChange} />
|
||||
<Button onClick={handleSearch}>查询</Button>
|
||||
<Button icon={<DownloadOutlined />} onClick={handleExport}>导出</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
scroll={{ x: 1400 }}
|
||||
pagination={{
|
||||
...pagination,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
}}
|
||||
onChange={handleTableChange}
|
||||
summary={(pageData) => {
|
||||
if (pageData.length === 0) return null;
|
||||
|
||||
const totalOrderAmount = pageData.reduce((sum, record) => sum + record.orderAmount, 0);
|
||||
const totalCommission = pageData.reduce((sum, record) => sum + record.commissionAmount, 0);
|
||||
|
||||
return (
|
||||
<Table.Summary fixed>
|
||||
<Table.Summary.Row style={{ fontWeight: 600 }}>
|
||||
<Table.Summary.Cell index={0} colSpan={3}>合计</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={3}>¥{formatMoney(totalOrderAmount)}</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={4}>-</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={5}>
|
||||
<span style={{ color: '#52c41a' }}>¥{formatMoney(totalCommission)}</span>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={6} colSpan={3}>-</Table.Summary.Cell>
|
||||
</Table.Summary.Row>
|
||||
</Table.Summary>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServiceFees;
|
||||
@@ -1,7 +1,17 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Card, Table, Tag, Button, Space, Modal, Form, Input, message, Descriptions, DatePicker } from 'antd';
|
||||
import { Card, Table, Tag, Button, Space, Modal, Form, Input, message, Descriptions, DatePicker, Tabs } from 'antd';
|
||||
import { CheckOutlined, CloseOutlined, EyeOutlined } from '@ant-design/icons';
|
||||
import { getWithdrawals, getWithdrawalDetail, approveWithdrawal, rejectWithdrawal, confirmWithdrawal } from '@/api/finance';
|
||||
import {
|
||||
getUserWithdrawals,
|
||||
getMerchantWithdrawals,
|
||||
getPlatformWithdrawals,
|
||||
approveUserWithdrawal,
|
||||
rejectUserWithdrawal,
|
||||
confirmUserWithdrawal,
|
||||
approveMerchantWithdrawal,
|
||||
rejectMerchantWithdrawal,
|
||||
confirmMerchantWithdrawal
|
||||
} from '@/api/finance';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@@ -30,6 +40,7 @@ const Withdrawals: React.FC = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [rejectForm] = Form.useForm();
|
||||
const [confirmForm] = Form.useForm();
|
||||
const [withdrawalType, setWithdrawalType] = useState<'user' | 'merchant' | 'platform'>('user');
|
||||
const [withdrawals, setWithdrawals] = useState<Withdrawal[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [pagination, setPagination] = useState({ current: 1, pageSize: 20, total: 0 });
|
||||
@@ -42,9 +53,9 @@ const Withdrawals: React.FC = () => {
|
||||
|
||||
useEffect(() => {
|
||||
fetchWithdrawals();
|
||||
}, []);
|
||||
}, [withdrawalType]);
|
||||
|
||||
const fetchWithdrawals = async (params = {}) => {
|
||||
const fetchWithdrawals = async (params: any = {}) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const queryParams = {
|
||||
@@ -53,9 +64,17 @@ const Withdrawals: React.FC = () => {
|
||||
pageSize: params.pageSize || pagination.pageSize,
|
||||
};
|
||||
|
||||
const res = await getWithdrawals(queryParams);
|
||||
setWithdrawals(res.data.items);
|
||||
setPagination({ ...pagination, total: res.data.total, ...params });
|
||||
let res;
|
||||
if (withdrawalType === 'user') {
|
||||
res = await getUserWithdrawals(queryParams);
|
||||
} else if (withdrawalType === 'merchant') {
|
||||
res = await getMerchantWithdrawals(queryParams);
|
||||
} else {
|
||||
res = await getPlatformWithdrawals(queryParams);
|
||||
}
|
||||
|
||||
setWithdrawals(res.data.items || []);
|
||||
setPagination({ ...pagination, total: res.data.total || 0, ...params });
|
||||
} catch (error) {
|
||||
message.error('获取提现记录失败');
|
||||
} finally {
|
||||
@@ -65,9 +84,11 @@ const Withdrawals: React.FC = () => {
|
||||
|
||||
const handleViewDetail = async (id: number) => {
|
||||
try {
|
||||
const res = await getWithdrawalDetail(id);
|
||||
setCurrentDetail(res.data);
|
||||
setDetailVisible(true);
|
||||
// TODO: 实现提现详情接口
|
||||
message.info('提现详情功能待实现');
|
||||
// const res = await getWithdrawalDetail(id);
|
||||
// setCurrentDetail(res.data);
|
||||
// setDetailVisible(true);
|
||||
} catch (error) {
|
||||
message.error('获取提现详情失败');
|
||||
}
|
||||
@@ -79,7 +100,11 @@ const Withdrawals: React.FC = () => {
|
||||
content: '确定要通过这笔提现申请吗?',
|
||||
onOk: async () => {
|
||||
try {
|
||||
await approveWithdrawal(id);
|
||||
if (withdrawalType === 'user') {
|
||||
await approveUserWithdrawal(id);
|
||||
} else if (withdrawalType === 'merchant') {
|
||||
await approveMerchantWithdrawal(id);
|
||||
}
|
||||
message.success('审核通过');
|
||||
fetchWithdrawals();
|
||||
} catch (error: any) {
|
||||
@@ -93,7 +118,11 @@ const Withdrawals: React.FC = () => {
|
||||
if (!currentId) return;
|
||||
setSubmitting(true);
|
||||
try {
|
||||
await rejectWithdrawal(currentId, values.reason);
|
||||
if (withdrawalType === 'user') {
|
||||
await rejectUserWithdrawal(currentId, values.reason);
|
||||
} else if (withdrawalType === 'merchant') {
|
||||
await rejectMerchantWithdrawal(currentId, values.reason);
|
||||
}
|
||||
message.success('已拒绝');
|
||||
setRejectVisible(false);
|
||||
rejectForm.resetFields();
|
||||
@@ -109,10 +138,11 @@ const Withdrawals: React.FC = () => {
|
||||
if (!currentId) return;
|
||||
setSubmitting(true);
|
||||
try {
|
||||
await confirmWithdrawal(currentId, {
|
||||
transactionNo: values.transactionNo,
|
||||
paidAt: values.paidAt.format('YYYY-MM-DD HH:mm:ss'),
|
||||
});
|
||||
if (withdrawalType === 'user') {
|
||||
await confirmUserWithdrawal(currentId, values.transactionNo);
|
||||
} else if (withdrawalType === 'merchant') {
|
||||
await confirmMerchantWithdrawal(currentId, values.transactionNo);
|
||||
}
|
||||
message.success('打款确认成功');
|
||||
setConfirmVisible(false);
|
||||
confirmForm.resetFields();
|
||||
@@ -131,17 +161,6 @@ const Withdrawals: React.FC = () => {
|
||||
key: 'id',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
width: 100,
|
||||
render: (type: string) => (
|
||||
<Tag color={type === 'user' ? 'blue' : 'orange'}>
|
||||
{type === 'user' ? '用户' : '商家'}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '申请人',
|
||||
key: 'applicant',
|
||||
@@ -268,12 +287,25 @@ const Withdrawals: React.FC = () => {
|
||||
<h2 style={{ marginBottom: 24 }}>提现审核</h2>
|
||||
|
||||
<Card>
|
||||
<Tabs
|
||||
activeKey={withdrawalType}
|
||||
onChange={(key) => {
|
||||
setWithdrawalType(key as 'user' | 'merchant' | 'platform');
|
||||
setPagination({ current: 1, pageSize: 20, total: 0 });
|
||||
}}
|
||||
items={[
|
||||
{ key: 'user', label: '用户提现' },
|
||||
{ key: 'merchant', label: '商家提现' },
|
||||
{ key: 'platform', label: '平台提现' },
|
||||
]}
|
||||
style={{ marginBottom: 16 }}
|
||||
/>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={withdrawals}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
scroll={{ x: 1400 }}
|
||||
scroll={{ x: 1300 }}
|
||||
pagination={{
|
||||
...pagination,
|
||||
showSizeChanger: true,
|
||||
@@ -294,11 +326,6 @@ const Withdrawals: React.FC = () => {
|
||||
{currentDetail && (
|
||||
<Descriptions column={1} bordered>
|
||||
<Descriptions.Item label="提现ID">{currentDetail.id}</Descriptions.Item>
|
||||
<Descriptions.Item label="类型">
|
||||
<Tag color={currentDetail.type === 'user' ? 'blue' : 'orange'}>
|
||||
{currentDetail.type === 'user' ? '用户' : '商家'}
|
||||
</Tag>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="申请人">
|
||||
{currentDetail.userName || currentDetail.merchantName} (ID: {currentDetail.userId || currentDetail.merchantId})
|
||||
</Descriptions.Item>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: '/api',
|
||||
baseURL: '',
|
||||
timeout: 15000,
|
||||
});
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/admin.ts","./src/api/config.ts","./src/api/coupon.ts","./src/api/finance.ts","./src/api/invite.ts","./src/api/order.ts","./src/api/review.ts","./src/api/room.ts","./src/components/settlementstatustag.tsx","./src/components/transactionamount.tsx","./src/components/withdrawalstatustag.tsx","./src/hooks/useapproval.ts","./src/hooks/usemodal.ts","./src/hooks/usetabledata.ts","./src/layouts/mainlayout.tsx","./src/pages/dashboard.tsx","./src/pages/invitemanage.tsx","./src/pages/login.tsx","./src/pages/merchantdetail.tsx","./src/pages/merchantlist.tsx","./src/pages/orderdetail.tsx","./src/pages/orderlist.tsx","./src/pages/orderstatistics.tsx","./src/pages/promotion.tsx","./src/pages/reviewmanage.tsx","./src/pages/roomaudit.tsx","./src/pages/storagesettings.tsx","./src/pages/systemsettings.tsx","./src/pages/userlist.tsx","./src/pages/coupon/couponform.tsx","./src/pages/coupon/couponlist.tsx","./src/pages/finance/accounts.tsx","./src/pages/finance/dashboard.tsx","./src/pages/finance/settlements.tsx","./src/pages/finance/withdrawals.tsx","./src/store/auth.ts","./src/utils/request.ts"],"errors":true,"version":"5.9.3"}
|
||||
{"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/admin.ts","./src/api/config.ts","./src/api/coupon.ts","./src/api/finance.ts","./src/api/invite.ts","./src/api/order.ts","./src/api/review.ts","./src/api/room.ts","./src/components/settlementstatustag.tsx","./src/components/transactionamount.tsx","./src/components/withdrawalstatustag.tsx","./src/hooks/useapproval.ts","./src/hooks/usemodal.ts","./src/hooks/usetabledata.ts","./src/layouts/mainlayout.tsx","./src/pages/dashboard.tsx","./src/pages/invitemanage.tsx","./src/pages/login.tsx","./src/pages/merchantdetail.tsx","./src/pages/merchantlist.tsx","./src/pages/orderdetail.tsx","./src/pages/orderlist.tsx","./src/pages/orderstatistics.tsx","./src/pages/promotion.tsx","./src/pages/reviewmanage.tsx","./src/pages/roomaudit.tsx","./src/pages/storagesettings.tsx","./src/pages/systemsettings.tsx","./src/pages/userlist.tsx","./src/pages/coupon/couponform.tsx","./src/pages/coupon/couponlist.tsx","./src/pages/finance/accounts.tsx","./src/pages/finance/dashboard.tsx","./src/pages/finance/earnings.tsx","./src/pages/finance/servicefees.tsx","./src/pages/finance/settlements.tsx","./src/pages/finance/withdrawals.tsx","./src/store/auth.ts","./src/utils/request.ts"],"version":"5.9.3"}
|
||||
Reference in New Issue
Block a user