组件库
This commit is contained in:
parent
c6771a7098
commit
b90005038f
|
|
@ -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()
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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: '该组件下的关联商品信息条目',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
@ -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: '关联的预售商品',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
@ -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: '该拆解页包含的拆解组件列表',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
@ -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
|
|
@ -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";`)
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
@ -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',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
|
||||||
|
|
@ -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".
|
||||||
|
|
|
||||||
|
|
@ -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 || '',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue