Fix catalog items missing due to page_id VARCHAR mismatch.
Local Build and Deploy / deploy (push) Successful in 56s
Local Build and Deploy / deploy (push) Successful in 56s
Use raw SQL for counts/loads/creates/moves so Habbo DBs with VARCHAR page_id and no AUTO_INCREMENT still show and persist furni. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
33a8a19820
commit
7bc0845932
6 files changed
+139
-79
No files matched your search
@@ -4,6 +4,7 @@ import { Prisma } from "@/generated/prisma/client";
|
||||
import { calcPagination, parseListParams } from "@/lib/admin-helpers";
|
||||
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { getCatalogItemCounts } from "@/lib/services/catalog-tree";
|
||||
import { CatalogActions } from "./catalog-actions";
|
||||
import { CatalogManagerDialog } from "./catalog-manager-dialog-wrapper";
|
||||
import { CatalogTable } from "./catalog-table";
|
||||
@@ -238,7 +239,7 @@ export default async function CatalogPagesPage({
|
||||
orderBy: { orderNum: "asc" },
|
||||
});
|
||||
const rootIds = rootPagesRaw.map((p) => p.id);
|
||||
const [rootChildCounts, rootItemCounts] = await Promise.all([
|
||||
const [rootChildCounts, rootItemCountMap] = await Promise.all([
|
||||
rootIds.length > 0
|
||||
? prisma.catalogPages.groupBy({
|
||||
by: ["parentId"],
|
||||
@@ -246,22 +247,12 @@ export default async function CatalogPagesPage({
|
||||
_count: true,
|
||||
})
|
||||
: [],
|
||||
rootIds.length > 0
|
||||
? prisma.catalogItems
|
||||
.groupBy({
|
||||
by: ["pageId"],
|
||||
where: { pageId: { in: rootIds } },
|
||||
_count: true,
|
||||
})
|
||||
.catch(() => [])
|
||||
: [],
|
||||
getCatalogItemCounts(rootIds),
|
||||
]);
|
||||
const rootChildMap = Object.fromEntries(
|
||||
rootChildCounts.map((c) => [c.parentId, c._count]),
|
||||
);
|
||||
const rootItemMap = Object.fromEntries(
|
||||
rootItemCounts.map((c) => [c.pageId, c._count]),
|
||||
);
|
||||
const rootItemMap = Object.fromEntries(rootItemCountMap);
|
||||
const rootPages: TreeNodeShape[] = rootPagesRaw.map((p) => ({
|
||||
id: p.id,
|
||||
caption: p.caption,
|
||||
@@ -301,16 +292,16 @@ export default async function CatalogPagesPage({
|
||||
if (search) {
|
||||
const searchPattern = `%${search}%`;
|
||||
const parentClause = hasParent
|
||||
? Prisma.sql`AND cp.parentId = ${parentId}`
|
||||
? Prisma.sql`AND cp.parent_id = ${parentId}`
|
||||
: Prisma.empty;
|
||||
|
||||
const matchedIds = await prisma.$queryRaw<{ id: number }[]>(Prisma.sql`
|
||||
SELECT DISTINCT cp.id FROM catalog_pages cp
|
||||
LEFT JOIN catalog_items ci ON ci.pageId = cp.id
|
||||
LEFT JOIN items_base ib ON FIND_IN_SET(ib.id, REPLACE(ci.itemIds, ';', ','))
|
||||
LEFT JOIN catalog_items ci ON CAST(ci.page_id AS CHAR) = CAST(cp.id AS CHAR)
|
||||
LEFT JOIN items_base ib ON FIND_IN_SET(ib.id, REPLACE(ci.item_ids, ';', ','))
|
||||
WHERE (cp.caption LIKE ${searchPattern}
|
||||
OR cp.pageLayout LIKE ${searchPattern}
|
||||
OR ci.catalogName LIKE ${searchPattern}
|
||||
OR cp.page_layout LIKE ${searchPattern}
|
||||
OR ci.catalog_name LIKE ${searchPattern}
|
||||
OR ib.public_name LIKE ${searchPattern}
|
||||
OR ib.item_name LIKE ${searchPattern})
|
||||
${parentClause}
|
||||
@@ -339,7 +330,7 @@ export default async function CatalogPagesPage({
|
||||
const parentIds = [
|
||||
...new Set(pages.map((p) => p.parentId).filter((id) => id > 0)),
|
||||
];
|
||||
const [childCounts, itemCounts, parentPages] = await Promise.all([
|
||||
const [childCounts, itemCountMapRaw, parentPages] = await Promise.all([
|
||||
pageIds.length > 0
|
||||
? prisma.catalogPages.groupBy({
|
||||
by: ["parentId"],
|
||||
@@ -347,13 +338,7 @@ export default async function CatalogPagesPage({
|
||||
_count: true,
|
||||
})
|
||||
: [],
|
||||
pageIds.length > 0
|
||||
? prisma.catalogItems.groupBy({
|
||||
by: ["pageId"],
|
||||
where: { pageId: { in: pageIds } },
|
||||
_count: true,
|
||||
})
|
||||
: [],
|
||||
getCatalogItemCounts(pageIds),
|
||||
parentIds.length > 0
|
||||
? prisma.catalogPages.findMany({
|
||||
where: { id: { in: parentIds } },
|
||||
@@ -364,9 +349,7 @@ export default async function CatalogPagesPage({
|
||||
const childCountMap = Object.fromEntries(
|
||||
childCounts.map((c) => [c.parentId, c._count]),
|
||||
);
|
||||
const itemCountMap = Object.fromEntries(
|
||||
itemCounts.map((c) => [c.pageId, c._count]),
|
||||
);
|
||||
const itemCountMap = Object.fromEntries(itemCountMapRaw);
|
||||
const parentNameMap = Object.fromEntries(
|
||||
parentPages.map((p) => [p.id, p.caption]),
|
||||
);
|
||||
|
||||
@@ -3,6 +3,12 @@ import { apiError, apiOk } from "@/lib/api-response";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { loadCatalogItemsData } from "@/lib/services/catalog-items-loader";
|
||||
|
||||
function jsonSafe<T>(data: T): T {
|
||||
return JSON.parse(
|
||||
JSON.stringify(data, (_k, v) => (typeof v === "bigint" ? Number(v) : v)),
|
||||
) as T;
|
||||
}
|
||||
|
||||
export const GET = withAdmin(
|
||||
{ permission: PERMS.CATALOG_VIEW },
|
||||
async (request) => {
|
||||
@@ -11,6 +17,6 @@ export const GET = withAdmin(
|
||||
return apiError("Invalid pageId");
|
||||
}
|
||||
const data = await loadCatalogItemsData(pageId);
|
||||
return apiOk(data as unknown as Record<string, unknown>);
|
||||
return apiOk(jsonSafe(data) as unknown as Record<string, unknown>);
|
||||
},
|
||||
);
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
deletePage,
|
||||
getAncestors,
|
||||
getTreeFlat,
|
||||
safeItemCounts,
|
||||
getCatalogItemCounts,
|
||||
toInt,
|
||||
} from "@/lib/services/catalog-tree";
|
||||
import { rcon } from "@/lib/services/rcon";
|
||||
@@ -158,7 +158,7 @@ async function getChildren(
|
||||
_count: true,
|
||||
})
|
||||
: Promise.resolve([]),
|
||||
safeItemCounts(ids),
|
||||
getCatalogItemCounts(ids),
|
||||
]);
|
||||
const childMap = Object.fromEntries(
|
||||
childCounts.map((c) => [toInt(c.parentId), c._count]),
|
||||
@@ -234,7 +234,7 @@ async function searchPages(q: string, isBc: boolean): Promise<TreeNode[]> {
|
||||
_count: true,
|
||||
})
|
||||
: Promise.resolve([]),
|
||||
safeItemCounts(ids),
|
||||
getCatalogItemCounts(ids),
|
||||
]);
|
||||
const childMap = Object.fromEntries(
|
||||
childCounts.map((c) => [toInt(c.parentId), c._count]),
|
||||
|
||||
Reference in new issue
Block a user