Compare commits
2 Commits
b55f6f859a
...
7a15b7cf79
Author | SHA1 | Date | |
---|---|---|---|
7a15b7cf79 | |||
f182112cd4 |
@ -56,14 +56,14 @@ export function FulfillmentWarehouse2Demo() {
|
||||
const [sortOrder, setSortOrder] = useState<"asc" | "desc">("asc");
|
||||
const [expandedStores, setExpandedStores] = useState<Set<string>>(new Set());
|
||||
|
||||
// Мок данные для статистики
|
||||
// Данные для статистики - показываем только реальные данные
|
||||
const warehouseStats: WarehouseStats = {
|
||||
products: { current: 2856, change: 124 },
|
||||
goods: { current: 1391, change: 87 },
|
||||
defects: { current: 43, change: -12 },
|
||||
pvzReturns: { current: 256, change: 34 },
|
||||
fulfillmentSupplies: { current: 189, change: 23 },
|
||||
sellerSupplies: { current: 534, change: 67 },
|
||||
products: { current: 0, change: 0 }, // Нет данных о продуктах
|
||||
goods: { current: 0, change: 0 }, // Нет данных о товарах
|
||||
defects: { current: 0, change: 0 }, // Нет данных о браке
|
||||
pvzReturns: { current: 0, change: 0 }, // Нет данных о возвратах с ПВЗ
|
||||
fulfillmentSupplies: { current: 0, change: 0 }, // Нет данных о расходниках ФФ
|
||||
sellerSupplies: { current: 0, change: 0 }, // Нет данных о расходниках селлера
|
||||
};
|
||||
|
||||
// Мок данные для магазинов
|
||||
@ -252,6 +252,7 @@ export function FulfillmentWarehouse2Demo() {
|
||||
</div>
|
||||
<span className="text-white text-xs font-semibold">{title}</span>
|
||||
</div>
|
||||
{/* Показываем изменения всегда */}
|
||||
<div
|
||||
className={`flex items-center space-x-1 px-1.5 py-0.5 rounded-full ${
|
||||
change >= 0 ? "bg-green-500/20" : "bg-red-500/20"
|
||||
|
@ -46,38 +46,38 @@ export function FulfillmentStatisticsDashboard() {
|
||||
quickActions: true,
|
||||
});
|
||||
|
||||
// Мок данные для статистики
|
||||
// Реальные данные для статистики (пока отсутствуют)
|
||||
const statisticsData = {
|
||||
// Данные за все время
|
||||
totalProducts: 15678,
|
||||
totalDefects: 145,
|
||||
totalSupplies: 2341,
|
||||
totalRevenue: 45670000,
|
||||
totalOrders: 8934,
|
||||
totalProducts: 0,
|
||||
totalDefects: 0,
|
||||
totalSupplies: 0,
|
||||
totalRevenue: 0,
|
||||
totalOrders: 0,
|
||||
|
||||
// Отправка на маркетплейсы
|
||||
sentToWildberries: 8934,
|
||||
sentToOzon: 4523,
|
||||
sentToOthers: 1876,
|
||||
sentToWildberries: 0,
|
||||
sentToOzon: 0,
|
||||
sentToOthers: 0,
|
||||
|
||||
// Аналитика производительности
|
||||
avgProcessingTime: 2.4,
|
||||
defectRate: 0.92,
|
||||
returnRate: 4.3,
|
||||
customerSatisfaction: 4.8,
|
||||
avgProcessingTime: 0,
|
||||
defectRate: 0,
|
||||
returnRate: 0,
|
||||
customerSatisfaction: 0,
|
||||
|
||||
// Тренды
|
||||
revenueTrend: 18,
|
||||
ordersTrend: 12,
|
||||
defectsTrend: -8,
|
||||
satisfactionTrend: 5,
|
||||
revenueTrend: 0,
|
||||
ordersTrend: 0,
|
||||
defectsTrend: 0,
|
||||
satisfactionTrend: 0,
|
||||
};
|
||||
|
||||
// Данные склада (перенесено из fulfillment-warehouse)
|
||||
// Данные склада (пока отсутствуют)
|
||||
const warehouseStats = {
|
||||
efficiency: 94.5,
|
||||
turnover: 2.3,
|
||||
utilizationRate: 87,
|
||||
efficiency: 0,
|
||||
turnover: 0,
|
||||
utilizationRate: 0,
|
||||
};
|
||||
|
||||
const formatNumber = (num: number) => {
|
||||
|
@ -389,8 +389,8 @@ export function FulfillmentWarehouseDashboard() {
|
||||
|
||||
return {
|
||||
products: {
|
||||
current: totalProductsFromOrders, // Реальное количество товаров на складе
|
||||
change: productsReceivedToday - productsUsedToday, // Реальное изменение за сутки
|
||||
current: 0, // Нет данных о готовых продуктах для продажи
|
||||
change: 0, // Нет данных об изменениях продуктов
|
||||
},
|
||||
goods: {
|
||||
current: 0, // Нет реальных данных о готовых товарах
|
||||
@ -695,20 +695,8 @@ export function FulfillmentWarehouseDashboard() {
|
||||
)
|
||||
);
|
||||
|
||||
// Реальные изменения товаров для этого партнера
|
||||
const partnerProductsChange =
|
||||
totalProducts > 0
|
||||
? Math.floor(
|
||||
(totalProducts /
|
||||
(allProducts.reduce(
|
||||
(sum, p: any) => sum + (p.orderedQuantity || 0),
|
||||
0
|
||||
) || 1)) *
|
||||
(productsReceivedToday - productsUsedToday)
|
||||
)
|
||||
: Math.floor(
|
||||
(productsReceivedToday - productsUsedToday) / totalVirtualPartners
|
||||
);
|
||||
// Нет данных об изменениях продуктов для этого партнера
|
||||
const partnerProductsChange = 0;
|
||||
|
||||
// Реальные изменения расходников селлера для этого партнера
|
||||
const partnerSuppliesChange =
|
||||
@ -720,9 +708,9 @@ export function FulfillmentWarehouseDashboard() {
|
||||
sum + (supply.currentStock || 0),
|
||||
0
|
||||
) || 1)) *
|
||||
suppliesReceivedToday
|
||||
(suppliesReceivedToday - suppliesUsedToday)
|
||||
)
|
||||
: Math.floor(suppliesReceivedToday / totalVirtualPartners);
|
||||
: Math.floor((suppliesReceivedToday - suppliesUsedToday) / totalVirtualPartners);
|
||||
|
||||
return {
|
||||
id: `virtual-partner-${index + 1}`,
|
||||
@ -977,9 +965,6 @@ export function FulfillmentWarehouseDashboard() {
|
||||
change: number;
|
||||
description: string;
|
||||
}) => {
|
||||
// Генерируем случайные значения для положительных и отрицательных изменений
|
||||
const positiveChange = Math.floor(Math.random() * 50) + 10; // от 10 до 59
|
||||
const negativeChange = Math.floor(Math.random() * 30) + 5; // от 5 до 34
|
||||
const percentChange = current > 0 ? (change / current) * 100 : 0;
|
||||
|
||||
return (
|
||||
@ -993,7 +978,7 @@ export function FulfillmentWarehouseDashboard() {
|
||||
</div>
|
||||
<span className="text-white text-xs font-semibold">{title}</span>
|
||||
</div>
|
||||
{/* Процентное изменение */}
|
||||
{/* Процентное изменение - всегда показываем */}
|
||||
<div className="flex items-center space-x-0.5 px-1.5 py-0.5 rounded bg-blue-500/20">
|
||||
{change >= 0 ? (
|
||||
<TrendingUp className="h-3 w-3 text-green-400" />
|
||||
@ -1013,17 +998,15 @@ export function FulfillmentWarehouseDashboard() {
|
||||
<div className="text-lg font-bold text-white">
|
||||
{formatNumber(current)}
|
||||
</div>
|
||||
{/* Изменения - всегда показываем */}
|
||||
<div className="flex items-center space-x-1">
|
||||
{/* Положительное изменение */}
|
||||
<div className="flex items-center space-x-0.5 px-1 py-0.5 rounded bg-green-500/20">
|
||||
<span className="text-xs font-bold text-green-400">
|
||||
+{positiveChange}
|
||||
</span>
|
||||
</div>
|
||||
{/* Отрицательное изменение */}
|
||||
<div className="flex items-center space-x-0.5 px-1 py-0.5 rounded bg-red-500/20">
|
||||
<span className="text-xs font-bold text-red-400">
|
||||
-{negativeChange}
|
||||
<div className={`flex items-center space-x-0.5 px-1 py-0.5 rounded ${
|
||||
change >= 0 ? 'bg-green-500/20' : 'bg-red-500/20'
|
||||
}`}>
|
||||
<span className={`text-xs font-bold ${
|
||||
change >= 0 ? 'text-green-400' : 'text-red-400'
|
||||
}`}>
|
||||
{change >= 0 ? '+' : ''}{change}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -1483,12 +1466,12 @@ export function FulfillmentWarehouseDashboard() {
|
||||
<div className="flex items-center justify-end space-x-1">
|
||||
<div className="flex items-center space-x-0.5">
|
||||
<span className="text-[9px] font-bold text-green-400">
|
||||
+0 {/* ТЕСТ: Временно захардкожено для проверки */}
|
||||
+{Math.max(totals.sellerSuppliesChange, 0)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-0.5">
|
||||
<span className="text-[9px] font-bold text-red-400">
|
||||
-0 {/* ТЕСТ: Временно захардкожено для проверки */}
|
||||
-{Math.max(-totals.sellerSuppliesChange, 0)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-0.5">
|
||||
|
@ -153,7 +153,7 @@ const CompactCampaignSelector = ({
|
||||
selectedCampaigns: number[],
|
||||
loading: boolean
|
||||
}) => {
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
const [isExpanded, setIsExpanded] = useState(true) // Автоматически разворачиваем для удобства
|
||||
const [showManualInput, setShowManualInput] = useState(false)
|
||||
const [manualIds, setManualIds] = useState('')
|
||||
const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set(selectedCampaigns))
|
||||
@ -166,6 +166,20 @@ const CompactCampaignSelector = ({
|
||||
|
||||
const campaigns = campaignsData?.getWildberriesCampaignsList?.data?.adverts || []
|
||||
|
||||
// Автоматически выбираем активные кампании при загрузке данных
|
||||
useEffect(() => {
|
||||
if (campaigns.length > 0 && selectedIds.size === 0) {
|
||||
const activeCampaigns = campaigns
|
||||
.filter((group: CampaignGroup) => group.status === 9) // Активные кампании
|
||||
.flatMap((group: CampaignGroup) => group.advert_list.map((item: CampaignListItem) => item.advertId))
|
||||
.slice(0, 3) // Берем первые 3 активные кампании
|
||||
|
||||
if (activeCampaigns.length > 0) {
|
||||
setSelectedIds(new Set(activeCampaigns))
|
||||
}
|
||||
}
|
||||
}, [campaigns])
|
||||
|
||||
// Функции для получения названий типов и статусов
|
||||
const getCampaignTypeName = (type: number) => {
|
||||
const types: Record<number, string> = {
|
||||
@ -280,7 +294,7 @@ const CompactCampaignSelector = ({
|
||||
) : (
|
||||
<>
|
||||
<Search className="h-3 w-3 mr-1" />
|
||||
Загрузить
|
||||
{selectedIds.size > 0 ? `Загрузить (${selectedIds.size})` : 'Выбрать'}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
@ -1001,10 +1015,23 @@ export function AdvertisingTab({ selectedPeriod, useCustomDates, startDate, endD
|
||||
<div className="text-center">
|
||||
<TrendingUp className="h-12 w-12 text-white/40 mx-auto mb-4" />
|
||||
<h3 className="text-lg font-semibold text-white mb-2">Статистика рекламных кампаний</h3>
|
||||
<p className="text-white/60 mb-4">Выберите кампании для получения детальной статистики</p>
|
||||
<p className="text-white/40 text-sm">
|
||||
<p className="text-white/60 mb-4">Выберите кампании выше и нажмите “Загрузить” для получения статистики</p>
|
||||
<p className="text-white/40 text-sm mb-4">
|
||||
Поддерживается API Wildberries /adv/v2/fullstats
|
||||
</p>
|
||||
|
||||
{/* Инструкция для пользователя */}
|
||||
<div className="bg-white/5 rounded-lg p-4 border border-white/10">
|
||||
<h4 className="text-white font-medium mb-2 flex items-center gap-2">
|
||||
<Target className="h-4 w-4" />
|
||||
Как начать работу:
|
||||
</h4>
|
||||
<ol className="text-white/60 text-sm space-y-1 list-decimal list-inside">
|
||||
<li>Разверните селектор кампаний выше (нажмите кнопку с иконкой)</li>
|
||||
<li>Выберите нужные кампании из списка или введите ID вручную</li>
|
||||
<li>Нажмите кнопку “Загрузить” для получения статистики</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
@ -35,49 +35,7 @@ export function FulfillmentWarehouseTab() {
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [selectedStatus, setSelectedStatus] = useState<string>('all')
|
||||
|
||||
const [orders, setOrders] = useState<FulfillmentOrder[]>([
|
||||
{
|
||||
id: '1',
|
||||
orderId: 'FL-2024-001',
|
||||
customerName: 'Иван Петров',
|
||||
items: [
|
||||
{ name: 'Товар A', quantity: 2, sku: 'SKU-001' },
|
||||
{ name: 'Товар B', quantity: 1, sku: 'SKU-002' }
|
||||
],
|
||||
status: 'pending',
|
||||
priority: 'high',
|
||||
createdAt: '2024-01-15T10:30:00',
|
||||
shippingAddress: 'Москва, ул. Ленина, 10',
|
||||
totalValue: 3500
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
orderId: 'FL-2024-002',
|
||||
customerName: 'Анна Сидорова',
|
||||
items: [
|
||||
{ name: 'Товар C', quantity: 1, sku: 'SKU-003' }
|
||||
],
|
||||
status: 'processing',
|
||||
priority: 'medium',
|
||||
createdAt: '2024-01-14T15:20:00',
|
||||
shippingAddress: 'СПб, пр. Невский, 25',
|
||||
totalValue: 1200
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
orderId: 'FL-2024-003',
|
||||
customerName: 'Олег Козлов',
|
||||
items: [
|
||||
{ name: 'Товар D', quantity: 3, sku: 'SKU-004' },
|
||||
{ name: 'Товар E', quantity: 2, sku: 'SKU-005' }
|
||||
],
|
||||
status: 'shipped',
|
||||
priority: 'low',
|
||||
createdAt: '2024-01-13T09:15:00',
|
||||
shippingAddress: 'Екатеринбург, ул. Мира, 45',
|
||||
totalValue: 5600
|
||||
}
|
||||
])
|
||||
const [orders, setOrders] = useState<FulfillmentOrder[]>([])
|
||||
|
||||
const stats: FulfillmentStats = {
|
||||
totalOrders: orders.length,
|
||||
|
Reference in New Issue
Block a user