- NestJS + TypeScript + Prisma + PostgreSQL 工程骨架 - 微信登录安全流程:服务端 code2Session 换 openid 后签发 JWT, session_key 缓存于 Redis,不信任前端 openid - 统一响应/异常处理、JWT 全局鉴权(@Public 豁免)、Swagger 文档 - Prisma 全量核心 schema(用户/分类/商品/设计清单/地址/订单/支付/上传/定制任务)+ seed - 业务模块空壳(商品/分类/设计清单/地址/订单/支付/上传/BullMQ 队列) - Docker 多阶段镜像 + 本地/生产 docker-compose - docs:密钥获取指南、COS SDK 移除记录 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
234 lines
7.1 KiB
SQL
234 lines
7.1 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "ProductStatus" AS ENUM ('DRAFT', 'ON_SALE', 'OFF_SHELF');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "DesignListStatus" AS ENUM ('DRAFT', 'SUBMITTED', 'PROCESSING', 'DONE');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "OrderStatus" AS ENUM ('PENDING', 'PAID', 'PROCESSING', 'SHIPPED', 'COMPLETED', 'CANCELLED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "PaymentProvider" AS ENUM ('WECHAT');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "PaymentStatus" AS ENUM ('PENDING', 'SUCCESS', 'REFUNDED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "CustomizationTaskStatus" AS ENUM ('PENDING', 'RUNNING', 'SUCCESS', 'FAILED');
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "User" (
|
|
"id" TEXT NOT NULL,
|
|
"openid" TEXT NOT NULL,
|
|
"unionid" TEXT,
|
|
"nickname" TEXT,
|
|
"avatar" TEXT,
|
|
"phone" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Category" (
|
|
"id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"parentId" TEXT,
|
|
"sort" INTEGER NOT NULL DEFAULT 0,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Category_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Product" (
|
|
"id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"categoryId" TEXT,
|
|
"price" DECIMAL(10,2) NOT NULL,
|
|
"images" TEXT[],
|
|
"description" TEXT,
|
|
"status" "ProductStatus" NOT NULL DEFAULT 'DRAFT',
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Product_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "DesignList" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"title" TEXT NOT NULL,
|
|
"items" JSONB NOT NULL,
|
|
"status" "DesignListStatus" NOT NULL DEFAULT 'DRAFT',
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "DesignList_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Address" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"phone" TEXT NOT NULL,
|
|
"province" TEXT NOT NULL,
|
|
"city" TEXT NOT NULL,
|
|
"district" TEXT NOT NULL,
|
|
"detail" TEXT NOT NULL,
|
|
"isDefault" BOOLEAN NOT NULL DEFAULT false,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Address_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Order" (
|
|
"id" TEXT NOT NULL,
|
|
"orderNo" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"status" "OrderStatus" NOT NULL DEFAULT 'PENDING',
|
|
"totalAmount" DECIMAL(10,2) NOT NULL,
|
|
"addressSnapshot" JSONB NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Order_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "OrderItem" (
|
|
"id" TEXT NOT NULL,
|
|
"orderId" TEXT NOT NULL,
|
|
"productId" TEXT,
|
|
"name" TEXT NOT NULL,
|
|
"price" DECIMAL(10,2) NOT NULL,
|
|
"quantity" INTEGER NOT NULL,
|
|
|
|
CONSTRAINT "OrderItem_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Payment" (
|
|
"id" TEXT NOT NULL,
|
|
"orderId" TEXT NOT NULL,
|
|
"transactionId" TEXT,
|
|
"provider" "PaymentProvider" NOT NULL DEFAULT 'WECHAT',
|
|
"status" "PaymentStatus" NOT NULL DEFAULT 'PENDING',
|
|
"paidAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Payment_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Upload" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"cosKey" TEXT NOT NULL,
|
|
"url" TEXT NOT NULL,
|
|
"mimetype" TEXT,
|
|
"size" INTEGER,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "Upload_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "CustomizationTask" (
|
|
"id" TEXT NOT NULL,
|
|
"designListId" TEXT,
|
|
"userId" TEXT,
|
|
"status" "CustomizationTaskStatus" NOT NULL DEFAULT 'PENDING',
|
|
"resultUrl" TEXT,
|
|
"queueJobId" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "CustomizationTask_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "User_openid_key" ON "User"("openid");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "User_phone_idx" ON "User"("phone");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Category_parentId_idx" ON "Category"("parentId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Product_categoryId_idx" ON "Product"("categoryId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Product_status_idx" ON "Product"("status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "DesignList_userId_idx" ON "DesignList"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Address_userId_idx" ON "Address"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Order_orderNo_key" ON "Order"("orderNo");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Order_userId_idx" ON "Order"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Order_status_idx" ON "Order"("status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "OrderItem_orderId_idx" ON "OrderItem"("orderId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Payment_orderId_key" ON "Payment"("orderId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Upload_userId_idx" ON "Upload"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CustomizationTask_designListId_idx" ON "CustomizationTask"("designListId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CustomizationTask_status_idx" ON "CustomizationTask"("status");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Category" ADD CONSTRAINT "Category_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Category"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Product" ADD CONSTRAINT "Product_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "Category"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "DesignList" ADD CONSTRAINT "DesignList_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Address" ADD CONSTRAINT "Address_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Order" ADD CONSTRAINT "Order_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "OrderItem" ADD CONSTRAINT "OrderItem_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Order"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "OrderItem" ADD CONSTRAINT "OrderItem_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Payment" ADD CONSTRAINT "Payment_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Order"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Upload" ADD CONSTRAINT "Upload_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CustomizationTask" ADD CONSTRAINT "CustomizationTask_designListId_fkey" FOREIGN KEY ("designListId") REFERENCES "DesignList"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CustomizationTask" ADD CONSTRAINT "CustomizationTask_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|