Добавлены новые зависимости, обновлены стили и улучшена структура проекта. Обновлен README с описанием функционала и технологий. Реализована анимация и адаптивный дизайн. Настроена авторизация с использованием Apollo Client.
This commit is contained in:
223
src/services/marketplace-service.ts
Normal file
223
src/services/marketplace-service.ts
Normal file
@ -0,0 +1,223 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export interface MarketplaceValidationResult {
|
||||
isValid: boolean
|
||||
message: string
|
||||
data?: {
|
||||
sellerId?: string
|
||||
sellerName?: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export interface WildberriesSellerInfo {
|
||||
id: number
|
||||
name: string
|
||||
inn: string
|
||||
kpp?: string
|
||||
}
|
||||
|
||||
export interface OzonSellerInfo {
|
||||
id: number
|
||||
name: string
|
||||
status: string
|
||||
}
|
||||
|
||||
export class MarketplaceService {
|
||||
private wbApiUrl: string
|
||||
private ozonApiUrl: string
|
||||
|
||||
constructor() {
|
||||
this.wbApiUrl = process.env.WILDBERRIES_API_URL || 'https://common-api.wildberries.ru'
|
||||
this.ozonApiUrl = process.env.OZON_API_URL || 'https://api-seller.ozon.ru'
|
||||
}
|
||||
|
||||
/**
|
||||
* Валидирует API ключ Wildberries
|
||||
*/
|
||||
async validateWildberriesApiKey(apiKey: string): Promise<MarketplaceValidationResult> {
|
||||
try {
|
||||
// Пытаемся получить информацию о продавце
|
||||
const response = await axios.get(
|
||||
`${this.wbApiUrl}/api/v1/seller-info`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': apiKey,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000
|
||||
}
|
||||
)
|
||||
|
||||
if (response.status === 200 && response.data) {
|
||||
const sellerData = response.data
|
||||
|
||||
return {
|
||||
isValid: true,
|
||||
message: 'API ключ Wildberries валиден',
|
||||
data: {
|
||||
sellerId: sellerData.id?.toString(),
|
||||
sellerName: sellerData.name || sellerData.supplierName,
|
||||
inn: sellerData.inn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Не удалось получить информацию о продавце Wildberries'
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Wildberries API validation error:', error)
|
||||
|
||||
if (axios.isAxiosError(error)) {
|
||||
if (error.response?.status === 401) {
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Неверный API ключ Wildberries'
|
||||
}
|
||||
}
|
||||
|
||||
if (error.response?.status === 403) {
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Доступ запрещён. Проверьте права API ключа Wildberries'
|
||||
}
|
||||
}
|
||||
|
||||
if (error.code === 'ECONNABORTED') {
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Превышено время ожидания ответа от Wildberries API'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Ошибка при проверке API ключа Wildberries'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Валидирует API ключ Ozon
|
||||
*/
|
||||
async validateOzonApiKey(apiKey: string, clientId?: string): Promise<MarketplaceValidationResult> {
|
||||
try {
|
||||
// Для Ozon нужен Client-Id
|
||||
if (!clientId) {
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Для Ozon API требуется Client-Id'
|
||||
}
|
||||
}
|
||||
|
||||
// Пытаемся получить информацию о продавце
|
||||
const response = await axios.post(
|
||||
`${this.ozonApiUrl}/v1/seller/info`,
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
'Api-Key': apiKey,
|
||||
'Client-Id': clientId,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000
|
||||
}
|
||||
)
|
||||
|
||||
if (response.status === 200 && response.data?.result) {
|
||||
const sellerData = response.data.result as OzonSellerInfo
|
||||
|
||||
return {
|
||||
isValid: true,
|
||||
message: 'API ключ Ozon валиден',
|
||||
data: {
|
||||
sellerId: sellerData.id?.toString(),
|
||||
sellerName: sellerData.name,
|
||||
status: sellerData.status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Не удалось получить информацию о продавце Ozon'
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Ozon API validation error:', error)
|
||||
|
||||
if (axios.isAxiosError(error)) {
|
||||
if (error.response?.status === 401) {
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Неверный API ключ или Client-Id для Ozon'
|
||||
}
|
||||
}
|
||||
|
||||
if (error.response?.status === 403) {
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Доступ запрещён. Проверьте права API ключа Ozon'
|
||||
}
|
||||
}
|
||||
|
||||
if (error.code === 'ECONNABORTED') {
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Превышено время ожидания ответа от Ozon API'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Ошибка при проверке API ключа Ozon'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Общий метод валидации API ключа по типу маркетплейса
|
||||
*/
|
||||
async validateApiKey(
|
||||
marketplace: 'WILDBERRIES' | 'OZON',
|
||||
apiKey: string,
|
||||
clientId?: string
|
||||
): Promise<MarketplaceValidationResult> {
|
||||
switch (marketplace) {
|
||||
case 'WILDBERRIES':
|
||||
return this.validateWildberriesApiKey(apiKey)
|
||||
case 'OZON':
|
||||
return this.validateOzonApiKey(apiKey, clientId)
|
||||
default:
|
||||
return {
|
||||
isValid: false,
|
||||
message: 'Неподдерживаемый тип маркетплейса'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет формат API ключа перед отправкой запроса
|
||||
*/
|
||||
validateApiKeyFormat(marketplace: 'WILDBERRIES' | 'OZON', apiKey: string): boolean {
|
||||
if (!apiKey || typeof apiKey !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
switch (marketplace) {
|
||||
case 'WILDBERRIES':
|
||||
// Wildberries API ключи обычно содержат буквы, цифры и дефисы
|
||||
return /^[a-zA-Z0-9\-_]{10,}$/.test(apiKey)
|
||||
case 'OZON':
|
||||
// Ozon API ключи обычно содержат буквы, цифры и дефисы
|
||||
return /^[a-zA-Z0-9\-_]{10,}$/.test(apiKey)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user