Обновлены компоненты интерфейса для работы с карточками товаров Wildberries: добавлены новые функции для загрузки и поиска карточек, улучшен интерфейс отображения товаров и их деталей. Исправлены проблемы с отображением текста и добавлены новые поля в GraphQL для работы с API ключами. Реализована логика обработки ошибок при взаимодействии с API.

This commit is contained in:
Bivekich
2025-07-21 13:51:12 +03:00
parent d964b9b6d4
commit d3fb590c6e
10 changed files with 836 additions and 254 deletions

View File

@ -43,7 +43,7 @@ interface WildberriesCardsResponse {
}
interface WildberriesCardFilter {
sort?: {
settings?: {
cursor?: {
limit?: number
nmID?: number
@ -55,61 +55,55 @@ interface WildberriesCardFilter {
objectIDs?: number[]
tagIDs?: number[]
brandIDs?: number[]
colorIDs?: number[]
sizeIDs?: number[]
}
}
}
export class WildberriesService {
private static baseUrl = 'https://marketplace-api.wildberries.ru'
private static contentUrl = 'https://content-api.wildberries.ru'
private static publicUrl = 'https://public-api.wildberries.ru'
private static supplierUrl = 'https://suppliers-api.wildberries.ru'
/**
* Получить список складов WB
*/
static async getWarehouses(apiKey: string): Promise<WildberriesWarehouse[]> {
try {
const response = await fetch(`${this.baseUrl}/api/v2/warehouses`, {
method: 'GET',
headers: {
'Authorization': apiKey,
'Content-Type': 'application/json',
},
})
if (!response.ok) {
throw new Error(`WB API Error: ${response.status} ${response.statusText}`)
}
const data: WildberriesWarehousesResponse = await response.json()
return data.data || []
} catch (error) {
console.error('Error fetching WB warehouses:', error)
throw new Error('Ошибка получения складов Wildberries')
}
}
/**
* Получить карточки товаров
* Получение карточек товаров через Content API v2
*/
static async getCards(apiKey: string, filter?: WildberriesCardFilter): Promise<WildberriesCard[]> {
try {
const response = await fetch(`${this.contentUrl}/content/v1/cards/cursor/list`, {
console.log('Calling WB Content API v2 with filter:', filter)
const response = await fetch(`${this.contentUrl}/content/v2/get/cards/list`, {
method: 'POST',
headers: {
'Authorization': apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(filter || {
sort: {
settings: {
cursor: {
limit: 100
},
filter: {
withPhoto: -1
}
}
})
})
console.log(`${this.contentUrl}/content/v2/get/cards/list`, response.status, response.statusText)
if (!response.ok) {
throw new Error(`WB API Error: ${response.status} ${response.statusText}`)
const errorText = await response.text()
let errorData
try {
errorData = JSON.parse(errorText)
} catch {
errorData = { message: errorText }
}
console.log('WB API Error Response:', errorData)
throw new Error(`WB API Error: ${response.status} - ${response.statusText}`)
}
const data: WildberriesCardsResponse = await response.json()
@ -121,16 +115,17 @@ export class WildberriesService {
}
/**
* Поиск карточек товаров по тексту
* Поиск карточек товаров
*/
static async searchCards(apiKey: string, searchText: string, limit: number = 100): Promise<WildberriesCard[]> {
static async searchCards(apiKey: string, searchTerm: string, limit = 50): Promise<WildberriesCard[]> {
const filter: WildberriesCardFilter = {
sort: {
settings: {
cursor: {
limit
},
filter: {
textSearch: searchText
textSearch: searchTerm,
withPhoto: -1
}
}
}
@ -139,63 +134,70 @@ export class WildberriesService {
}
/**
* Валидация API ключа WB
* Получение всех карточек товаров с пагинацией
*/
static async getAllCards(apiKey: string, limit = 100): Promise<WildberriesCard[]> {
const filter: WildberriesCardFilter = {
settings: {
cursor: {
limit
},
filter: {
withPhoto: -1
}
}
}
return this.getCards(apiKey, filter)
}
/**
* Получение складов WB
*/
static async getWarehouses(apiKey: string): Promise<WildberriesWarehouse[]> {
try {
const response = await fetch(`${this.supplierUrl}/api/v3/warehouses`, {
headers: {
'Authorization': apiKey,
}
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const data: WildberriesWarehousesResponse = await response.json()
return data.data || []
} catch (error) {
console.error('Error fetching warehouses:', error)
return []
}
}
/**
* Проверка валидности API ключа
*/
static async validateApiKey(apiKey: string): Promise<boolean> {
try {
await this.getWarehouses(apiKey)
return true
const response = await fetch(`${this.contentUrl}/content/v2/get/cards/list`, {
method: 'POST',
headers: {
'Authorization': apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({
settings: {
cursor: {
limit: 1
}
}
})
})
return response.ok
} catch (error) {
console.error('WB API key validation failed:', error)
console.error('Error validating API key:', error)
return false
}
}
/**
* Получить информацию о поставке
*/
static async getSupplyInfo(apiKey: string, supplyId: string): Promise<unknown> {
try {
const response = await fetch(`${this.baseUrl}/api/v3/supplies/${supplyId}`, {
method: 'GET',
headers: {
'Authorization': apiKey,
'Content-Type': 'application/json',
},
})
if (!response.ok) {
throw new Error(`WB API Error: ${response.status} ${response.statusText}`)
}
return await response.json()
} catch (error) {
console.error('Error fetching WB supply info:', error)
throw new Error('Ошибка получения информации о поставке')
}
}
/**
* Получить список поставок
*/
static async getSupplies(apiKey: string, limit: number = 1000, next: number = 0): Promise<unknown> {
try {
const response = await fetch(`${this.baseUrl}/api/v3/supplies?limit=${limit}&next=${next}`, {
method: 'GET',
headers: {
'Authorization': apiKey,
'Content-Type': 'application/json',
},
})
if (!response.ok) {
throw new Error(`WB API Error: ${response.status} ${response.statusText}`)
}
return await response.json()
} catch (error) {
console.error('Error fetching WB supplies:', error)
throw new Error('Ошибка получения списка поставок')
}
}
}