diff --git a/.deploy-tmp/check-fk.js b/.deploy-tmp/check-fk.js new file mode 100644 index 0000000..fafc567 --- /dev/null +++ b/.deploy-tmp/check-fk.js @@ -0,0 +1,15 @@ +// One-off diagnostic — list FK constraints on orders.flash_sale_id +// Run from packages/server so .env is loaded. +const { PrismaClient } = require('@prisma/client') +const p = new PrismaClient() +;(async () => { + const rows = await p.$queryRawUnsafe(` + SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME IN ('orders', 'flash_sales', 'flash_sale_orders') + ORDER BY TABLE_NAME, ORDINAL_POSITION + `) + console.log('FK rows:', JSON.stringify(rows, null, 2)) + await p.$disconnect() +})().catch((e) => { console.error(e); process.exit(1) }) \ No newline at end of file diff --git a/.deploy-tmp/resolve-migration.js b/.deploy-tmp/resolve-migration.js new file mode 100644 index 0000000..eb27431 --- /dev/null +++ b/.deploy-tmp/resolve-migration.js @@ -0,0 +1,33 @@ +// Mark the failed drop_flash_sale migration as rolled_back so deploy can retry. +const { PrismaClient } = require('@prisma/client') +const p = new PrismaClient() +const dump = (x) => JSON.stringify(x, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2) +;(async () => { + const before = await p.$queryRawUnsafe( + `SELECT migration_name, finished_at, rolled_back_at, applied_steps_count + FROM _prisma_migrations + WHERE migration_name = ?`, + '20260910030338_drop_flash_sale' + ) + console.log('before:', dump(before)) + + const result = await p.$executeRawUnsafe( + `UPDATE _prisma_migrations + SET rolled_back_at = NOW() + WHERE migration_name = ? + AND finished_at IS NULL + AND rolled_back_at IS NULL`, + '20260910030338_drop_flash_sale' + ) + console.log('rows updated:', result) + + const after = await p.$queryRawUnsafe( + `SELECT migration_name, finished_at, rolled_back_at, applied_steps_count + FROM _prisma_migrations + WHERE migration_name = ?`, + '20260910030338_drop_flash_sale' + ) + console.log('after:', dump(after)) + + await p.$disconnect() +})().catch((e) => { console.error(e); process.exit(1) }) \ No newline at end of file diff --git a/.deploy-tmp/verify-migration.js b/.deploy-tmp/verify-migration.js new file mode 100644 index 0000000..c109c88 --- /dev/null +++ b/.deploy-tmp/verify-migration.js @@ -0,0 +1,27 @@ +// Verify migration result on production +const { PrismaClient } = require('@prisma/client') +const p = new PrismaClient() +;(async () => { + const tables = await p.$queryRawUnsafe(` + SELECT TABLE_NAME + FROM information_schema.TABLES + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME LIKE '%flash%' + `) + const ordersCol = await p.$queryRawUnsafe(` + SELECT COLUMN_NAME + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'orders' + AND COLUMN_NAME = 'flash_sale_id' + `) + const mig = await p.$queryRawUnsafe(` + SELECT migration_name, finished_at, rolled_back_at + FROM _prisma_migrations + WHERE migration_name = '20260910030338_drop_flash_sale' + `) + console.log('flash tables:', tables) + console.log('orders.flash_sale_id col:', ordersCol) + console.log('migration row:', mig) + await p.$disconnect() +})().catch((e) => { console.error(e); process.exit(1) }) \ No newline at end of file diff --git a/docs/flash-sale-removal.md b/docs/flash-sale-removal.md new file mode 100644 index 0000000..bd39464 --- /dev/null +++ b/docs/flash-sale-removal.md @@ -0,0 +1,41 @@ +# 移除秒杀功能 + +按业务调整下线限时秒杀活动。前后端代码、共享类型、Prisma schema 与迁移均已同步清理。 + +## 清理范围 + +| 层 | 内容 | +| --- | --- | +| 后端模块 | `packages/server/src/flash-sale/`(service、controller、admin controller、dto、测试) | +| 调度任务 | `SchedulerService.handleExpireFlashSaleReservations` 及其依赖注入 | +| 支付流程 | `PaymentService` 中 `flashSaleOrder` 标记为 PAID 的分支 | +| 前端页面 | `pages/flash-sale/detail.vue`、`pages/admin/flash-sales.vue` | +| 前端组件 | `components/FlashSaleSection.vue` | +| 前端状态 | `stores/flash-sale.ts` | +| 前端入口 | `pages/admin/index.vue` 秒杀管理菜单与对应样式 | +| 首页 | `pages/home/index.vue` 中 `FlashSaleSection` 引用 | +| 共享类型 | `shared/src/types/flash-sale.ts`,`enums.ts` 中 `FlashSaleStatus`、`FlashSaleOrderStatus`,以及 `index.ts` 的 re-export | +| 数据库 | Prisma 删除 `FlashSale`、`FlashSaleOrder` 模型、相关枚举与 `Order.flash_sale_id` 字段 | + +## 数据库迁移 + +新增 `packages/server/prisma/migrations/20260910030338_drop_flash_sale/migration.sql`。 +执行 `pnpm prisma migrate deploy` 后以下内容会被移除: + +- `flash_sales`、`flash_sale_orders` 两张表 +- `orders.flash_sale_id` 列与外键 +- `FlashSaleStatus`、`FlashSaleOrderStatus` 枚举 + +迁移以 MySQL 方言编写;SQLite 开发环境由 Prisma shadow database 自动重建。 + +## 验证 + +```bash +pnpm build:shared +pnpm build:server +pnpm test # 包含 payment / scheduler 套件 +``` + +## 回退说明 + +回退需要还原 schema 与源码,本项目不保留 git 自动恢复外的额外兜底。如需重新启用秒杀,按 git 历史恢复即可,并运行 `pnpm prisma migrate reset` 重新初始化数据库。 \ No newline at end of file diff --git a/packages/app/src/components/FlashSaleSection.vue b/packages/app/src/components/FlashSaleSection.vue deleted file mode 100644 index 807954f..0000000 --- a/packages/app/src/components/FlashSaleSection.vue +++ /dev/null @@ -1,185 +0,0 @@ - - - - - diff --git a/packages/app/src/pages.json b/packages/app/src/pages.json index 9a6f730..7d5bec2 100644 --- a/packages/app/src/pages.json +++ b/packages/app/src/pages.json @@ -75,12 +75,6 @@ "navigationStyle": "custom" } }, - { - "path": "pages/flash-sale/detail", - "style": { - "navigationStyle": "custom" - } - }, { "path": "pages/profile/progress", "style": { @@ -171,12 +165,6 @@ "navigationStyle": "custom" } }, - { - "path": "flash-sales", - "style": { - "navigationStyle": "custom" - } - }, { "path": "member-progress", "style": { diff --git a/packages/app/src/pages/admin/flash-sales.vue b/packages/app/src/pages/admin/flash-sales.vue deleted file mode 100644 index ccfaa47..0000000 --- a/packages/app/src/pages/admin/flash-sales.vue +++ /dev/null @@ -1,863 +0,0 @@ -