组件库

This commit is contained in:
龟男日记\www 2026-02-23 02:31:11 +08:00
parent c6771a7098
commit b90005038f
15 changed files with 6702 additions and 17 deletions

9
scripts/check-db.ts Normal file
View File

@ -0,0 +1,9 @@
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const { Pool } = require('d:/Project/gbmake/gb-payload/node_modules/.pnpm/pg@8.16.3/node_modules/pg')
const pool = new Pool({ connectionString: 'postgres://gb-payload:123123@localhost/gb-payload' })
const t = await pool.query(`SELECT tablename FROM pg_tables WHERE schemaname='public' AND tablename LIKE 'disassem%' ORDER BY tablename`)
console.log('Disassembly tables:', t.rows.map((r: any) => r.tablename))
const m = await pool.query('SELECT name FROM payload_migrations ORDER BY id')
console.log('Migrations:', m.rows.map((r: any) => r.name))
await pool.end()

211
scripts/fix-migrations.ts Normal file
View File

@ -0,0 +1,211 @@
/**
* Fix script: Re-insert historical migration records and apply new migration
* using a direct pg connection (no Payload init to avoid dev-mode push loops).
*
* Run with: pnpm tsx --env-file=.env scripts/fix-migrations.ts
*/
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const { Pool } = require(
'd:/Project/gbmake/gb-payload/node_modules/.pnpm/pg@8.16.3/node_modules/pg'
)
const pool = new Pool({
connectionString: process.env.DATABASE_URL ?? 'postgres://gb-payload:123123@localhost/gb-payload',
})
async function run(sql: string, params: any[] = []) {
const result = await pool.query(sql, params)
return result.rows
}
// ── Check current migration state ────────────────────────────────────────────
console.log('📋 Checking payload_migrations table...')
const existing = await run(`SELECT name FROM payload_migrations ORDER BY id`)
const existingNames = new Set(existing.map((r: any) => r.name))
console.log('Currently recorded:', existingNames.size > 0 ? [...existingNames] : '(none)')
// ── Mark all historical migrations as done ────────────────────────────────────
const historyMigrations = [
'20260208_171142',
'20260212_193303',
'20260212_202303',
'20260222_170233',
'hero_slider_simplify',
'product_recommendations_simplify',
]
for (const name of historyMigrations) {
if (!existingNames.has(name)) {
await run(
`INSERT INTO payload_migrations (name, batch, updated_at, created_at) VALUES ($1, 1, now(), now())`,
[name]
)
console.log(`✅ Marked done: ${name}`)
} else {
console.log(`⏭️ Already recorded: ${name}`)
}
}
// ── Skip if new migration already applied ─────────────────────────────────────
if (existingNames.has('20260223_disassembly_refactor')) {
console.log('\n⏭ Migration 20260223_disassembly_refactor already applied.')
await pool.end()
process.exit(0)
}
// ── Show what disassembly tables exist ───────────────────────────────────────
const disasmTables = await run(
`SELECT tablename FROM pg_tables WHERE schemaname='public' AND tablename LIKE 'disassembly%' ORDER BY tablename`
)
console.log('\nCurrent disassembly tables:', disasmTables.map((r: any) => r.tablename))
console.log('\n🔧 Applying: 20260223_disassembly_refactor ...')
try {
// 1. disassembly_components
await run(`CREATE TABLE IF NOT EXISTS disassembly_components (
id serial PRIMARY KEY NOT NULL,
label varchar NOT NULL,
start_coordinate_x numeric DEFAULT 0 NOT NULL,
start_coordinate_y numeric DEFAULT 0 NOT NULL,
start_radius numeric DEFAULT 20 NOT NULL,
updated_at timestamp(3) with time zone DEFAULT now() NOT NULL,
created_at timestamp(3) with time zone DEFAULT now() NOT NULL
)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_updated_at_idx ON disassembly_components USING btree (updated_at)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_created_at_idx ON disassembly_components USING btree (created_at)`)
console.log(' ✅ disassembly_components')
// 2. disassembly_linked_products
await run(`CREATE TABLE IF NOT EXISTS disassembly_linked_products (
id serial PRIMARY KEY NOT NULL,
coordinate_x numeric DEFAULT 0 NOT NULL,
coordinate_y numeric DEFAULT 0 NOT NULL,
product_name varchar,
updated_at timestamp(3) with time zone DEFAULT now() NOT NULL,
created_at timestamp(3) with time zone DEFAULT now() NOT NULL
)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_updated_at_idx ON disassembly_linked_products USING btree (updated_at)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_created_at_idx ON disassembly_linked_products USING btree (created_at)`)
console.log(' ✅ disassembly_linked_products')
// 3. disassembly_components_rels
await run(`CREATE TABLE IF NOT EXISTS disassembly_components_rels (
id serial PRIMARY KEY NOT NULL,
"order" integer,
parent_id integer NOT NULL,
path varchar NOT NULL,
disassembly_linked_products_id integer
)`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_components_rels_parent_fk') THEN
ALTER TABLE disassembly_components_rels ADD CONSTRAINT disassembly_components_rels_parent_fk
FOREIGN KEY (parent_id) REFERENCES disassembly_components(id) ON DELETE cascade;
END IF;
END $$`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_components_rels_disassembly_linked_products_fk') THEN
ALTER TABLE disassembly_components_rels ADD CONSTRAINT disassembly_components_rels_disassembly_linked_products_fk
FOREIGN KEY (disassembly_linked_products_id) REFERENCES disassembly_linked_products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_rels_order_idx ON disassembly_components_rels USING btree ("order")`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_rels_parent_idx ON disassembly_components_rels USING btree (parent_id)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_rels_path_idx ON disassembly_components_rels USING btree (path)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_components_rels_disassembly_linked_products_id_idx ON disassembly_components_rels USING btree (disassembly_linked_products_id)`)
console.log(' ✅ disassembly_components_rels')
// 4. disassembly_linked_products_rels
await run(`CREATE TABLE IF NOT EXISTS disassembly_linked_products_rels (
id serial PRIMARY KEY NOT NULL,
"order" integer,
parent_id integer NOT NULL,
path varchar NOT NULL,
products_id integer,
preorder_products_id integer
)`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_linked_products_rels_parent_fk') THEN
ALTER TABLE disassembly_linked_products_rels ADD CONSTRAINT disassembly_linked_products_rels_parent_fk
FOREIGN KEY (parent_id) REFERENCES disassembly_linked_products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_linked_products_rels_products_fk') THEN
ALTER TABLE disassembly_linked_products_rels ADD CONSTRAINT disassembly_linked_products_rels_products_fk
FOREIGN KEY (products_id) REFERENCES products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_linked_products_rels_preorder_products_fk') THEN
ALTER TABLE disassembly_linked_products_rels ADD CONSTRAINT disassembly_linked_products_rels_preorder_products_fk
FOREIGN KEY (preorder_products_id) REFERENCES preorder_products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_order_idx ON disassembly_linked_products_rels USING btree ("order")`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_parent_idx ON disassembly_linked_products_rels USING btree (parent_id)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_path_idx ON disassembly_linked_products_rels USING btree (path)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_products_id_idx ON disassembly_linked_products_rels USING btree (products_id)`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_linked_products_rels_preorder_products_id_idx ON disassembly_linked_products_rels USING btree (preorder_products_id)`)
console.log(' ✅ disassembly_linked_products_rels')
// 5. Update disassembly_pages_rels
await run(`ALTER TABLE disassembly_pages_rels DROP CONSTRAINT IF EXISTS disassembly_pages_rels_products_fk`)
await run(`ALTER TABLE disassembly_pages_rels DROP CONSTRAINT IF EXISTS disassembly_pages_rels_preorder_products_fk`)
await run(`DROP INDEX IF EXISTS disassembly_pages_rels_products_id_idx`)
await run(`DROP INDEX IF EXISTS disassembly_pages_rels_preorder_products_id_idx`)
const pc = await run(`SELECT 1 FROM information_schema.columns WHERE table_name='disassembly_pages_rels' AND column_name='products_id'`)
if (pc.length > 0) await run(`ALTER TABLE disassembly_pages_rels DROP COLUMN products_id`)
const prc = await run(`SELECT 1 FROM information_schema.columns WHERE table_name='disassembly_pages_rels' AND column_name='preorder_products_id'`)
if (prc.length > 0) await run(`ALTER TABLE disassembly_pages_rels DROP COLUMN preorder_products_id`)
await run(`ALTER TABLE disassembly_pages_rels ADD COLUMN IF NOT EXISTS disassembly_components_id integer`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'disassembly_pages_rels_disassembly_components_fk') THEN
ALTER TABLE disassembly_pages_rels ADD CONSTRAINT disassembly_pages_rels_disassembly_components_fk
FOREIGN KEY (disassembly_components_id) REFERENCES disassembly_components(id) ON DELETE cascade;
END IF;
END $$`)
await run(`CREATE INDEX IF NOT EXISTS disassembly_pages_rels_disassembly_components_id_idx ON disassembly_pages_rels USING btree (disassembly_components_id)`)
console.log(' ✅ disassembly_pages_rels updated')
// 6. Update payload_locked_documents_rels
await run(`ALTER TABLE payload_locked_documents_rels ADD COLUMN IF NOT EXISTS disassembly_components_id integer`)
await run(`ALTER TABLE payload_locked_documents_rels ADD COLUMN IF NOT EXISTS disassembly_linked_products_id integer`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'payload_locked_documents_rels_disassembly_components_fk') THEN
ALTER TABLE payload_locked_documents_rels ADD CONSTRAINT payload_locked_documents_rels_disassembly_components_fk
FOREIGN KEY (disassembly_components_id) REFERENCES disassembly_components(id) ON DELETE cascade;
END IF;
END $$`)
await run(`DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'payload_locked_documents_rels_disassembly_linked_products_fk') THEN
ALTER TABLE payload_locked_documents_rels ADD CONSTRAINT payload_locked_documents_rels_disassembly_linked_products_fk
FOREIGN KEY (disassembly_linked_products_id) REFERENCES disassembly_linked_products(id) ON DELETE cascade;
END IF;
END $$`)
await run(`CREATE INDEX IF NOT EXISTS payload_locked_documents_rels_disassembly_components_id_idx ON payload_locked_documents_rels USING btree (disassembly_components_id)`)
await run(`CREATE INDEX IF NOT EXISTS payload_locked_documents_rels_disassembly_linked_products_id_idx ON payload_locked_documents_rels USING btree (disassembly_linked_products_id)`)
console.log(' ✅ payload_locked_documents_rels updated')
// 7. Drop old array tables
await run(`DROP TABLE IF EXISTS disassembly_pages_components_linked_products CASCADE`)
await run(`DROP TABLE IF EXISTS disassembly_pages_components CASCADE`)
console.log(' ✅ Old array tables dropped')
// 8. Record migration
await run(
`INSERT INTO payload_migrations (name, batch, updated_at, created_at) VALUES ($1, 2, now(), now())`,
['20260223_disassembly_refactor']
)
console.log('\n🎉 Migration 20260223_disassembly_refactor applied successfully!')
} catch (err: any) {
console.error('\n❌ Error:', err?.message ?? err)
await pool.end()
process.exit(1)
}
await pool.end()
process.exit(0)

View File

@ -95,9 +95,9 @@ export async function GET(req: NextRequest) {
orderCount: totalCount, orderCount: totalCount,
startDate: product.preorderStartDate, startDate: product.preorderStartDate,
endDate: product.preorderEndDate, endDate: product.preorderEndDate,
// 计算进度百分比(含 fakeOrderCount用于展示 // 计算进度百分比(含 fakeOrderCount用于展示,不限制 100 以支持超出显示
progress: product.fundingGoal > 0 progress: product.fundingGoal > 0
? Math.min(Math.round((totalCount / product.fundingGoal) * 100), 100) ? Math.round((totalCount / product.fundingGoal) * 100)
: 0, : 0,
// 计算剩余天数 // 计算剩余天数
daysLeft: product.preorderEndDate daysLeft: product.preorderEndDate

View File

@ -2,6 +2,8 @@ import { NextRequest, NextResponse } from 'next/server'
import { getPayload } from 'payload' import { getPayload } from 'payload'
import config from '@payload-config' import config from '@payload-config'
const MEDUSA_PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || ''
/** /**
* Medusa * Medusa
* GET /api/preorders/:id/orders * GET /api/preorders/:id/orders
@ -57,9 +59,10 @@ export async function GET(
// 从 Medusa 获取订单数据 // 从 Medusa 获取订单数据
const medusaUrl = process.env.MEDUSA_BACKEND_URL || 'http://localhost:9000' const medusaUrl = process.env.MEDUSA_BACKEND_URL || 'http://localhost:9000'
const medusaResponse = await fetch(`${medusaUrl}/admin/orders`, { const medusaResponse = await fetch(`${medusaUrl}/admin/orders?limit=500`, {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'x-publishable-api-key': MEDUSA_PUBLISHABLE_KEY,
}, },
}) })

View File

@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from 'next/server'
import payload from 'payload' import payload from 'payload'
const MEDUSA_BACKEND_URL = process.env.MEDUSA_BACKEND_URL || 'http://localhost:9000' const MEDUSA_BACKEND_URL = process.env.MEDUSA_BACKEND_URL || 'http://localhost:9000'
const MEDUSA_ADMIN_API_KEY = process.env.MEDUSA_ADMIN_API_KEY || '' const MEDUSA_PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || ''
/** /**
* *
@ -77,7 +77,7 @@ export async function POST(req: NextRequest) {
`${MEDUSA_BACKEND_URL}/admin/orders?product_id=${medusaId}&limit=1000`, `${MEDUSA_BACKEND_URL}/admin/orders?product_id=${medusaId}&limit=1000`,
{ {
headers: { headers: {
'x-medusa-access-token': MEDUSA_ADMIN_API_KEY, 'x-publishable-api-key': MEDUSA_PUBLISHABLE_KEY,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
} }

View File

@ -0,0 +1,93 @@
import type { CollectionConfig } from 'payload'
import { logAfterChange, logAfterDelete } from '../../hooks/logAction'
import { cacheAfterChange, cacheAfterDelete } from '../../hooks/cacheInvalidation'
/**
* -
*
* DisassemblyPages
* components
*/
export const DisassemblyComponents: CollectionConfig = {
slug: 'disassembly-components',
admin: {
useAsTitle: 'label',
hidden: true,
description: '拆解页中的拆解组件(通过拆解页管理)',
defaultColumns: ['label', 'startRadius', 'updatedAt'],
},
access: {
read: () => true,
create: ({ req: { user } }) => !!user,
update: ({ req: { user } }) => !!user,
delete: ({ req: { user } }) => !!user,
},
hooks: {
afterChange: [logAfterChange, cacheAfterChange],
afterDelete: [logAfterDelete, cacheAfterDelete],
},
fields: [
// 组件名称Admin 面板标识用)
{
name: 'label',
label: '组件名称',
type: 'text',
required: true,
admin: {
description: '用于 Admin 面板中标识该组件',
},
},
// 起点坐标
{
name: 'startCoordinate',
label: '起点坐标',
type: 'group',
admin: {
description: '组件锚点在页面/图片上的坐标',
},
fields: [
{
name: 'x',
label: 'X',
type: 'number',
required: true,
defaultValue: 0,
admin: { description: '水平坐标' },
},
{
name: 'y',
label: 'Y',
type: 'number',
required: true,
defaultValue: 0,
admin: { description: '垂直坐标' },
},
],
},
// 起点坐标半径
{
name: 'startRadius',
label: '起点坐标半径',
type: 'number',
required: true,
defaultValue: 20,
admin: {
description: '锚点热区半径px',
},
},
// 第三层:关联商品信息列表
{
name: 'linkedProducts',
label: '关联商品信息',
type: 'relationship',
relationTo: 'disassembly-linked-products',
hasMany: true,
admin: {
description: '该组件下的关联商品信息条目',
},
},
],
}

View File

@ -0,0 +1,92 @@
import type { CollectionConfig } from 'payload'
import { logAfterChange, logAfterDelete } from '../../hooks/logAction'
import { cacheAfterChange, cacheAfterDelete } from '../../hooks/cacheInvalidation'
/**
* -
*
* DisassemblyComponents/
* linkedProducts
*/
export const DisassemblyLinkedProducts: CollectionConfig = {
slug: 'disassembly-linked-products',
admin: {
useAsTitle: 'productName',
hidden: true,
description: '拆解组件中的关联商品信息(通过拆解组件管理)',
defaultColumns: ['productName', 'products', 'preorderProducts', 'updatedAt'],
},
access: {
read: () => true,
create: ({ req: { user } }) => !!user,
update: ({ req: { user } }) => !!user,
delete: ({ req: { user } }) => !!user,
},
hooks: {
afterChange: [logAfterChange, cacheAfterChange],
afterDelete: [logAfterDelete, cacheAfterDelete],
},
fields: [
// 具体坐标(商品标注在图片上的坐标)
{
name: 'coordinate',
label: '具体坐标',
type: 'group',
admin: {
description: '商品标注在图片上的坐标',
},
fields: [
{
name: 'x',
label: 'X',
type: 'number',
required: true,
defaultValue: 0,
admin: { description: '水平坐标' },
},
{
name: 'y',
label: 'Y',
type: 'number',
required: true,
defaultValue: 0,
admin: { description: '垂直坐标' },
},
],
},
// 商品名称(显示用,留空则使用关联商品标题)
{
name: 'productName',
label: '商品名称',
type: 'text',
admin: {
description: '展示在标注上的商品名称,留空则使用关联商品标题',
},
},
// 关联普通商品列表
{
name: 'products',
label: '关联商品 (Products)',
type: 'relationship',
relationTo: 'products',
hasMany: true,
admin: {
description: '关联的普通商品',
},
},
// 关联预售商品列表
{
name: 'preorderProducts',
label: '关联预售商品 (PreorderProducts)',
type: 'relationship',
relationTo: 'preorder-products',
hasMany: true,
admin: {
description: '关联的预售商品',
},
},
],
}

View File

@ -0,0 +1,73 @@
import type { CollectionConfig } from 'payload'
import { logAfterChange, logAfterDelete } from '../../hooks/logAction'
import { cacheAfterChange, cacheAfterDelete } from '../../hooks/cacheInvalidation'
/**
* -
*
* Collection
* URL DisassemblyComponents
*
*
* DisassemblyPages
* components[] DisassemblyComponents ()
* linkedProducts[] DisassemblyLinkedProducts ()
*/
export const DisassemblyPages: CollectionConfig = {
slug: 'disassembly-pages',
admin: {
useAsTitle: 'name',
defaultColumns: ['mainImage', 'name', 'url', 'updatedAt'],
description: '管理产品拆解页,包含拆解组件和关联商品信息',
pagination: {
defaultLimit: 25,
},
},
access: {
read: () => true,
create: ({ req: { user } }) => !!user,
update: ({ req: { user } }) => !!user,
delete: ({ req: { user } }) => !!user,
},
hooks: {
afterChange: [logAfterChange, cacheAfterChange],
afterDelete: [logAfterDelete, cacheAfterDelete],
},
fields: [
// 主图
{
name: 'mainImage',
label: '主图',
type: 'upload',
relationTo: 'media',
required: true,
},
// 名称
{
name: 'name',
label: '名称',
type: 'text',
required: true,
},
// URL 链接
{
name: 'url',
label: 'URL 链接',
type: 'text',
admin: {
description: '该拆解页对应的页面路径或外部链接',
},
},
// 第二层:拆解组件列表
{
name: 'components',
label: '拆解组件',
type: 'relationship',
relationTo: 'disassembly-components',
hasMany: true,
admin: {
description: '该拆解页包含的拆解组件列表',
},
},
],
}

View File

@ -11,7 +11,9 @@ export function PreorderProgressCell({ rowData }: any) {
const fundingGoal = parseInt(rowData?.fundingGoal || '0', 10) || 100 const fundingGoal = parseInt(rowData?.fundingGoal || '0', 10) || 100
const totalCount = orderCount + fakeOrderCount const totalCount = orderCount + fakeOrderCount
const percentage = fundingGoal > 0 ? Math.min(Math.round((totalCount / fundingGoal) * 100), 100) : 0 const percentage = fundingGoal > 0 ? Math.round((totalCount / fundingGoal) * 100) : 0
const isExceeded = percentage > 100
const barWidth = Math.min(percentage, 100)
return ( return (
<div className="preorder-progress-info"> <div className="preorder-progress-info">
@ -22,11 +24,27 @@ export function PreorderProgressCell({ rowData }: any) {
</span> </span>
</div> </div>
<div className="progress-bar"> <div className="progress-bar" style={{ position: 'relative' }}>
<div <div
className="progress-fill" className="progress-fill"
style={{ width: `${percentage}%` }} style={{
width: `${barWidth}%`,
background: isExceeded ? 'var(--theme-success-600, #16a34a)' : undefined,
}}
/> />
{isExceeded && (
<div style={{
position: 'absolute',
right: 0,
top: '50%',
transform: 'translateY(-50%)',
width: 6,
height: 6,
borderRadius: '50%',
background: '#16a34a',
boxShadow: '0 0 0 2px #fff',
}} />
)}
</div> </div>
<div className="progress-stats"> <div className="progress-stats">
@ -40,7 +58,9 @@ export function PreorderProgressCell({ rowData }: any) {
</div> </div>
<div className="stat-item"> <div className="stat-item">
<span className="stat-label"></span> <span className="stat-label"></span>
<span className="stat-value">{percentage}%</span> <span className="stat-value" style={isExceeded ? { color: '#16a34a', fontWeight: 700 } : {}}>
{isExceeded ? `超出 ${percentage - 100}%` : `${percentage}%`}
</span>
</div> </div>
</div> </div>
</div> </div>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,314 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TYPE "public"."enum_preorder_products_preorder_type" AS ENUM('standard', 'crowdfunding', 'limited');
CREATE TYPE "public"."enum_hero_slider_slides_layout" AS ENUM('left', 'right', 'center');
CREATE TABLE "products_taobao_links" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"url" varchar NOT NULL,
"title" varchar,
"thumbnail" varchar,
"note" varchar
);
CREATE TABLE "preorder_products_taobao_links" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"url" varchar NOT NULL,
"title" varchar,
"thumbnail" varchar,
"note" varchar
);
CREATE TABLE "disassembly_pages_components_linked_products" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"coordinate_x" numeric DEFAULT 0 NOT NULL,
"coordinate_y" numeric DEFAULT 0 NOT NULL,
"product_name" varchar
);
CREATE TABLE "disassembly_pages_components" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"label" varchar,
"start_coordinate_x" numeric DEFAULT 0 NOT NULL,
"start_coordinate_y" numeric DEFAULT 0 NOT NULL,
"start_radius" numeric DEFAULT 20 NOT NULL
);
CREATE TABLE "disassembly_pages" (
"id" serial PRIMARY KEY NOT NULL,
"main_image_id" integer NOT NULL,
"name" varchar NOT NULL,
"url" varchar,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "disassembly_pages_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"products_id" integer,
"preorder_products_id" integer
);
CREATE TABLE "hero_slider_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"products_id" integer,
"preorder_products_id" integer
);
CREATE TABLE "site_access" (
"id" serial PRIMARY KEY NOT NULL,
"is_accessible" boolean DEFAULT true NOT NULL,
"maintenance_message" varchar DEFAULT 'The site is currently under maintenance. Please check back later.' NOT NULL,
"estimated_restore_time" timestamp(3) with time zone,
"updated_at" timestamp(3) with time zone,
"created_at" timestamp(3) with time zone
);
ALTER TABLE "order_products" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "order_products_rels" DISABLE ROW LEVEL SECURITY;
DROP TABLE "order_products" CASCADE;
DROP TABLE "order_products_rels" CASCADE;
ALTER TABLE "preorder_products_rels" DROP CONSTRAINT "preorder_products_rels_order_products_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_order_products_fk";
ALTER TABLE "hero_slider_slides" DROP CONSTRAINT "hero_slider_slides_image_mobile_id_media_id_fk";
ALTER TABLE "product_recommendations_rels" DROP CONSTRAINT "product_recommendations_rels_order_products_fk";
DROP INDEX "preorder_products_rels_order_products_id_idx";
DROP INDEX "payload_locked_documents_rels_order_products_id_idx";
DROP INDEX "hero_slider_slides_image_mobile_idx";
DROP INDEX "product_recommendations_rels_order_products_id_idx";
ALTER TABLE "preorder_products" ALTER COLUMN "description" SET DATA TYPE varchar;
ALTER TABLE "hero_slider_slides" ALTER COLUMN "subtitle" SET NOT NULL;
ALTER TABLE "products" ADD COLUMN "seed_id" varchar;
ALTER TABLE "products" ADD COLUMN "start_price" numeric;
ALTER TABLE "products" ADD COLUMN "description" varchar;
ALTER TABLE "products" ADD COLUMN "tags" varchar;
ALTER TABLE "products" ADD COLUMN "type" varchar;
ALTER TABLE "products" ADD COLUMN "collection" varchar;
ALTER TABLE "products" ADD COLUMN "category" varchar;
ALTER TABLE "products" ADD COLUMN "height" numeric;
ALTER TABLE "products" ADD COLUMN "width" numeric;
ALTER TABLE "products" ADD COLUMN "length" numeric;
ALTER TABLE "products" ADD COLUMN "weight" numeric;
ALTER TABLE "products" ADD COLUMN "mid_code" varchar;
ALTER TABLE "products" ADD COLUMN "hs_code" varchar;
ALTER TABLE "products" ADD COLUMN "country_of_origin" varchar;
ALTER TABLE "products_rels" ADD COLUMN "preorder_products_id" integer;
ALTER TABLE "preorder_products" ADD COLUMN "seed_id" varchar;
ALTER TABLE "preorder_products" ADD COLUMN "start_price" numeric;
ALTER TABLE "preorder_products" ADD COLUMN "preorder_type" "enum_preorder_products_preorder_type" DEFAULT 'standard' NOT NULL;
ALTER TABLE "preorder_products" ADD COLUMN "funding_goal" numeric DEFAULT 0 NOT NULL;
ALTER TABLE "preorder_products" ADD COLUMN "preorder_start_date" timestamp(3) with time zone;
ALTER TABLE "preorder_products" ADD COLUMN "preorder_end_date" timestamp(3) with time zone;
ALTER TABLE "preorder_products" ADD COLUMN "order_count" numeric DEFAULT 0;
ALTER TABLE "preorder_products" ADD COLUMN "fake_order_count" numeric DEFAULT 0;
ALTER TABLE "preorder_products" ADD COLUMN "content" jsonb;
ALTER TABLE "preorder_products" ADD COLUMN "tags" varchar;
ALTER TABLE "preorder_products" ADD COLUMN "type" varchar;
ALTER TABLE "preorder_products" ADD COLUMN "collection" varchar;
ALTER TABLE "preorder_products" ADD COLUMN "category" varchar;
ALTER TABLE "preorder_products" ADD COLUMN "height" numeric;
ALTER TABLE "preorder_products" ADD COLUMN "width" numeric;
ALTER TABLE "preorder_products" ADD COLUMN "length" numeric;
ALTER TABLE "preorder_products" ADD COLUMN "weight" numeric;
ALTER TABLE "preorder_products" ADD COLUMN "mid_code" varchar;
ALTER TABLE "preorder_products" ADD COLUMN "hs_code" varchar;
ALTER TABLE "preorder_products" ADD COLUMN "country_of_origin" varchar;
ALTER TABLE "preorder_products_rels" ADD COLUMN "products_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "disassembly_pages_id" integer;
ALTER TABLE "hero_slider_slides" ADD COLUMN "desc" varchar NOT NULL;
ALTER TABLE "hero_slider_slides" ADD COLUMN "layout" "enum_hero_slider_slides_layout" DEFAULT 'left' NOT NULL;
ALTER TABLE "hero_slider_slides" ADD COLUMN "show_focus_circle" boolean DEFAULT false;
ALTER TABLE "hero_slider_slides" ADD COLUMN "price" varchar NOT NULL;
ALTER TABLE "product_recommendations_lists" ADD COLUMN "preorder" boolean DEFAULT false;
ALTER TABLE "products_taobao_links" ADD CONSTRAINT "products_taobao_links_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "preorder_products_taobao_links" ADD CONSTRAINT "preorder_products_taobao_links_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."preorder_products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_pages_components_linked_products" ADD CONSTRAINT "disassembly_pages_components_linked_products_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."disassembly_pages_components"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_pages_components" ADD CONSTRAINT "disassembly_pages_components_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."disassembly_pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_pages" ADD CONSTRAINT "disassembly_pages_main_image_id_media_id_fk" FOREIGN KEY ("main_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "disassembly_pages_rels" ADD CONSTRAINT "disassembly_pages_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."disassembly_pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_pages_rels" ADD CONSTRAINT "disassembly_pages_rels_products_fk" FOREIGN KEY ("products_id") REFERENCES "public"."products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_pages_rels" ADD CONSTRAINT "disassembly_pages_rels_preorder_products_fk" FOREIGN KEY ("preorder_products_id") REFERENCES "public"."preorder_products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "hero_slider_rels" ADD CONSTRAINT "hero_slider_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."hero_slider"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "hero_slider_rels" ADD CONSTRAINT "hero_slider_rels_products_fk" FOREIGN KEY ("products_id") REFERENCES "public"."products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "hero_slider_rels" ADD CONSTRAINT "hero_slider_rels_preorder_products_fk" FOREIGN KEY ("preorder_products_id") REFERENCES "public"."preorder_products"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "products_taobao_links_order_idx" ON "products_taobao_links" USING btree ("_order");
CREATE INDEX "products_taobao_links_parent_id_idx" ON "products_taobao_links" USING btree ("_parent_id");
CREATE INDEX "preorder_products_taobao_links_order_idx" ON "preorder_products_taobao_links" USING btree ("_order");
CREATE INDEX "preorder_products_taobao_links_parent_id_idx" ON "preorder_products_taobao_links" USING btree ("_parent_id");
CREATE INDEX "disassembly_pages_components_linked_products_order_idx" ON "disassembly_pages_components_linked_products" USING btree ("_order");
CREATE INDEX "disassembly_pages_components_linked_products_parent_id_idx" ON "disassembly_pages_components_linked_products" USING btree ("_parent_id");
CREATE INDEX "disassembly_pages_components_order_idx" ON "disassembly_pages_components" USING btree ("_order");
CREATE INDEX "disassembly_pages_components_parent_id_idx" ON "disassembly_pages_components" USING btree ("_parent_id");
CREATE INDEX "disassembly_pages_main_image_idx" ON "disassembly_pages" USING btree ("main_image_id");
CREATE INDEX "disassembly_pages_updated_at_idx" ON "disassembly_pages" USING btree ("updated_at");
CREATE INDEX "disassembly_pages_created_at_idx" ON "disassembly_pages" USING btree ("created_at");
CREATE INDEX "disassembly_pages_rels_order_idx" ON "disassembly_pages_rels" USING btree ("order");
CREATE INDEX "disassembly_pages_rels_parent_idx" ON "disassembly_pages_rels" USING btree ("parent_id");
CREATE INDEX "disassembly_pages_rels_path_idx" ON "disassembly_pages_rels" USING btree ("path");
CREATE INDEX "disassembly_pages_rels_products_id_idx" ON "disassembly_pages_rels" USING btree ("products_id");
CREATE INDEX "disassembly_pages_rels_preorder_products_id_idx" ON "disassembly_pages_rels" USING btree ("preorder_products_id");
CREATE INDEX "hero_slider_rels_order_idx" ON "hero_slider_rels" USING btree ("order");
CREATE INDEX "hero_slider_rels_parent_idx" ON "hero_slider_rels" USING btree ("parent_id");
CREATE INDEX "hero_slider_rels_path_idx" ON "hero_slider_rels" USING btree ("path");
CREATE INDEX "hero_slider_rels_products_id_idx" ON "hero_slider_rels" USING btree ("products_id");
CREATE INDEX "hero_slider_rels_preorder_products_id_idx" ON "hero_slider_rels" USING btree ("preorder_products_id");
ALTER TABLE "products_rels" ADD CONSTRAINT "products_rels_preorder_products_fk" FOREIGN KEY ("preorder_products_id") REFERENCES "public"."preorder_products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "preorder_products_rels" ADD CONSTRAINT "preorder_products_rels_products_fk" FOREIGN KEY ("products_id") REFERENCES "public"."products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_disassembly_pages_fk" FOREIGN KEY ("disassembly_pages_id") REFERENCES "public"."disassembly_pages"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "products_handle_idx" ON "products" USING btree ("handle");
CREATE UNIQUE INDEX "products_seed_id_idx" ON "products" USING btree ("seed_id");
CREATE INDEX "products_rels_preorder_products_id_idx" ON "products_rels" USING btree ("preorder_products_id");
CREATE INDEX "preorder_products_handle_idx" ON "preorder_products" USING btree ("handle");
CREATE UNIQUE INDEX "preorder_products_seed_id_idx" ON "preorder_products" USING btree ("seed_id");
CREATE INDEX "preorder_products_rels_products_id_idx" ON "preorder_products_rels" USING btree ("products_id");
CREATE INDEX "payload_locked_documents_rels_disassembly_pages_id_idx" ON "payload_locked_documents_rels" USING btree ("disassembly_pages_id");
ALTER TABLE "preorder_products_rels" DROP COLUMN "order_products_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "order_products_id";
ALTER TABLE "hero_slider_slides" DROP COLUMN "image_mobile_id";
ALTER TABLE "product_recommendations_rels" DROP COLUMN "order_products_id";
DROP TYPE "public"."enum_order_products_status";`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
CREATE TYPE "public"."enum_order_products_status" AS ENUM('draft', 'published');
CREATE TABLE "order_products" (
"id" serial PRIMARY KEY NOT NULL,
"medusa_id" varchar NOT NULL,
"status" "enum_order_products_status" DEFAULT 'draft' NOT NULL,
"title" varchar NOT NULL,
"handle" varchar,
"thumbnail" varchar,
"last_synced_at" timestamp(3) with time zone,
"description" jsonb,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "order_products_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"preorder_products_id" integer,
"order_products_id" integer
);
ALTER TABLE "products_taobao_links" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "preorder_products_taobao_links" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "disassembly_pages_components_linked_products" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "disassembly_pages_components" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "disassembly_pages" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "disassembly_pages_rels" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "hero_slider_rels" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "site_access" DISABLE ROW LEVEL SECURITY;
DROP TABLE "products_taobao_links" CASCADE;
DROP TABLE "preorder_products_taobao_links" CASCADE;
DROP TABLE "disassembly_pages_components_linked_products" CASCADE;
DROP TABLE "disassembly_pages_components" CASCADE;
DROP TABLE "disassembly_pages" CASCADE;
DROP TABLE "disassembly_pages_rels" CASCADE;
DROP TABLE "hero_slider_rels" CASCADE;
DROP TABLE "site_access" CASCADE;
ALTER TABLE "products_rels" DROP CONSTRAINT "products_rels_preorder_products_fk";
ALTER TABLE "preorder_products_rels" DROP CONSTRAINT "preorder_products_rels_products_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_disassembly_pages_fk";
DROP INDEX "products_handle_idx";
DROP INDEX "products_seed_id_idx";
DROP INDEX "products_rels_preorder_products_id_idx";
DROP INDEX "preorder_products_handle_idx";
DROP INDEX "preorder_products_seed_id_idx";
DROP INDEX "preorder_products_rels_products_id_idx";
DROP INDEX "payload_locked_documents_rels_disassembly_pages_id_idx";
ALTER TABLE "preorder_products" ALTER COLUMN "description" SET DATA TYPE jsonb;
ALTER TABLE "hero_slider_slides" ALTER COLUMN "subtitle" DROP NOT NULL;
ALTER TABLE "preorder_products_rels" ADD COLUMN "order_products_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "order_products_id" integer;
ALTER TABLE "hero_slider_slides" ADD COLUMN "image_mobile_id" integer;
ALTER TABLE "product_recommendations_rels" ADD COLUMN "order_products_id" integer;
ALTER TABLE "order_products_rels" ADD CONSTRAINT "order_products_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."order_products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "order_products_rels" ADD CONSTRAINT "order_products_rels_preorder_products_fk" FOREIGN KEY ("preorder_products_id") REFERENCES "public"."preorder_products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "order_products_rels" ADD CONSTRAINT "order_products_rels_order_products_fk" FOREIGN KEY ("order_products_id") REFERENCES "public"."order_products"("id") ON DELETE cascade ON UPDATE no action;
CREATE UNIQUE INDEX "order_products_medusa_id_idx" ON "order_products" USING btree ("medusa_id");
CREATE INDEX "order_products_updated_at_idx" ON "order_products" USING btree ("updated_at");
CREATE INDEX "order_products_created_at_idx" ON "order_products" USING btree ("created_at");
CREATE INDEX "order_products_rels_order_idx" ON "order_products_rels" USING btree ("order");
CREATE INDEX "order_products_rels_parent_idx" ON "order_products_rels" USING btree ("parent_id");
CREATE INDEX "order_products_rels_path_idx" ON "order_products_rels" USING btree ("path");
CREATE INDEX "order_products_rels_preorder_products_id_idx" ON "order_products_rels" USING btree ("preorder_products_id");
CREATE INDEX "order_products_rels_order_products_id_idx" ON "order_products_rels" USING btree ("order_products_id");
ALTER TABLE "preorder_products_rels" ADD CONSTRAINT "preorder_products_rels_order_products_fk" FOREIGN KEY ("order_products_id") REFERENCES "public"."order_products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_order_products_fk" FOREIGN KEY ("order_products_id") REFERENCES "public"."order_products"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "hero_slider_slides" ADD CONSTRAINT "hero_slider_slides_image_mobile_id_media_id_fk" FOREIGN KEY ("image_mobile_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "product_recommendations_rels" ADD CONSTRAINT "product_recommendations_rels_order_products_fk" FOREIGN KEY ("order_products_id") REFERENCES "public"."order_products"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "preorder_products_rels_order_products_id_idx" ON "preorder_products_rels" USING btree ("order_products_id");
CREATE INDEX "payload_locked_documents_rels_order_products_id_idx" ON "payload_locked_documents_rels" USING btree ("order_products_id");
CREATE INDEX "hero_slider_slides_image_mobile_idx" ON "hero_slider_slides" USING btree ("image_mobile_id");
CREATE INDEX "product_recommendations_rels_order_products_id_idx" ON "product_recommendations_rels" USING btree ("order_products_id");
ALTER TABLE "products" DROP COLUMN "seed_id";
ALTER TABLE "products" DROP COLUMN "start_price";
ALTER TABLE "products" DROP COLUMN "description";
ALTER TABLE "products" DROP COLUMN "tags";
ALTER TABLE "products" DROP COLUMN "type";
ALTER TABLE "products" DROP COLUMN "collection";
ALTER TABLE "products" DROP COLUMN "category";
ALTER TABLE "products" DROP COLUMN "height";
ALTER TABLE "products" DROP COLUMN "width";
ALTER TABLE "products" DROP COLUMN "length";
ALTER TABLE "products" DROP COLUMN "weight";
ALTER TABLE "products" DROP COLUMN "mid_code";
ALTER TABLE "products" DROP COLUMN "hs_code";
ALTER TABLE "products" DROP COLUMN "country_of_origin";
ALTER TABLE "products_rels" DROP COLUMN "preorder_products_id";
ALTER TABLE "preorder_products" DROP COLUMN "seed_id";
ALTER TABLE "preorder_products" DROP COLUMN "start_price";
ALTER TABLE "preorder_products" DROP COLUMN "preorder_type";
ALTER TABLE "preorder_products" DROP COLUMN "funding_goal";
ALTER TABLE "preorder_products" DROP COLUMN "preorder_start_date";
ALTER TABLE "preorder_products" DROP COLUMN "preorder_end_date";
ALTER TABLE "preorder_products" DROP COLUMN "order_count";
ALTER TABLE "preorder_products" DROP COLUMN "fake_order_count";
ALTER TABLE "preorder_products" DROP COLUMN "content";
ALTER TABLE "preorder_products" DROP COLUMN "tags";
ALTER TABLE "preorder_products" DROP COLUMN "type";
ALTER TABLE "preorder_products" DROP COLUMN "collection";
ALTER TABLE "preorder_products" DROP COLUMN "category";
ALTER TABLE "preorder_products" DROP COLUMN "height";
ALTER TABLE "preorder_products" DROP COLUMN "width";
ALTER TABLE "preorder_products" DROP COLUMN "length";
ALTER TABLE "preorder_products" DROP COLUMN "weight";
ALTER TABLE "preorder_products" DROP COLUMN "mid_code";
ALTER TABLE "preorder_products" DROP COLUMN "hs_code";
ALTER TABLE "preorder_products" DROP COLUMN "country_of_origin";
ALTER TABLE "preorder_products_rels" DROP COLUMN "products_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "disassembly_pages_id";
ALTER TABLE "hero_slider_slides" DROP COLUMN "desc";
ALTER TABLE "hero_slider_slides" DROP COLUMN "layout";
ALTER TABLE "hero_slider_slides" DROP COLUMN "show_focus_circle";
ALTER TABLE "hero_slider_slides" DROP COLUMN "price";
ALTER TABLE "product_recommendations_lists" DROP COLUMN "preorder";
DROP TYPE "public"."enum_preorder_products_preorder_type";
DROP TYPE "public"."enum_hero_slider_slides_layout";`)
}

View File

@ -0,0 +1,250 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
/**
* disassembly_pages Collection
*
* arrays
* disassembly_pages
* disassembly_pages_components (array: order, parent_id, label, , )
* disassembly_pages_components_linked_products (nested array: order, parent_id, , product_name)
* disassembly_pages_rels (products_id, preorder_products_id)
*
* Collections
* disassembly_pages (rels disassembly_components)
* disassembly_components ( Collection)
* disassembly_components_rels (linkedProducts disassembly_linked_products)
* disassembly_linked_products ( Collection)
* disassembly_linked_products_rels (products, preorder_products)
*/
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
-- 1. disassembly_components
CREATE TABLE "disassembly_components" (
"id" serial PRIMARY KEY NOT NULL,
"label" varchar NOT NULL,
"start_coordinate_x" numeric DEFAULT 0 NOT NULL,
"start_coordinate_y" numeric DEFAULT 0 NOT NULL,
"start_radius" numeric DEFAULT 20 NOT NULL,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE INDEX "disassembly_components_updated_at_idx"
ON "disassembly_components" USING btree ("updated_at");
CREATE INDEX "disassembly_components_created_at_idx"
ON "disassembly_components" USING btree ("created_at");
-- 2. disassembly_components_rels
CREATE TABLE "disassembly_components_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"disassembly_linked_products_id" integer
);
ALTER TABLE "disassembly_components_rels"
ADD CONSTRAINT "disassembly_components_rels_parent_fk"
FOREIGN KEY ("parent_id") REFERENCES "public"."disassembly_components"("id")
ON DELETE cascade ON UPDATE no action;
CREATE INDEX "disassembly_components_rels_order_idx"
ON "disassembly_components_rels" USING btree ("order");
CREATE INDEX "disassembly_components_rels_parent_idx"
ON "disassembly_components_rels" USING btree ("parent_id");
CREATE INDEX "disassembly_components_rels_path_idx"
ON "disassembly_components_rels" USING btree ("path");
-- 3. disassembly_linked_products
CREATE TABLE "disassembly_linked_products" (
"id" serial PRIMARY KEY NOT NULL,
"coordinate_x" numeric DEFAULT 0 NOT NULL,
"coordinate_y" numeric DEFAULT 0 NOT NULL,
"product_name" varchar,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE INDEX "disassembly_linked_products_updated_at_idx"
ON "disassembly_linked_products" USING btree ("updated_at");
CREATE INDEX "disassembly_linked_products_created_at_idx"
ON "disassembly_linked_products" USING btree ("created_at");
-- 4. disassembly_linked_products_rels
CREATE TABLE "disassembly_linked_products_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"products_id" integer,
"preorder_products_id" integer
);
ALTER TABLE "disassembly_linked_products_rels"
ADD CONSTRAINT "disassembly_linked_products_rels_parent_fk"
FOREIGN KEY ("parent_id") REFERENCES "public"."disassembly_linked_products"("id")
ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_linked_products_rels"
ADD CONSTRAINT "disassembly_linked_products_rels_products_fk"
FOREIGN KEY ("products_id") REFERENCES "public"."products"("id")
ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_linked_products_rels"
ADD CONSTRAINT "disassembly_linked_products_rels_preorder_products_fk"
FOREIGN KEY ("preorder_products_id") REFERENCES "public"."preorder_products"("id")
ON DELETE cascade ON UPDATE no action;
CREATE INDEX "disassembly_linked_products_rels_order_idx"
ON "disassembly_linked_products_rels" USING btree ("order");
CREATE INDEX "disassembly_linked_products_rels_parent_idx"
ON "disassembly_linked_products_rels" USING btree ("parent_id");
CREATE INDEX "disassembly_linked_products_rels_path_idx"
ON "disassembly_linked_products_rels" USING btree ("path");
CREATE INDEX "disassembly_linked_products_rels_products_id_idx"
ON "disassembly_linked_products_rels" USING btree ("products_id");
CREATE INDEX "disassembly_linked_products_rels_preorder_products_id_idx"
ON "disassembly_linked_products_rels" USING btree ("preorder_products_id");
-- 5. disassembly_pages_rels disassembly_components
-- products/preorder_products disassembly_linked_products_rels
ALTER TABLE "disassembly_pages_rels"
DROP CONSTRAINT IF EXISTS "disassembly_pages_rels_products_fk";
ALTER TABLE "disassembly_pages_rels"
DROP CONSTRAINT IF EXISTS "disassembly_pages_rels_preorder_products_fk";
DROP INDEX IF EXISTS "disassembly_pages_rels_products_id_idx";
DROP INDEX IF EXISTS "disassembly_pages_rels_preorder_products_id_idx";
ALTER TABLE "disassembly_pages_rels" DROP COLUMN IF EXISTS "products_id";
ALTER TABLE "disassembly_pages_rels" DROP COLUMN IF EXISTS "preorder_products_id";
-- disassembly_components_id
ALTER TABLE "disassembly_pages_rels"
ADD COLUMN "disassembly_components_id" integer;
ALTER TABLE "disassembly_pages_rels"
ADD CONSTRAINT "disassembly_pages_rels_disassembly_components_fk"
FOREIGN KEY ("disassembly_components_id") REFERENCES "public"."disassembly_components"("id")
ON DELETE cascade ON UPDATE no action;
CREATE INDEX "disassembly_pages_rels_disassembly_components_id_idx"
ON "disassembly_pages_rels" USING btree ("disassembly_components_id");
-- 6. payload_locked_documents_rels Collection
ALTER TABLE "payload_locked_documents_rels"
ADD COLUMN "disassembly_components_id" integer;
ALTER TABLE "payload_locked_documents_rels"
ADD COLUMN "disassembly_linked_products_id" integer;
ALTER TABLE "payload_locked_documents_rels"
ADD CONSTRAINT "payload_locked_documents_rels_disassembly_components_fk"
FOREIGN KEY ("disassembly_components_id") REFERENCES "public"."disassembly_components"("id")
ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels"
ADD CONSTRAINT "payload_locked_documents_rels_disassembly_linked_products_fk"
FOREIGN KEY ("disassembly_linked_products_id") REFERENCES "public"."disassembly_linked_products"("id")
ON DELETE cascade ON UPDATE no action;
CREATE INDEX "payload_locked_documents_rels_disassembly_components_id_idx"
ON "payload_locked_documents_rels" USING btree ("disassembly_components_id");
CREATE INDEX "payload_locked_documents_rels_disassembly_linked_products_id_idx"
ON "payload_locked_documents_rels" USING btree ("disassembly_linked_products_id");
-- 7. disassembly_components_rels
ALTER TABLE "disassembly_components_rels"
ADD CONSTRAINT "disassembly_components_rels_disassembly_linked_products_fk"
FOREIGN KEY ("disassembly_linked_products_id") REFERENCES "public"."disassembly_linked_products"("id")
ON DELETE cascade ON UPDATE no action;
CREATE INDEX "disassembly_components_rels_disassembly_linked_products_id_idx"
ON "disassembly_components_rels" USING btree ("disassembly_linked_products_id");
-- 8.
ALTER TABLE "disassembly_pages_components_linked_products" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "disassembly_pages_components" DISABLE ROW LEVEL SECURITY;
DROP TABLE "disassembly_pages_components_linked_products" CASCADE;
DROP TABLE "disassembly_pages_components" CASCADE;
`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
--
CREATE TABLE "disassembly_pages_components_linked_products" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"coordinate_x" numeric DEFAULT 0 NOT NULL,
"coordinate_y" numeric DEFAULT 0 NOT NULL,
"product_name" varchar
);
CREATE TABLE "disassembly_pages_components" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"label" varchar,
"start_coordinate_x" numeric DEFAULT 0 NOT NULL,
"start_coordinate_y" numeric DEFAULT 0 NOT NULL,
"start_radius" numeric DEFAULT 20 NOT NULL
);
ALTER TABLE "disassembly_pages_components_linked_products"
ADD CONSTRAINT "disassembly_pages_components_linked_products_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."disassembly_pages_components"("id")
ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_pages_components"
ADD CONSTRAINT "disassembly_pages_components_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."disassembly_pages"("id")
ON DELETE cascade ON UPDATE no action;
CREATE INDEX "disassembly_pages_components_linked_products_order_idx"
ON "disassembly_pages_components_linked_products" USING btree ("_order");
CREATE INDEX "disassembly_pages_components_linked_products_parent_id_idx"
ON "disassembly_pages_components_linked_products" USING btree ("_parent_id");
CREATE INDEX "disassembly_pages_components_order_idx"
ON "disassembly_pages_components" USING btree ("_order");
CREATE INDEX "disassembly_pages_components_parent_id_idx"
ON "disassembly_pages_components" USING btree ("_parent_id");
-- disassembly_pages_rels
ALTER TABLE "disassembly_pages_rels"
DROP CONSTRAINT IF EXISTS "disassembly_pages_rels_disassembly_components_fk";
DROP INDEX IF EXISTS "disassembly_pages_rels_disassembly_components_id_idx";
ALTER TABLE "disassembly_pages_rels" DROP COLUMN IF EXISTS "disassembly_components_id";
ALTER TABLE "disassembly_pages_rels" ADD COLUMN "products_id" integer;
ALTER TABLE "disassembly_pages_rels" ADD COLUMN "preorder_products_id" integer;
ALTER TABLE "disassembly_pages_rels"
ADD CONSTRAINT "disassembly_pages_rels_products_fk"
FOREIGN KEY ("products_id") REFERENCES "public"."products"("id")
ON DELETE cascade ON UPDATE no action;
ALTER TABLE "disassembly_pages_rels"
ADD CONSTRAINT "disassembly_pages_rels_preorder_products_fk"
FOREIGN KEY ("preorder_products_id") REFERENCES "public"."preorder_products"("id")
ON DELETE cascade ON UPDATE no action;
CREATE INDEX "disassembly_pages_rels_products_id_idx"
ON "disassembly_pages_rels" USING btree ("products_id");
CREATE INDEX "disassembly_pages_rels_preorder_products_id_idx"
ON "disassembly_pages_rels" USING btree ("preorder_products_id");
-- payload_locked_documents_rels
ALTER TABLE "payload_locked_documents_rels"
DROP CONSTRAINT IF EXISTS "payload_locked_documents_rels_disassembly_components_fk";
ALTER TABLE "payload_locked_documents_rels"
DROP CONSTRAINT IF EXISTS "payload_locked_documents_rels_disassembly_linked_products_fk";
DROP INDEX IF EXISTS "payload_locked_documents_rels_disassembly_components_id_idx";
DROP INDEX IF EXISTS "payload_locked_documents_rels_disassembly_linked_products_id_idx";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN IF EXISTS "disassembly_components_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN IF EXISTS "disassembly_linked_products_id";
-- Collection
DROP TABLE IF EXISTS "disassembly_linked_products_rels" CASCADE;
DROP TABLE IF EXISTS "disassembly_linked_products" CASCADE;
DROP TABLE IF EXISTS "disassembly_components_rels" CASCADE;
DROP TABLE IF EXISTS "disassembly_components" CASCADE;
`)
}

View File

@ -1,8 +1,10 @@
import * as migration_20260208_171142 from './20260208_171142' import * as migration_20260208_171142 from './20260208_171142';
import * as migration_20260212_193303 from './20260212_193303' import * as migration_20260212_193303 from './20260212_193303';
import * as migration_20260212_202303 from './20260212_202303' import * as migration_20260212_202303 from './20260212_202303';
import * as migration_hero_slider_simplify from './hero_slider_simplify' import * as migration_20260222_170233 from './20260222_170233';
import * as migration_product_recommendations_simplify from './product_recommendations_simplify' import * as migration_hero_slider_simplify from './hero_slider_simplify';
import * as migration_product_recommendations_simplify from './product_recommendations_simplify';
import * as migration_20260223_disassembly_refactor from './20260223_disassembly_refactor';
export const migrations = [ export const migrations = [
{ {
@ -17,14 +19,27 @@ export const migrations = [
}, },
{ {
up: migration_20260212_202303.up, up: migration_20260212_202303.up,
down: migration_20260212_202303.down,
name: '20260212_202303', name: '20260212_202303',
}, },
{
up: migration_20260222_170233.up,
down: migration_20260222_170233.down,
name: '20260222_170233',
},
{ {
up: migration_hero_slider_simplify.up, up: migration_hero_slider_simplify.up,
down: migration_hero_slider_simplify.down,
name: 'hero_slider_simplify', name: 'hero_slider_simplify',
}, },
{ {
up: migration_product_recommendations_simplify.up, up: migration_product_recommendations_simplify.up,
name: 'product_recommendations_simplify', down: migration_product_recommendations_simplify.down,
name: 'product_recommendations_simplify'
}, },
] {
up: migration_20260223_disassembly_refactor.up,
down: migration_20260223_disassembly_refactor.down,
name: '20260223_disassembly_refactor',
},
];

View File

@ -74,6 +74,9 @@ export interface Config {
announcements: Announcement; announcements: Announcement;
articles: Article; articles: Article;
logs: Log; logs: Log;
'disassembly-pages': DisassemblyPage;
'disassembly-components': DisassemblyComponent;
'disassembly-linked-products': DisassemblyLinkedProduct;
'payload-kv': PayloadKv; 'payload-kv': PayloadKv;
'payload-jobs': PayloadJob; 'payload-jobs': PayloadJob;
'payload-locked-documents': PayloadLockedDocument; 'payload-locked-documents': PayloadLockedDocument;
@ -89,6 +92,9 @@ export interface Config {
announcements: AnnouncementsSelect<false> | AnnouncementsSelect<true>; announcements: AnnouncementsSelect<false> | AnnouncementsSelect<true>;
articles: ArticlesSelect<false> | ArticlesSelect<true>; articles: ArticlesSelect<false> | ArticlesSelect<true>;
logs: LogsSelect<false> | LogsSelect<true>; logs: LogsSelect<false> | LogsSelect<true>;
'disassembly-pages': DisassemblyPagesSelect<false> | DisassemblyPagesSelect<true>;
'disassembly-components': DisassemblyComponentsSelect<false> | DisassemblyComponentsSelect<true>;
'disassembly-linked-products': DisassemblyLinkedProductsSelect<false> | DisassemblyLinkedProductsSelect<true>;
'payload-kv': PayloadKvSelect<false> | PayloadKvSelect<true>; 'payload-kv': PayloadKvSelect<false> | PayloadKvSelect<true>;
'payload-jobs': PayloadJobsSelect<false> | PayloadJobsSelect<true>; 'payload-jobs': PayloadJobsSelect<false> | PayloadJobsSelect<true>;
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>; 'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
@ -697,6 +703,99 @@ export interface Log {
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
} }
/**
*
*
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disassembly-pages".
*/
export interface DisassemblyPage {
id: number;
mainImage: number | Media;
name: string;
/**
*
*/
url?: string | null;
/**
*
*/
components?: (number | DisassemblyComponent)[] | null;
updatedAt: string;
createdAt: string;
}
/**
*
*
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disassembly-components".
*/
export interface DisassemblyComponent {
id: number;
/**
* Admin
*/
label: string;
/**
* /
*/
startCoordinate: {
/**
*
*/
x: number;
/**
*
*/
y: number;
};
/**
* px
*/
startRadius: number;
/**
*
*/
linkedProducts?: (number | DisassemblyLinkedProduct)[] | null;
updatedAt: string;
createdAt: string;
}
/**
*
*
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disassembly-linked-products".
*/
export interface DisassemblyLinkedProduct {
id: number;
/**
*
*/
coordinate: {
/**
*
*/
x: number;
/**
*
*/
y: number;
};
/**
* 使
*/
productName?: string | null;
/**
*
*/
products?: (number | Product)[] | null;
/**
*
*/
preorderProducts?: (number | PreorderProduct)[] | null;
updatedAt: string;
createdAt: string;
}
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-kv". * via the `definition` "payload-kv".
@ -840,6 +939,18 @@ export interface PayloadLockedDocument {
| ({ | ({
relationTo: 'logs'; relationTo: 'logs';
value: number | Log; value: number | Log;
} | null)
| ({
relationTo: 'disassembly-pages';
value: number | DisassemblyPage;
} | null)
| ({
relationTo: 'disassembly-components';
value: number | DisassemblyComponent;
} | null)
| ({
relationTo: 'disassembly-linked-products';
value: number | DisassemblyLinkedProduct;
} | null); } | null);
globalSlug?: string | null; globalSlug?: string | null;
user: { user: {
@ -1067,6 +1178,52 @@ export interface LogsSelect<T extends boolean = true> {
updatedAt?: T; updatedAt?: T;
createdAt?: T; createdAt?: T;
} }
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disassembly-pages_select".
*/
export interface DisassemblyPagesSelect<T extends boolean = true> {
mainImage?: T;
name?: T;
url?: T;
components?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disassembly-components_select".
*/
export interface DisassemblyComponentsSelect<T extends boolean = true> {
label?: T;
startCoordinate?:
| T
| {
x?: T;
y?: T;
};
startRadius?: T;
linkedProducts?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disassembly-linked-products_select".
*/
export interface DisassemblyLinkedProductsSelect<T extends boolean = true> {
coordinate?:
| T
| {
x?: T;
y?: T;
};
productName?: T;
products?: T;
preorderProducts?: T;
updatedAt?: T;
createdAt?: T;
}
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-kv_select". * via the `definition` "payload-kv_select".

View File

@ -12,6 +12,9 @@ import { PreorderProducts } from './collections/PreorderProducts'
import { Announcements } from './collections/Announcements' import { Announcements } from './collections/Announcements'
import { Articles } from './collections/Articles' import { Articles } from './collections/Articles'
import { Logs } from './collections/Logs' import { Logs } from './collections/Logs'
import { DisassemblyPages } from './collections/disassembly/DisassemblyPages'
import { DisassemblyComponents } from './collections/disassembly/DisassemblyComponents'
import { DisassemblyLinkedProducts } from './collections/disassembly/DisassemblyLinkedProducts'
import { AdminSettings } from './globals/AdminSettings' import { AdminSettings } from './globals/AdminSettings'
import { LogsManager } from './globals/LogsManager' import { LogsManager } from './globals/LogsManager'
import { HeroSlider } from './globals/HeroSlider' import { HeroSlider } from './globals/HeroSlider'
@ -48,7 +51,7 @@ export default buildConfig({
}, },
fallbackLanguage: 'zh', fallbackLanguage: 'zh',
}, },
collections: [Users, Media, Products, PreorderProducts, Announcements, Articles, Logs], collections: [Users, Media, Products, PreorderProducts, Announcements, Articles, Logs, DisassemblyPages, DisassemblyComponents, DisassemblyLinkedProducts],
globals: [AdminSettings, LogsManager, HeroSlider, ProductRecommendations, SiteAccess], globals: [AdminSettings, LogsManager, HeroSlider, ProductRecommendations, SiteAccess],
editor: lexicalEditor(), editor: lexicalEditor(),
secret: process.env.PAYLOAD_SECRET || '', secret: process.env.PAYLOAD_SECRET || '',