feat: 积分商城-供应商-对账-发票3
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import { config } from 'dotenv'
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import { randomBytes, scryptSync } from 'node:crypto'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
config({ path: fileURLToPath(new URL('../.env', import.meta.url)), quiet: true })
|
||||
const prisma = new PrismaClient()
|
||||
try {
|
||||
const username = (process.env.SUPPLIED_ADMIN_USERNAME || 'admin').trim()
|
||||
const password = process.env.SUPPLIED_ADMIN_PASSWORD || `Sp!${randomBytes(12).toString('base64url')}9a`
|
||||
if (!username || username.length > 64 || password.length < 12 || password.length > 128) {
|
||||
throw new Error('账号长度需为 1-64,密码长度需为 12-128')
|
||||
}
|
||||
const tables = await prisma.$queryRaw`SELECT TABLE_NAME AS name FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND LOWER(TABLE_NAME) IN ('user', 'cartitem', 'supplied_cart_item')`
|
||||
const legacyUser = tables.find(row => row.name.toLowerCase() === 'user')
|
||||
const legacyCart = tables.find(row => row.name.toLowerCase() === 'cartitem')
|
||||
if (legacyUser) {
|
||||
const rows = await prisma.$queryRawUnsafe('SELECT COUNT(*) AS count FROM `' + legacyUser.name.replace(/`/g, '``') + '`')
|
||||
if (Number(rows[0].count) > 0) throw new Error('旧 user 表存在数据,未删除,请先处理原有数据')
|
||||
}
|
||||
if (legacyCart) {
|
||||
if (tables.some(row => row.name.toLowerCase() === 'supplied_cart_item')) throw new Error('新旧购物车表同时存在,未覆盖数据')
|
||||
await prisma.$executeRawUnsafe('RENAME TABLE `' + legacyCart.name.replace(/`/g, '``') + '` TO `supplied_cart_item`')
|
||||
}
|
||||
if (legacyUser) await prisma.$executeRawUnsafe('DROP TABLE `' + legacyUser.name.replace(/`/g, '``') + '`')
|
||||
await prisma.$executeRawUnsafe(readFileSync(new URL('./sql/supplied-user.sql', import.meta.url), 'utf8').trim().replace(/;$/, ''))
|
||||
const existing = await prisma.$queryRaw`SELECT id FROM supplied_user WHERE username = ${username} LIMIT 1`
|
||||
if (existing.length) throw new Error('账号已存在,未覆盖原有密码')
|
||||
const salt = randomBytes(16).toString('hex')
|
||||
const hash = scryptSync(password, salt, 64, { N: 32768, r: 8, p: 1, maxmem: 64 * 1024 * 1024 }).toString('hex')
|
||||
const passwordHash = `scrypt$${salt}$${hash}`
|
||||
await prisma.$executeRaw`INSERT INTO supplied_user (username, passwordHash, nickname) VALUES (${username}, ${passwordHash}, ${'管理员'})`
|
||||
console.log(JSON.stringify({ username, password, table: 'supplied_user' }))
|
||||
} catch (error) {
|
||||
console.error(error instanceof Error ? error.message : '初始化账号失败')
|
||||
process.exitCode = 1
|
||||
} finally {
|
||||
await prisma.$disconnect()
|
||||
}
|
||||
@@ -7,16 +7,21 @@ datasource db {
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
mobile String @unique
|
||||
nickname String?
|
||||
avatarUrl String?
|
||||
points Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
model SuppliedUser {
|
||||
id Int @id @default(autoincrement())
|
||||
username String? @unique @db.VarChar(64)
|
||||
virtualId String? @unique @db.VarChar(191)
|
||||
passwordHash String? @db.VarChar(255)
|
||||
nickname String @default("管理员") @db.VarChar(64)
|
||||
enabled Boolean @default(true)
|
||||
tokenHash String? @unique @db.Char(64)
|
||||
tokenExpiresAt DateTime?
|
||||
failedLoginCount Int @default(0)
|
||||
lockedUntil DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
carts CartItem[]
|
||||
@@map("supplied_user")
|
||||
}
|
||||
|
||||
model SupplierProduct {
|
||||
@@ -75,10 +80,10 @@ model CartItem {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
product SupplierProduct @relation(fields: [productId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, productId, skuText])
|
||||
@@unique([userId, productId, skuText], map: "CartItem_userId_productId_skuText_key")
|
||||
@@map("supplied_cart_item")
|
||||
}
|
||||
|
||||
model SupplierOrderMain {
|
||||
|
||||
@@ -18,10 +18,10 @@ SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for cartitem
|
||||
-- Table structure for supplied_cart_item
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `cartitem`;
|
||||
CREATE TABLE `cartitem` (
|
||||
DROP TABLE IF EXISTS `supplied_cart_item`;
|
||||
CREATE TABLE `supplied_cart_item` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`userId` int NOT NULL,
|
||||
`productId` int NOT NULL,
|
||||
@@ -35,7 +35,7 @@ CREATE TABLE `cartitem` (
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of cartitem
|
||||
-- Records of supplied_cart_item
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
@@ -528,24 +528,23 @@ CREATE TABLE `supplier_user_address` (
|
||||
INSERT INTO `supplier_user_address` VALUES (1, 'addr-1785395646503', '99999999', 'b2397ac9a67f476c9833471d27709db1', '谌盼兮', '13545478393', '吉林省', '白山市', '临江市', '未来科技城', '220681', '430213', 1, '2026-07-30 07:14:06.541', '2026-07-30 07:29:34.829', 0);
|
||||
INSERT INTO `supplier_user_address` VALUES (2, 'addr-1788252731181', '99999999', 'c281e124321c8db3a14f0a7c86046c3c', '谌盼兮', '19090230905', '湖北省', '武汉市', '洪山区', '中国地质大学', '420111', '430074', 1, '2026-09-01 08:52:11.226', '2026-09-01 08:52:11.226', 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user`;
|
||||
CREATE TABLE `user` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`mobile` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`nickname` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||
`avatarUrl` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||
`points` int NOT NULL DEFAULT 0,
|
||||
`createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` datetime(3) NOT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `User_mobile_key`(`mobile` ASC) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of user
|
||||
-- ----------------------------
|
||||
CREATE TABLE IF NOT EXISTS `supplied_user` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`username` VARCHAR(64) NULL,
|
||||
`virtualId` VARCHAR(191) COLLATE utf8mb4_bin NULL,
|
||||
`passwordHash` VARCHAR(255) NULL,
|
||||
`nickname` VARCHAR(64) NOT NULL DEFAULT '管理员',
|
||||
`enabled` BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
`tokenHash` CHAR(64) NULL,
|
||||
`tokenExpiresAt` DATETIME(3) NULL,
|
||||
`failedLoginCount` INT NOT NULL DEFAULT 0,
|
||||
`lockedUntil` DATETIME(3) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `supplied_user_username_key` (`username`),
|
||||
UNIQUE KEY `supplied_user_virtualId_key` (`virtualId`),
|
||||
UNIQUE KEY `supplied_user_tokenHash_key` (`tokenHash`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE `supplied_user`
|
||||
ADD COLUMN `virtualId` VARCHAR(191) COLLATE utf8mb4_bin NULL AFTER `username`,
|
||||
ADD UNIQUE KEY `supplied_user_virtualId_key` (`virtualId`),
|
||||
MODIFY COLUMN `username` VARCHAR(64) NULL,
|
||||
MODIFY COLUMN `passwordHash` VARCHAR(255) NULL;
|
||||
@@ -0,0 +1,18 @@
|
||||
CREATE TABLE IF NOT EXISTS `supplied_user` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`username` VARCHAR(64) NULL,
|
||||
`virtualId` VARCHAR(191) COLLATE utf8mb4_bin NULL,
|
||||
`passwordHash` VARCHAR(255) NULL,
|
||||
`nickname` VARCHAR(64) NOT NULL DEFAULT '管理员',
|
||||
`enabled` BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
`tokenHash` CHAR(64) NULL,
|
||||
`tokenExpiresAt` DATETIME(3) NULL,
|
||||
`failedLoginCount` INT NOT NULL DEFAULT 0,
|
||||
`lockedUntil` DATETIME(3) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `supplied_user_username_key` (`username`),
|
||||
UNIQUE KEY `supplied_user_virtualId_key` (`virtualId`),
|
||||
UNIQUE KEY `supplied_user_tokenHash_key` (`tokenHash`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
Reference in New Issue
Block a user