Улучшена обработка SSD в компонентах QuickDetailSection, UnitDetailsSection и KnotIn. Добавлены отладочные логи для отслеживания значений SSD и состояния загрузки данных. Обновлены условия пропуска запросов в зависимости от наличия SSD. Исправлена логика передачи SSD в компонент KnotIn с использованием значения узла или родительского SSD.

This commit is contained in:
Bivekich
2025-07-05 13:35:49 +03:00
parent e989d402a3
commit 36c5990921
5 changed files with 168 additions and 29 deletions

View File

@ -156,10 +156,15 @@ const QuickDetailSection: React.FC<QuickDetailSectionProps> = ({
}; };
const handleUnitClick = (unit: LaximoUnit) => { const handleUnitClick = (unit: LaximoUnit) => {
setSelectedUnit({ // ИСПРАВЛЕНИЕ: Сохраняем SSD узла из API ответа
...unit, console.log('🔍 handleUnitClick - сохраняем узел с SSD:', {
ssd: unit.ssd || ssd // Сохраняем правильный SSD в selectedUnit unitId: unit.unitid,
unitName: unit.name,
unitSsd: unit.ssd ? `${unit.ssd.substring(0, 50)}...` : 'отсутствует',
unitSsdLength: unit.ssd?.length
}); });
setSelectedUnit(unit); // Сохраняем полный объект узла с его SSD
}; };
const handleBackFromUnit = () => { const handleBackFromUnit = () => {
@ -209,21 +214,23 @@ const QuickDetailSection: React.FC<QuickDetailSectionProps> = ({
// Если выбран узел для детального просмотра, показываем UnitDetailsSection // Если выбран узел для детального просмотра, показываем UnitDetailsSection
if (selectedUnit) { if (selectedUnit) {
const unitSsd = selectedUnit.ssd || ssd; // ИСПРАВЛЕНИЕ: Используем SSD узла из API ответа, а не родительский SSD
// API Laximo возвращает для каждого узла свой собственный SSD
console.log('🔍 QuickDetailSection передает в UnitDetailsSection:', { console.log('🔍 QuickDetailSection передает в UnitDetailsSection:', {
unitSsd: unitSsd ? `${unitSsd.substring(0, 50)}...` : 'отсутствует', parentSsd: ssd ? `${ssd.substring(0, 50)}...` : 'отсутствует',
unitSsdLength: unitSsd?.length, parentSsdLength: ssd?.length,
selectedUnitSsd: selectedUnit.ssd ? `${selectedUnit.ssd.substring(0, 50)}...` : 'отсутствует', selectedUnitSsd: selectedUnit.ssd ? `${selectedUnit.ssd.substring(0, 50)}...` : 'отсутствует',
fallbackSsd: ssd ? `${ssd.substring(0, 50)}...` : 'отсутствует', selectedUnitSsdLength: selectedUnit.ssd?.length,
unitId: selectedUnit.unitid, unitId: selectedUnit.unitid,
unitName: selectedUnit.name unitName: selectedUnit.name,
note: 'Используем SSD УЗЛА из API ответа'
}); });
return ( return (
<UnitDetailsSection <UnitDetailsSection
catalogCode={catalogCode} catalogCode={catalogCode}
vehicleId={vehicleId} vehicleId={vehicleId}
ssd={unitSsd} // Используем SSD узла ssd={selectedUnit.ssd || ssd} // Используем SSD узла, fallback на родительский SSD
unitId={selectedUnit.unitid} unitId={selectedUnit.unitid}
unitName={selectedUnit.name} unitName={selectedUnit.name}
onBack={handleBackFromUnit} onBack={handleBackFromUnit}

View File

@ -42,7 +42,8 @@ const UnitDetailsSection: React.FC<UnitDetailsSectionProps> = ({
ssd: ssd ? `${ssd.substring(0, 50)}...` : 'отсутствует', ssd: ssd ? `${ssd.substring(0, 50)}...` : 'отсутствует',
ssdLength: ssd?.length, ssdLength: ssd?.length,
unitId, unitId,
unitName unitName,
note: 'Используем SSD узла для API запросов'
}); });
const { data: unitInfoData, loading: unitInfoLoading, error: unitInfoError } = useQuery<{ laximoUnitInfo: LaximoUnitInfo }>( const { data: unitInfoData, loading: unitInfoLoading, error: unitInfoError } = useQuery<{ laximoUnitInfo: LaximoUnitInfo }>(
@ -52,11 +53,11 @@ const UnitDetailsSection: React.FC<UnitDetailsSectionProps> = ({
catalogCode, catalogCode,
vehicleId, vehicleId,
unitId, unitId,
ssd: ssd || '' ssd
}, },
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId, skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId || !ssd || ssd.trim() === '',
errorPolicy: 'all', errorPolicy: 'all',
fetchPolicy: 'no-cache', // Отключаем кэширование для получения актуального SSD fetchPolicy: 'no-cache', // Отключаем кэширование для получения актуальных данных
notifyOnNetworkStatusChange: true notifyOnNetworkStatusChange: true
} }
); );
@ -76,9 +77,9 @@ const UnitDetailsSection: React.FC<UnitDetailsSectionProps> = ({
catalogCode, catalogCode,
vehicleId, vehicleId,
unitId, unitId,
ssd: ssd || '' ssd
}, },
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId, skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId || !ssd || ssd.trim() === '',
errorPolicy: 'all', errorPolicy: 'all',
fetchPolicy: 'no-cache', // Отключаем кэширование для получения актуального SSD fetchPolicy: 'no-cache', // Отключаем кэширование для получения актуального SSD
notifyOnNetworkStatusChange: true notifyOnNetworkStatusChange: true
@ -100,9 +101,9 @@ const UnitDetailsSection: React.FC<UnitDetailsSectionProps> = ({
catalogCode, catalogCode,
vehicleId, vehicleId,
unitId, unitId,
ssd: ssd || '' ssd
}, },
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId, skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId || !ssd || ssd.trim() === '',
errorPolicy: 'all', errorPolicy: 'all',
fetchPolicy: 'no-cache', // Отключаем кэширование для получения актуального SSD fetchPolicy: 'no-cache', // Отключаем кэширование для получения актуального SSD
notifyOnNetworkStatusChange: true notifyOnNetworkStatusChange: true

View File

@ -43,30 +43,72 @@ const KnotIn: React.FC<KnotInProps> = ({ catalogCode, vehicleId, ssd, unitId, un
const router = useRouter(); const router = useRouter();
// Получаем инфо об узле (для картинки) // Получаем инфо об узле (для картинки)
console.log('🔍 KnotIn - GET_LAXIMO_UNIT_INFO запрос:', {
catalogCode,
vehicleId,
unitId,
ssd: ssd ? `${ssd.substring(0, 50)}...` : 'отсутствует',
ssdLength: ssd?.length,
skipCondition: !catalogCode || !vehicleId || !unitId || !ssd || ssd.trim() === ''
});
const { data: unitInfoData, loading: unitInfoLoading, error: unitInfoError } = useQuery( const { data: unitInfoData, loading: unitInfoLoading, error: unitInfoError } = useQuery(
GET_LAXIMO_UNIT_INFO, GET_LAXIMO_UNIT_INFO,
{ {
variables: { catalogCode: catalogCode || '', vehicleId: vehicleId || '', unitId: unitId || '', ssd: ssd || '' }, variables: {
skip: !catalogCode || !vehicleId || !unitId, catalogCode,
vehicleId,
unitId,
ssd
},
skip: !catalogCode || !vehicleId || !unitId || !ssd || ssd.trim() === '',
errorPolicy: 'all', errorPolicy: 'all',
} }
); );
// Получаем карту координат // Получаем карту координат
console.log('🔍 KnotIn - GET_LAXIMO_UNIT_IMAGE_MAP запрос:', {
catalogCode,
vehicleId,
unitId,
ssd: ssd ? `${ssd.substring(0, 50)}...` : 'отсутствует',
ssdLength: ssd?.length,
skipCondition: !catalogCode || !vehicleId || !unitId || !ssd || ssd.trim() === ''
});
const { data: imageMapData, loading: imageMapLoading, error: imageMapError } = useQuery( const { data: imageMapData, loading: imageMapLoading, error: imageMapError } = useQuery(
GET_LAXIMO_UNIT_IMAGE_MAP, GET_LAXIMO_UNIT_IMAGE_MAP,
{ {
variables: { catalogCode: catalogCode || '', vehicleId: vehicleId || '', unitId: unitId || '', ssd: ssd || '' }, variables: {
skip: !catalogCode || !vehicleId || !unitId, catalogCode,
vehicleId,
unitId,
ssd
},
skip: !catalogCode || !vehicleId || !unitId || !ssd || ssd.trim() === '',
errorPolicy: 'all', errorPolicy: 'all',
} }
); );
// Если нет необходимых данных, показываем заглушку // Если нет необходимых данных, показываем заглушку
if (!catalogCode || !vehicleId || !unitId) { if (!catalogCode || !vehicleId || !unitId || !ssd || ssd.trim() === '') {
console.log('⚠️ KnotIn: отсутствуют необходимые данные:', {
catalogCode: !!catalogCode,
vehicleId: !!vehicleId,
unitId: !!unitId,
ssd: !!ssd,
ssdValid: ssd ? ssd.trim() !== '' : false
});
return ( return (
<div className="text-center py-8 text-gray-500"> <div className="text-center py-8 text-gray-500">
<div className="text-lg font-medium mb-2">Схема узла</div> <div className="text-lg font-medium mb-2">Схема узла</div>
<div className="text-sm">Выберите узел для отображения схемы</div> <div className="text-sm">Выберите узел для отображения схемы</div>
{process.env.NODE_ENV === 'development' && (
<div className="text-xs text-red-500 mt-2">
Debug: catalogCode={catalogCode}, vehicleId={vehicleId}, unitId={unitId}, ssd={ssd ? 'есть' : 'нет'}
</div>
)}
</div> </div>
); );
} }
@ -75,6 +117,29 @@ const KnotIn: React.FC<KnotInProps> = ({ catalogCode, vehicleId, ssd, unitId, un
const coordinates = imageMapData?.laximoUnitImageMap?.coordinates || []; const coordinates = imageMapData?.laximoUnitImageMap?.coordinates || [];
const imageUrl = unitInfo?.imageurl ? getImageUrl(unitInfo.imageurl, selectedImageSize) : ''; const imageUrl = unitInfo?.imageurl ? getImageUrl(unitInfo.imageurl, selectedImageSize) : '';
// Логируем успешную загрузку данных
React.useEffect(() => {
if (unitInfo) {
console.log('✅ KnotIn: данные узла загружены:', {
unitName: unitInfo.name,
hasImage: !!unitInfo.imageurl,
imageUrl: unitInfo.imageurl,
processedImageUrl: imageUrl
});
}
}, [unitInfo, imageUrl]);
React.useEffect(() => {
if (coordinates.length > 0) {
console.log('✅ KnotIn: координаты карты загружены:', {
coordinatesCount: coordinates.length,
firstCoordinate: coordinates[0]
});
} else if (imageMapData) {
console.log('⚠️ KnotIn: карта изображений загружена, но координаты пустые:', imageMapData);
}
}, [coordinates, imageMapData]);
// Масштабируем точки после загрузки картинки // Масштабируем точки после загрузки картинки
const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => { const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {
const img = e.currentTarget; const img = e.currentTarget;
@ -110,13 +175,49 @@ const KnotIn: React.FC<KnotInProps> = ({ catalogCode, vehicleId, ssd, unitId, un
}, [parts, coordinates]); }, [parts, coordinates]);
if (unitInfoLoading || imageMapLoading) { if (unitInfoLoading || imageMapLoading) {
console.log('🔄 KnotIn: загрузка данных...', {
unitInfoLoading,
imageMapLoading,
unitInfoError: unitInfoError?.message,
imageMapError: imageMapError?.message
});
return <div className="text-center py-8 text-gray-500">Загружаем схему узла...</div>; return <div className="text-center py-8 text-gray-500">Загружаем схему узла...</div>;
} }
if (unitInfoError) { if (unitInfoError) {
return <div className="text-center py-8 text-red-600">Ошибка загрузки схемы: {unitInfoError.message}</div>; console.error('❌ KnotIn: ошибка загрузки информации об узле:', unitInfoError);
return (
<div className="text-center py-8 text-red-600">
Ошибка загрузки схемы: {unitInfoError.message}
{process.env.NODE_ENV === 'development' && (
<div className="text-xs mt-2 text-gray-500">
GraphQL Error: {JSON.stringify(unitInfoError, null, 2)}
</div>
)}
</div>
);
} }
if (imageMapError) {
console.error('❌ KnotIn: ошибка загрузки карты изображений:', imageMapError);
}
if (!imageUrl) { if (!imageUrl) {
return <div className="text-center py-8 text-gray-400">Нет изображения для этого узла</div>; console.log('⚠️ KnotIn: нет URL изображения:', {
unitInfo: !!unitInfo,
imageurl: unitInfo?.imageurl,
unitInfoData: !!unitInfoData
});
return (
<div className="text-center py-8 text-gray-400">
Нет изображения для этого узла
{process.env.NODE_ENV === 'development' && unitInfo && (
<div className="text-xs mt-2 text-gray-500">
Debug: unitInfo.imageurl = {unitInfo.imageurl || 'отсутствует'}
</div>
)}
</div>
);
} }
return ( return (

View File

@ -327,7 +327,12 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
className="dropdown-link-3 w-dropdown-link" className="dropdown-link-3 w-dropdown-link"
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
handleQuickGroupToggle(group.quickgroupid, 0); // Если это конечная группа с link=true, открываем QuickGroup
if (group.link && onQuickGroupSelect) {
onQuickGroupSelect(group);
} else {
handleQuickGroupToggle(group.quickgroupid, 0);
}
}} }}
> >
{group.name} {group.name}
@ -366,7 +371,12 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
className="dropdown-link-3 w-dropdown-link" className="dropdown-link-3 w-dropdown-link"
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
handleQuickGroupToggle(child.quickgroupid, 1); // Если это конечная группа с link=true, открываем QuickGroup
if (child.link && onQuickGroupSelect) {
onQuickGroupSelect(child);
} else {
handleQuickGroupToggle(child.quickgroupid, 1);
}
}} }}
> >
{child.name} {child.name}
@ -400,7 +410,12 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
className="dropdown-link-3 w-dropdown-link" className="dropdown-link-3 w-dropdown-link"
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
handleQuickGroupToggle(subChild.quickgroupid, 3); // Если это конечная группа с link=true, открываем QuickGroup
if (subChild.link && onQuickGroupSelect) {
onQuickGroupSelect(subChild);
} else {
handleQuickGroupToggle(subChild.quickgroupid, 3);
}
}} }}
> >
{subChild.name} {subChild.name}
@ -458,7 +473,10 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
className="dropdown-link-3 w-dropdown-link pl-0" className="dropdown-link-3 w-dropdown-link pl-0"
onClick={e => { onClick={e => {
e.preventDefault(); e.preventDefault();
if (onNodeSelect) { // Если это конечная категория с link=true, открываем QuickGroup
if (subcat.link && onQuickGroupSelect) {
onQuickGroupSelect(subcat);
} else if (onNodeSelect) {
onNodeSelect({ onNodeSelect({
...subcat, ...subcat,
unitid: subcat.unitid || subcat.quickgroupid || subcat.id unitid: subcat.unitid || subcat.quickgroupid || subcat.id

View File

@ -414,10 +414,22 @@ const VehicleDetailsPage = () => {
<div className="w-layout-hflex flex-block-13"> <div className="w-layout-hflex flex-block-13">
<div className="w-layout-vflex flex-block-14-copy-copy"> <div className="w-layout-vflex flex-block-14-copy-copy">
{/* <button onClick={() => setSelectedNode(null)} style={{ marginBottom: 16 }}>Назад</button> */} {/* <button onClick={() => setSelectedNode(null)} style={{ marginBottom: 16 }}>Назад</button> */}
{/* ОТЛАДКА: Логируем передачу SSD в KnotIn */}
{(() => {
const knotSsd = selectedNode.ssd || vehicleInfo.ssd;
console.log('🔍 [vehicleId].tsx передает в KnotIn:', {
selectedNodeSsd: selectedNode.ssd ? `${selectedNode.ssd.substring(0, 50)}...` : 'отсутствует',
vehicleInfoSsd: vehicleInfo.ssd ? `${vehicleInfo.ssd.substring(0, 50)}...` : 'отсутствует',
finalSsd: knotSsd ? `${knotSsd.substring(0, 50)}...` : 'отсутствует',
unitId: selectedNode.unitid,
unitName: selectedNode.name
});
return null;
})()}
<KnotIn <KnotIn
catalogCode={vehicleInfo.catalog} catalogCode={vehicleInfo.catalog}
vehicleId={vehicleInfo.vehicleid} vehicleId={vehicleInfo.vehicleid}
ssd={vehicleInfo.ssd} ssd={selectedNode.ssd || vehicleInfo.ssd} // ИСПРАВЛЕНИЕ: Используем SSD узла, fallback на родительский SSD
unitId={selectedNode.unitid} unitId={selectedNode.unitid}
unitName={selectedNode.name} unitName={selectedNode.name}
parts={unitDetails} parts={unitDetails}