fix(api): 替换所有接口请求的域名为 guilixu-api.websoft.top
- 将获取 STS Token 的接口地址由 paopao-api 改为 guilixu-api - 更新图片上传接口地址为新的 guilixu-api 域名 - 修改用户推广页面中邀请码链接和二维码接口的域名 - 更改注册页微信登录接口请求的域名为 guilixu-api
This commit is contained in:
259
src/pages/rebate/records/index.tsx
Normal file
259
src/pages/rebate/records/index.tsx
Normal file
@@ -0,0 +1,259 @@
|
||||
import { View, Text, ScrollView } from '@tarojs/components';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useDidShow } from '@tarojs/taro';
|
||||
import Taro from '@tarojs/taro';
|
||||
import NavBar from '@/components/NavBar';
|
||||
import LoadMore from '@/components/common/LoadMore';
|
||||
import EmptyState from '@/components/common/EmptyState';
|
||||
import { pageShopDealerCapital } from '@/api/shop/shopDealerCapital';
|
||||
import type { ShopDealerCapital, ShopDealerCapitalParam, FlowTypeEnum } from '@/api/shop/shopDealerCapital/model';
|
||||
import type { PageResult } from '@/api';
|
||||
|
||||
// 资金流动类型映射
|
||||
const flowTypeMap = {
|
||||
10: { label: '佣金收入', type: 'order' as const, color: 'text-green-500' },
|
||||
20: { label: '提现支出', type: 'order' as const, color: 'text-red-500' },
|
||||
30: { label: '转账支出', type: 'order' as const, color: 'text-orange-500' },
|
||||
40: { label: '转账收入', type: 'order' as const, color: 'text-green-500' },
|
||||
50: { label: '佣金解冻', type: 'order' as const, color: 'text-blue-500' },
|
||||
60: { label: '配送奖励', type: 'order' as const, color: 'text-purple-500' },
|
||||
};
|
||||
|
||||
// 返利记录类型映射
|
||||
const rebateTypeMap = {
|
||||
register: { label: '注册奖励', bgColor: 'bg-blue-100', textColor: 'text-blue-600' },
|
||||
order: { label: '订单佣金', bgColor: 'bg-green-100', textColor: 'text-green-600' },
|
||||
};
|
||||
|
||||
export default function RebateRecordsPage() {
|
||||
const [records, setRecords] = useState<ShopDealerCapital[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [loadingMore, setLoadingMore] = useState(false);
|
||||
const [hasMore, setHasMore] = useState(true);
|
||||
const [page, setPage] = useState(1);
|
||||
const [totalSettled, setTotalSettled] = useState(0);
|
||||
const [totalPending, setTotalPending] = useState(0);
|
||||
const [activeTab, setActiveTab] = useState<'all' | 'settled' | 'pending'>('all');
|
||||
|
||||
// 过滤后的记录
|
||||
const filteredRecords = records.filter(record => {
|
||||
// 佣金收入和解冻是已结算,提现支出是已结算,其他待定
|
||||
const isSettled = [10, 20, 30, 40, 50, 60].includes(record.flowType || 0);
|
||||
if (activeTab === 'all') return true;
|
||||
if (activeTab === 'settled') return isSettled;
|
||||
if (activeTab === 'pending') return !isSettled;
|
||||
return true;
|
||||
});
|
||||
|
||||
// 加载数据
|
||||
const loadData = useCallback(async (pageNum: number = 1, isLoadMore = false) => {
|
||||
if (isLoadMore) {
|
||||
setLoadingMore(true);
|
||||
} else {
|
||||
setLoading(true);
|
||||
}
|
||||
|
||||
try {
|
||||
const params: ShopDealerCapitalParam = {
|
||||
page: pageNum,
|
||||
limit: 10,
|
||||
order: 'desc',
|
||||
sort: 'createTime',
|
||||
};
|
||||
|
||||
const result: PageResult<ShopDealerCapital> = await pageShopDealerCapital(params);
|
||||
|
||||
if (result && result.list) {
|
||||
if (isLoadMore) {
|
||||
setRecords(prev => [...prev, ...result.list]);
|
||||
} else {
|
||||
setRecords(result.list);
|
||||
}
|
||||
|
||||
// 计算已结算和待结算金额
|
||||
let settled = 0;
|
||||
let pending = 0;
|
||||
result.list.forEach(item => {
|
||||
const money = item.money || 0;
|
||||
// 佣金收入类的是正向金额,提现支出是负向
|
||||
if (item.flowType === 10 || item.flowType === 40 || item.flowType === 50 || item.flowType === 60) {
|
||||
settled += money;
|
||||
}
|
||||
});
|
||||
|
||||
if (isLoadMore) {
|
||||
setTotalSettled(prev => prev + settled);
|
||||
} else {
|
||||
setTotalSettled(settled);
|
||||
}
|
||||
|
||||
setHasMore(result.list.length >= 10);
|
||||
setPage(pageNum);
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error('获取返利记录失败:', e);
|
||||
Taro.showToast({ title: e.message || '获取数据失败', icon: 'none' });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
setLoadingMore(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 下拉刷新
|
||||
const onPullDownRefresh = useCallback(() => {
|
||||
loadData(1).then(() => {
|
||||
Taro.stopPullDownRefresh();
|
||||
});
|
||||
}, [loadData]);
|
||||
|
||||
// 上拉加载更多
|
||||
const onReachBottom = useCallback(() => {
|
||||
if (!loadingMore && hasMore) {
|
||||
loadData(page + 1, true);
|
||||
}
|
||||
}, [loadingMore, hasMore, page, loadData]);
|
||||
|
||||
useEffect(() => {
|
||||
loadData(1);
|
||||
}, []);
|
||||
|
||||
// 格式化金额
|
||||
const formatMoney = (money: number | undefined, flowType: number | undefined) => {
|
||||
const amount = money || 0;
|
||||
// 提现支出显示为负数
|
||||
if (flowType === 20 || flowType === 30) {
|
||||
return `-¥${Math.abs(amount).toFixed(2)}`;
|
||||
}
|
||||
return `+¥${amount.toFixed(2)}`;
|
||||
};
|
||||
|
||||
// 格式化时间
|
||||
const formatDate = (dateStr: string | undefined) => {
|
||||
if (!dateStr) return '';
|
||||
const date = new Date(dateStr);
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hour = String(date.getHours()).padStart(2, '0');
|
||||
const minute = String(date.getMinutes()).padStart(2, '0');
|
||||
return `${date.getFullYear()}-${month}-${day} ${hour}:${minute}`;
|
||||
};
|
||||
|
||||
// 获取状态信息
|
||||
const getRecordStatus = (flowType: number | undefined) => {
|
||||
// 佣金收入、解冻、配送奖励是已结算
|
||||
if (flowType === 10 || flowType === 40 || flowType === 50 || flowType === 60) {
|
||||
return { text: '已结算', color: 'text-green-500' };
|
||||
}
|
||||
// 提现支出显示为已提现
|
||||
if (flowType === 20 || flowType === 30) {
|
||||
return { text: '已提现', color: 'text-blue-500' };
|
||||
}
|
||||
return { text: '处理中', color: 'text-orange-500' };
|
||||
};
|
||||
|
||||
// 获取类型信息
|
||||
const getRecordType = (flowType: number | undefined) => {
|
||||
const info = flowTypeMap[flowType as keyof typeof flowTypeMap];
|
||||
if (info) {
|
||||
return {
|
||||
label: info.label,
|
||||
bgColor: info.type === 'register' ? rebateTypeMap.register.bgColor : rebateTypeMap.order.bgColor,
|
||||
textColor: info.type === 'register' ? rebateTypeMap.register.textColor : rebateTypeMap.order.textColor,
|
||||
};
|
||||
}
|
||||
return {
|
||||
label: '其他',
|
||||
bgColor: 'bg-gray-100',
|
||||
textColor: 'text-gray-600',
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<View className="min-h-screen bg-gray-100">
|
||||
<NavBar title="返利记录" />
|
||||
|
||||
{/* 统计信息 */}
|
||||
<View className="bg-white p-4 flex justify-around mb-4">
|
||||
<View className="text-center">
|
||||
<Text className="text-2xl font-bold text-green-500 block">¥{totalSettled.toFixed(2)}</Text>
|
||||
<Text className="text-xs text-gray-500">已结算</Text>
|
||||
</View>
|
||||
<View className="text-center">
|
||||
<Text className="text-2xl font-bold text-orange-500 block">¥{totalPending.toFixed(2)}</Text>
|
||||
<Text className="text-xs text-gray-500">待结算</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 标签切换 */}
|
||||
<View className="bg-white flex mb-4">
|
||||
{[
|
||||
{ key: 'all', label: '全部' },
|
||||
{ key: 'settled', label: '已结算' },
|
||||
{ key: 'pending', label: '待结算' }
|
||||
].map(tab => (
|
||||
<View
|
||||
key={tab.key}
|
||||
className={`flex-1 py-3 text-center relative ${
|
||||
activeTab === tab.key ? 'text-red-500 font-medium' : 'text-gray-500'
|
||||
}`}
|
||||
onClick={() => setActiveTab(tab.key as any)}
|
||||
>
|
||||
<Text>{tab.label}</Text>
|
||||
{activeTab === tab.key && (
|
||||
<View className="absolute bottom-0 w-8 bg-red-500 rounded-t" style={{ left: '50%', transform: 'translateX(-50%)', height: '4px' }} />
|
||||
)}
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{/* 记录列表 */}
|
||||
{loading ? (
|
||||
<LoadMore loading />
|
||||
) : filteredRecords.length === 0 ? (
|
||||
<EmptyState message="暂无返利记录" />
|
||||
) : (
|
||||
<ScrollView
|
||||
scrollY
|
||||
className="p-4"
|
||||
onScrollToLower={onReachBottom}
|
||||
onScrollUpperThreshold={50}
|
||||
>
|
||||
{filteredRecords.map(record => {
|
||||
const typeInfo = getRecordType(record.flowType);
|
||||
const statusInfo = getRecordStatus(record.flowType);
|
||||
const isPositive = [10, 40, 50, 60].includes(record.flowType || 0);
|
||||
|
||||
return (
|
||||
<View key={record.id} className="bg-white rounded-lg p-4 mb-4">
|
||||
<View className="flex justify-between items-start mb-2">
|
||||
<View className="flex-1">
|
||||
<View className="flex items-center mb-1">
|
||||
<Text className={`text-xs px-2 py-1 rounded mr-2 ${typeInfo.bgColor} ${typeInfo.textColor}`}>
|
||||
{typeInfo.label}
|
||||
</Text>
|
||||
<Text className={statusInfo.color}>
|
||||
{statusInfo.text}
|
||||
</Text>
|
||||
</View>
|
||||
<Text className="text-base">{record.comments || '返利记录'}</Text>
|
||||
{record.orderNo && (
|
||||
<Text className="text-xs text-gray-500 mt-1 block">订单号:{record.orderNo}</Text>
|
||||
)}
|
||||
{record.toNickName && (
|
||||
<Text className="text-xs text-gray-500 mt-1 block">对方:{record.toNickName}</Text>
|
||||
)}
|
||||
</View>
|
||||
<Text className={`text-xl font-bold ${isPositive ? 'text-green-500' : 'text-red-500'}`}>
|
||||
{formatMoney(record.money, record.flowType)}
|
||||
</Text>
|
||||
</View>
|
||||
<Text className="text-xs text-gray-400">{formatDate(record.createTime)}</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
<LoadMore loading={loadingMore} hasMore={hasMore} />
|
||||
</ScrollView>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
117
src/pages/rebate/withdraw/index.tsx
Normal file
117
src/pages/rebate/withdraw/index.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
import { View, Text, Input } from '@tarojs/components';
|
||||
import { useState } from 'react';
|
||||
import Taro from '@tarojs/taro';
|
||||
import NavBar from '@/components/NavBar';
|
||||
|
||||
export default function RebateWithdrawPage() {
|
||||
const [amount, setAmount] = useState('');
|
||||
const [account, setAccount] = useState('');
|
||||
const [name, setName] = useState('');
|
||||
const [canWithdraw, setCanWithdraw] = useState(528.50);
|
||||
|
||||
const handleWithdraw = () => {
|
||||
if (parseFloat(amount) > canWithdraw) {
|
||||
Taro.showToast({ title: '余额不足', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (parseFloat(amount) < 100) {
|
||||
Taro.showToast({ title: '最低提现金额¥100', icon: 'none' })
|
||||
return
|
||||
}
|
||||
// TODO: 接入提现 API
|
||||
};
|
||||
|
||||
return (
|
||||
<View className="bg-gray-100 flex flex-col" style={{ minHeight: '100vh' }}>
|
||||
<NavBar title="佣金提现" />
|
||||
|
||||
<View className="flex-1 p-4">
|
||||
{/* 可提现金额 */}
|
||||
<View className="bg-white rounded-lg p-4 mb-4">
|
||||
<Text className="text-sm text-gray-500 mb-2 block">可提现金额(元)</Text>
|
||||
<View className="flex items-baseline">
|
||||
<Text className="text-3xl font-bold text-red-500">{canWithdraw.toFixed(2)}</Text>
|
||||
</View>
|
||||
<Text className="text-xs text-gray-400 mt-2 block">最低提现金额 ¥100.00</Text>
|
||||
</View>
|
||||
|
||||
{/* 提现金额 */}
|
||||
<View className="bg-white rounded-lg p-4 mb-4">
|
||||
<Text className="text-base font-medium mb-3 block">提现金额</Text>
|
||||
<View className="flex items-center border-b border-gray-200 pb-3 mb-3">
|
||||
<Text className="text-2xl font-bold mr-2">¥</Text>
|
||||
<Input
|
||||
className="flex-1 text-2xl font-bold"
|
||||
type="digit"
|
||||
placeholder="请输入提现金额"
|
||||
value={amount}
|
||||
onInput={(e: any) => setAmount(e.detail.value)}
|
||||
/>
|
||||
</View>
|
||||
<View className="flex justify-between text-sm">
|
||||
<Text className="text-gray-500">手续费:¥0.00</Text>
|
||||
<Text
|
||||
className="text-blue-500"
|
||||
onClick={() => setAmount(canWithdraw.toString())}
|
||||
>
|
||||
全部提现
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 收款信息 */}
|
||||
<View className="bg-white rounded-lg p-4 mb-4">
|
||||
<Text className="text-base font-medium mb-3 block">收款信息</Text>
|
||||
|
||||
<View className="mb-4">
|
||||
<Text className="text-sm text-gray-600 mb-2 block">收款人姓名</Text>
|
||||
<Input
|
||||
className="w-full p-3 bg-gray-100 rounded-lg text-sm"
|
||||
placeholder="请输入收款人姓名"
|
||||
value={name}
|
||||
onInput={(e: any) => setName(e.detail.value)}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View className="mb-4">
|
||||
<Text className="text-sm text-gray-600 mb-2 block">支付宝账号</Text>
|
||||
<Input
|
||||
className="w-full p-3 bg-gray-100 rounded-lg text-sm"
|
||||
placeholder="请输入支付宝账号"
|
||||
value={account}
|
||||
onInput={(e: any) => setAccount(e.detail.value)}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 提现说明 */}
|
||||
<View className="bg-white rounded-lg p-4 mb-4">
|
||||
<Text className="text-base font-medium mb-3 block">提现说明</Text>
|
||||
<View className="text-sm text-gray-500 flex flex-col" style={{ gap: '8px' }}>
|
||||
<View className="flex">
|
||||
<Text className="text-red-500 mr-2">•</Text>
|
||||
<Text>提现申请将在1-3个工作日内审核</Text>
|
||||
</View>
|
||||
<View className="flex">
|
||||
<Text className="text-red-500 mr-2">•</Text>
|
||||
<Text>提现金额将打入您指定的支付宝账号</Text>
|
||||
</View>
|
||||
<View className="flex">
|
||||
<Text className="text-red-500 mr-2">•</Text>
|
||||
<Text>如有疑问,请联系客服</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="p-4 bg-white border-t border-gray-200" style={{ paddingBottom: '20px' }}>
|
||||
<View
|
||||
className="bg-red-500 text-white rounded-full w-full h-12 flex items-center justify-center"
|
||||
onClick={handleWithdraw}
|
||||
>
|
||||
<Text className="text-white font-medium">申请提现</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user