|
|
@@ -1,5 +1,10 @@
|
|
|
import { apiPost } from "@/lib/api";
|
|
|
import { normalizeAssetUrl, toAbsoluteFileUrl } from "@/lib/media-url";
|
|
|
+import {
|
|
|
+ applyClientPageSlice,
|
|
|
+ extractPageMeta,
|
|
|
+ type PageMetaRaw,
|
|
|
+} from "@/lib/page-meta";
|
|
|
|
|
|
export type GoodsType = 1 | 2 | 3 | 4 | 5;
|
|
|
export type CustomType = 0 | 1 | 2;
|
|
|
@@ -188,12 +193,7 @@ type GoodsSearchListResponse = {
|
|
|
};
|
|
|
list?: GoodsSearchListItem[];
|
|
|
records?: GoodsSearchListItem[];
|
|
|
- page?: {
|
|
|
- current?: number;
|
|
|
- row?: number;
|
|
|
- size?: number;
|
|
|
- total?: number;
|
|
|
- };
|
|
|
+ page?: PageMetaRaw;
|
|
|
};
|
|
|
|
|
|
type GoodsVideoListItem = {
|
|
|
@@ -223,12 +223,7 @@ type GoodsVideoListResponse = {
|
|
|
};
|
|
|
list?: GoodsVideoListItem[];
|
|
|
records?: GoodsVideoListItem[];
|
|
|
- page?: {
|
|
|
- current?: number;
|
|
|
- row?: number;
|
|
|
- size?: number;
|
|
|
- total?: number;
|
|
|
- };
|
|
|
+ page?: PageMetaRaw;
|
|
|
};
|
|
|
|
|
|
function toCategory(goodsType: GoodsType): CourseCategory {
|
|
|
@@ -396,36 +391,6 @@ function normalizeVideo(item: GoodsVideoListItem): CourseVideo | null {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
-function extractVideoPage(payload: GoodsVideoListResponse): {
|
|
|
- current: number;
|
|
|
- row: number;
|
|
|
- total: number;
|
|
|
-} {
|
|
|
- const current = Number(payload.page?.current);
|
|
|
- const row = Number(payload.page?.row ?? payload.page?.size);
|
|
|
- const total = Number(payload.page?.total);
|
|
|
- return {
|
|
|
- current: Number.isFinite(current) && current > 0 ? current : 1,
|
|
|
- row: Number.isFinite(row) && row > 0 ? row : 10,
|
|
|
- total: Number.isFinite(total) && total >= 0 ? total : 0,
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-function extractSearchPage(payload: GoodsSearchListResponse): {
|
|
|
- current: number;
|
|
|
- row: number;
|
|
|
- total: number;
|
|
|
-} {
|
|
|
- const current = Number(payload.page?.current);
|
|
|
- const row = Number(payload.page?.row ?? payload.page?.size);
|
|
|
- const total = Number(payload.page?.total);
|
|
|
- return {
|
|
|
- current: Number.isFinite(current) && current > 0 ? current : 1,
|
|
|
- row: Number.isFinite(row) && row > 0 ? row : 10,
|
|
|
- total: Number.isFinite(total) && total >= 0 ? total : 0,
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
function parseDownloadUrls(rawDownload: unknown): string[] {
|
|
|
if (typeof rawDownload !== "string") return [];
|
|
|
const input = rawDownload.trim();
|
|
|
@@ -515,15 +480,21 @@ export async function fetchCoursesPaged(
|
|
|
page: { current, row },
|
|
|
},
|
|
|
);
|
|
|
- const list = extractList(payload)
|
|
|
- .map(normalizeCourse)
|
|
|
- .filter((c): c is Course => c !== null);
|
|
|
- const serverPage = extractSearchPage(payload);
|
|
|
+ const serverPage = extractPageMeta(payload.page, { current, row });
|
|
|
+ const pageCurrent = serverPage.current || current;
|
|
|
+ const pageRow = serverPage.row || row;
|
|
|
+ const list = applyClientPageSlice(
|
|
|
+ extractList(payload)
|
|
|
+ .map(normalizeCourse)
|
|
|
+ .filter((c): c is Course => c !== null),
|
|
|
+ pageCurrent,
|
|
|
+ pageRow,
|
|
|
+ );
|
|
|
return {
|
|
|
list,
|
|
|
page: {
|
|
|
- current: serverPage.current || current,
|
|
|
- row: serverPage.row || row,
|
|
|
+ current: pageCurrent,
|
|
|
+ row: pageRow,
|
|
|
total: serverPage.total || list.length,
|
|
|
},
|
|
|
};
|
|
|
@@ -560,17 +531,22 @@ export async function fetchCourseVideos(
|
|
|
page: { current, row },
|
|
|
},
|
|
|
);
|
|
|
- const list = extractVideoList(payload)
|
|
|
- .map(normalizeVideo)
|
|
|
- .filter((v): v is CourseVideo => v !== null)
|
|
|
- .slice(0, 10);
|
|
|
- const serverPage = extractVideoPage(payload);
|
|
|
+ const serverPage = extractPageMeta(payload.page, { current, row });
|
|
|
+ const pageCurrent = serverPage.current || current;
|
|
|
+ const pageRow = serverPage.row || row;
|
|
|
+ const list = applyClientPageSlice(
|
|
|
+ extractVideoList(payload)
|
|
|
+ .map(normalizeVideo)
|
|
|
+ .filter((v): v is CourseVideo => v !== null),
|
|
|
+ pageCurrent,
|
|
|
+ pageRow,
|
|
|
+ );
|
|
|
return {
|
|
|
list,
|
|
|
page: {
|
|
|
- current: serverPage.current || current,
|
|
|
- row: serverPage.row || row,
|
|
|
- total: serverPage.total || (current - 1) * row + list.length,
|
|
|
+ current: pageCurrent,
|
|
|
+ row: pageRow,
|
|
|
+ total: serverPage.total || list.length,
|
|
|
},
|
|
|
};
|
|
|
} catch {
|
|
|
@@ -596,13 +572,19 @@ export async function fetchCourseFiles(
|
|
|
goodsId: normalizedGoodsId,
|
|
|
page: { current, row },
|
|
|
});
|
|
|
- const finalList = extractVideoList(payload).flatMap(normalizeFileFromVideo);
|
|
|
- const serverPage = extractVideoPage(payload);
|
|
|
+ const serverPage = extractPageMeta(payload.page, { current, row });
|
|
|
+ const pageCurrent = serverPage.current || current;
|
|
|
+ const pageRow = serverPage.row || row;
|
|
|
+ const finalList = applyClientPageSlice(
|
|
|
+ extractVideoList(payload).flatMap(normalizeFileFromVideo),
|
|
|
+ pageCurrent,
|
|
|
+ pageRow,
|
|
|
+ );
|
|
|
return {
|
|
|
list: finalList,
|
|
|
page: {
|
|
|
- current: serverPage.current || current,
|
|
|
- row: serverPage.row || row,
|
|
|
+ current: pageCurrent,
|
|
|
+ row: pageRow,
|
|
|
total: serverPage.total || finalList.length,
|
|
|
},
|
|
|
};
|