правильный запрос и парс данных
This commit is contained in:
parent
1ee85347ee
commit
a1ac81e793
@ -79,16 +79,28 @@ export const publicationMakeRequest = ({ url, body }: PublicationMakeRequestPara
|
|||||||
let globalStatus: string | null = null;
|
let globalStatus: string | null = null;
|
||||||
let isFirstRequest = true;
|
let isFirstRequest = true;
|
||||||
|
|
||||||
export async function getData({ quizId }: { quizId: string }): Promise<{
|
/*
|
||||||
|
если запросить 0 вопросов - придёт items: null
|
||||||
|
если не запрашивать конфиг - поле конфига вообще не придёт
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface GetDataProps {
|
||||||
|
quizId: string;
|
||||||
|
limit: number;
|
||||||
|
page: number;
|
||||||
|
needConfig: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getData({ quizId, limit, page, needConfig }: GetDataProps): Promise<{
|
||||||
data: GetQuizDataResponse | null;
|
data: GetQuizDataResponse | null;
|
||||||
isRecentlyCompleted: boolean;
|
isRecentlyCompleted: boolean;
|
||||||
error?: AxiosError;
|
error?: AxiosError;
|
||||||
}> {
|
}> {
|
||||||
const body = {
|
const body = {
|
||||||
quiz_id: quizId,
|
quiz_id: quizId,
|
||||||
limit: 100,
|
limit,
|
||||||
page: 0,
|
page,
|
||||||
need_config: true,
|
need_config: needConfig,
|
||||||
} as any;
|
} as any;
|
||||||
if (paudParam) body.auditory = Number(paudParam);
|
if (paudParam) body.auditory = Number(paudParam);
|
||||||
|
|
||||||
@ -111,7 +123,12 @@ export async function getData({ quizId }: { quizId: string }): Promise<{
|
|||||||
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
||||||
|
|
||||||
//Тут ещё проверка на антифрод без парса конфига. Нам не интересно время если не нужно запрещать проходить чаще чем в сутки
|
//Тут ещё проверка на антифрод без парса конфига. Нам не интересно время если не нужно запрещать проходить чаще чем в сутки
|
||||||
if (typeof sessions[quizId] === "number" && data.settings.cfg.includes('antifraud":true')) {
|
if (
|
||||||
|
needConfig &&
|
||||||
|
data?.settings !== undefined &&
|
||||||
|
typeof sessions[quizId] === "number" &&
|
||||||
|
data.settings.cfg.includes('antifraud":true')
|
||||||
|
) {
|
||||||
// unix время. Если меньше суток прошло - выводить ошибку, иначе пустить дальше
|
// unix время. Если меньше суток прошло - выводить ошибку, иначе пустить дальше
|
||||||
if (Date.now() - sessions[quizId] < 86400000) {
|
if (Date.now() - sessions[quizId] < 86400000) {
|
||||||
return { data, isRecentlyCompleted: true };
|
return { data, isRecentlyCompleted: true };
|
||||||
@ -128,113 +145,10 @@ export async function getData({ quizId }: { quizId: string }): Promise<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDataSingle({ quizId, page }: { quizId: string; page?: number }): Promise<{
|
export async function getAndParceData(props: GetDataProps) {
|
||||||
data: GetQuizDataResponse | null;
|
if (!props.quizId) throw new Error("No quiz id");
|
||||||
isRecentlyCompleted: boolean;
|
|
||||||
error?: AxiosError;
|
|
||||||
}> {
|
|
||||||
try {
|
|
||||||
// Первый запрос: 1 вопрос + конфиг
|
|
||||||
if (isFirstRequest) {
|
|
||||||
const { data, headers } = await axios<GetQuizDataResponse>(
|
|
||||||
domain + `/answer/v1.0.0/settings${window.location.search}`,
|
|
||||||
{
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"X-Sessionkey": SESSIONS,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
DeviceType: DeviceType,
|
|
||||||
Device: Device,
|
|
||||||
OS: OSDevice,
|
|
||||||
Browser: userAgent,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
quiz_id: quizId,
|
|
||||||
limit: 1,
|
|
||||||
page: 0,
|
|
||||||
need_config: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
globalStatus = data.settings.status;
|
const response = await getData(props);
|
||||||
isFirstRequest = false;
|
|
||||||
SESSIONS = headers["x-sessionkey"] || SESSIONS;
|
|
||||||
|
|
||||||
// Проверка антифрода
|
|
||||||
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
|
||||||
if (typeof sessions[quizId] === "number" && data.settings.cfg.includes('antifraud":true')) {
|
|
||||||
if (Date.now() - sessions[quizId] < 86400000) {
|
|
||||||
return { data, isRecentlyCompleted: true };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если статус не AI - сразу делаем запрос за всеми вопросами
|
|
||||||
if (globalStatus !== "ai") {
|
|
||||||
const secondResponse = await axios<GetQuizDataResponse>(
|
|
||||||
domain + `/answer/v1.0.0/settings${window.location.search}`,
|
|
||||||
{
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"X-Sessionkey": SESSIONS,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
DeviceType: DeviceType,
|
|
||||||
Device: Device,
|
|
||||||
OS: OSDevice,
|
|
||||||
Browser: userAgent,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
quiz_id: quizId,
|
|
||||||
limit: 100,
|
|
||||||
page: 0,
|
|
||||||
need_config: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
data: { ...data, items: secondResponse.data.items },
|
|
||||||
isRecentlyCompleted: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return { data, isRecentlyCompleted: false };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Последующие запросы
|
|
||||||
const response = await axios<GetQuizDataResponse>(domain + `/answer/v1.0.0/settings${window.location.search}`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"X-Sessionkey": SESSIONS,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
DeviceType: DeviceType,
|
|
||||||
Device: Device,
|
|
||||||
OS: OSDevice,
|
|
||||||
Browser: userAgent,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
quiz_id: quizId,
|
|
||||||
limit: 1,
|
|
||||||
page: page,
|
|
||||||
need_config: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
data: response.data,
|
|
||||||
isRecentlyCompleted: false,
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
isRecentlyCompleted: false,
|
|
||||||
error: error as AxiosError,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export async function getQuizData({ quizId, status = "" }: { quizId: string; status?: string }) {
|
|
||||||
if (!quizId) throw new Error("No quiz id");
|
|
||||||
|
|
||||||
const response = await getData({ quizId });
|
|
||||||
const quizDataResponse = response.data;
|
const quizDataResponse = response.data;
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
@ -252,8 +166,10 @@ export async function getQuizData({ quizId, status = "" }: { quizId: string; sta
|
|||||||
throw new Error("Quiz not found");
|
throw new Error("Quiz not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Парсим строки в строках
|
||||||
const quizSettings = replaceSpacesToEmptyLines(parseQuizData(quizDataResponse));
|
const quizSettings = replaceSpacesToEmptyLines(parseQuizData(quizDataResponse));
|
||||||
|
|
||||||
|
//Единоразово стрингифаим ВСЁ распаршенное и удаляем лишние пробелы
|
||||||
const res = JSON.parse(
|
const res = JSON.parse(
|
||||||
JSON.stringify({ data: quizSettings })
|
JSON.stringify({ data: quizSettings })
|
||||||
.replaceAll(/\\" \\"/g, '""')
|
.replaceAll(/\\" \\"/g, '""')
|
||||||
@ -263,124 +179,6 @@ export async function getQuizData({ quizId, status = "" }: { quizId: string; sta
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
let page = 1;
|
|
||||||
|
|
||||||
export async function getQuizDataAI(quizId: string) {
|
|
||||||
console.log("[getQuizDataAI] Starting with quizId:", quizId); // Добавлено
|
|
||||||
let maxRetries = 50;
|
|
||||||
|
|
||||||
if (!quizId) {
|
|
||||||
console.error("[getQuizDataAI] Error: No quiz id provided");
|
|
||||||
throw new Error("No quiz id");
|
|
||||||
}
|
|
||||||
|
|
||||||
let lastError: Error | null = null;
|
|
||||||
let responseData: any = null;
|
|
||||||
|
|
||||||
// Первый цикл - обработка result вопросов
|
|
||||||
console.log("[getQuizDataAI] Starting result retries loop"); // Добавлено
|
|
||||||
let resultRetryCount = 0;
|
|
||||||
while (resultRetryCount < maxRetries) {
|
|
||||||
try {
|
|
||||||
console.log(`[getQuizDataAI] Attempt ${resultRetryCount + 1} for result questions, page: ${page}`);
|
|
||||||
const response = await getData({ quizId });
|
|
||||||
console.log("[getQuizDataAI] Response from getData:", response);
|
|
||||||
|
|
||||||
if (response.error) {
|
|
||||||
console.error("[getQuizDataAI] Error in response:", response.error);
|
|
||||||
throw response.error;
|
|
||||||
}
|
|
||||||
if (!response.data) {
|
|
||||||
console.error("[getQuizDataAI] Error: Quiz not found");
|
|
||||||
throw new Error("Quiz not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasAiResult = response.data.items.some((item) => item.typ === "result");
|
|
||||||
console.log("[getQuizDataAI] Has AI result:", hasAiResult);
|
|
||||||
|
|
||||||
if (hasAiResult) {
|
|
||||||
page++;
|
|
||||||
resultRetryCount++;
|
|
||||||
console.log(`[getQuizDataAI] Found result question, incrementing page to ${page}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
responseData = response;
|
|
||||||
console.log("[getQuizDataAI] Found non-result questions, breaking loop");
|
|
||||||
break;
|
|
||||||
} catch (error) {
|
|
||||||
lastError = error as Error;
|
|
||||||
resultRetryCount++;
|
|
||||||
console.error(`[getQuizDataAI] Error in attempt ${resultRetryCount}:`, error);
|
|
||||||
|
|
||||||
if (resultRetryCount >= maxRetries) {
|
|
||||||
console.error("[getQuizDataAI] Max retries reached for result questions");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const delay = 1500 * resultRetryCount;
|
|
||||||
console.log(`[getQuizDataAI] Waiting ${delay}ms before next retry`);
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!responseData) {
|
|
||||||
console.error("[getQuizDataAI] Failed after result retries, throwing error");
|
|
||||||
throw lastError || new Error("Failed to get quiz data after result retries");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Второй цикл - обработка пустого массива
|
|
||||||
console.log("[getQuizDataAI] Starting empty items retry loop"); // Добавлено
|
|
||||||
let isEmpty = !responseData.data?.items.length;
|
|
||||||
let emptyRetryCount = 0;
|
|
||||||
|
|
||||||
while (isEmpty && emptyRetryCount < maxRetries) {
|
|
||||||
try {
|
|
||||||
console.log(`[getQuizDataAI] Empty items retry ${emptyRetryCount + 1}`);
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
||||||
const response = await getData({ quizId });
|
|
||||||
|
|
||||||
if (response.error) {
|
|
||||||
console.error("[getQuizDataAI] Error in empty items check:", response.error);
|
|
||||||
throw response.error;
|
|
||||||
}
|
|
||||||
if (!response.data) {
|
|
||||||
console.error("[getQuizDataAI] Error: Quiz not found in empty check");
|
|
||||||
throw new Error("Quiz not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
isEmpty = !response.data.items.length;
|
|
||||||
console.log("[getQuizDataAI] Is items empty:", isEmpty);
|
|
||||||
|
|
||||||
if (!isEmpty) {
|
|
||||||
responseData = response;
|
|
||||||
console.log("[getQuizDataAI] Found non-empty items, updating responseData");
|
|
||||||
}
|
|
||||||
emptyRetryCount++;
|
|
||||||
} catch (error) {
|
|
||||||
lastError = error as Error;
|
|
||||||
emptyRetryCount++;
|
|
||||||
console.error(`[getQuizDataAI] Error in empty check attempt ${emptyRetryCount}:`, error);
|
|
||||||
|
|
||||||
if (emptyRetryCount >= maxRetries) {
|
|
||||||
console.error("[getQuizDataAI] Max empty retries reached");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEmpty) {
|
|
||||||
console.error("[getQuizDataAI] Items still empty after retries");
|
|
||||||
throw new Error("Items array is empty after maximum retries");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Финальная обработка
|
|
||||||
console.log("[getQuizDataAI] Processing final response data");
|
|
||||||
|
|
||||||
console.log("[getQuizDataAI] Final response before return:", responseData);
|
|
||||||
return responseData.data.items;
|
|
||||||
}
|
|
||||||
|
|
||||||
type SendAnswerProps = {
|
type SendAnswerProps = {
|
||||||
questionId: string;
|
questionId: string;
|
||||||
body: string | string[];
|
body: string | string[];
|
||||||
@ -389,8 +187,6 @@ type SendAnswerProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function sendAnswer({ questionId, body, qid, preview = false }: SendAnswerProps) {
|
export function sendAnswer({ questionId, body, qid, preview = false }: SendAnswerProps) {
|
||||||
console.log("qid");
|
|
||||||
console.log(qid);
|
|
||||||
if (preview) return;
|
if (preview) return;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { QuizSettings } from "@model/settingsData";
|
|||||||
|
|
||||||
export interface GetQuizDataResponse {
|
export interface GetQuizDataResponse {
|
||||||
cnt: number;
|
cnt: number;
|
||||||
settings: {
|
settings?: {
|
||||||
fp: boolean;
|
fp: boolean;
|
||||||
rep: boolean;
|
rep: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
@ -27,6 +27,13 @@ export interface GetQuizDataResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function parseQuizData(quizDataResponse: GetQuizDataResponse): Omit<QuizSettings, "recentlyCompleted"> {
|
export function parseQuizData(quizDataResponse: GetQuizDataResponse): Omit<QuizSettings, "recentlyCompleted"> {
|
||||||
|
const readyData = {
|
||||||
|
cnt: quizDataResponse.cnt,
|
||||||
|
show_badge: quizDataResponse.show_badge,
|
||||||
|
settings: {} as QuizSettings["settings"],
|
||||||
|
questions: [] as QuizSettings["questions"],
|
||||||
|
} as QuizSettings;
|
||||||
|
|
||||||
const items: QuizSettings["questions"] = quizDataResponse.items.map((item) => {
|
const items: QuizSettings["questions"] = quizDataResponse.items.map((item) => {
|
||||||
const content = JSON.parse(item.c);
|
const content = JSON.parse(item.c);
|
||||||
|
|
||||||
@ -41,7 +48,10 @@ export function parseQuizData(quizDataResponse: GetQuizDataResponse): Omit<QuizS
|
|||||||
} as unknown as AnyTypedQuizQuestion;
|
} as unknown as AnyTypedQuizQuestion;
|
||||||
});
|
});
|
||||||
|
|
||||||
const settings: QuizSettings["settings"] = {
|
readyData.questions = items;
|
||||||
|
|
||||||
|
if (quizDataResponse?.settings !== undefined) {
|
||||||
|
readyData.settings = {
|
||||||
fp: quizDataResponse.settings.fp,
|
fp: quizDataResponse.settings.fp,
|
||||||
rep: quizDataResponse.settings.rep,
|
rep: quizDataResponse.settings.rep,
|
||||||
name: quizDataResponse.settings.name,
|
name: quizDataResponse.settings.name,
|
||||||
@ -52,6 +62,7 @@ export function parseQuizData(quizDataResponse: GetQuizDataResponse): Omit<QuizS
|
|||||||
pausable: quizDataResponse.settings.pausable,
|
pausable: quizDataResponse.settings.pausable,
|
||||||
status: quizDataResponse.settings.status,
|
status: quizDataResponse.settings.status,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return { cnt: quizDataResponse.cnt, settings, questions: items, show_badge: quizDataResponse.show_badge };
|
return readyData;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user