重构 monorepo 并完善网页端订阅与首页体验
- 迁移为 frontend-web、frontend-electron、backend-web 与 docker 部署结构 - 网页端:订阅门禁二次弹窗、套餐/支付组件化、顶栏分组对齐 - 首页:最近文件与模板库布局优化,缩略图对齐,下载与删除操作 - 新增管理后台、支付与云端文件 API,更新 README 与项目规范 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
-- SoonDesign 数据库结构 (UTF-8 无 BOM)
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`email` VARCHAR(190) NOT NULL,
|
||||
`password_hash` VARCHAR(255) NOT NULL,
|
||||
`role` ENUM('user','admin') NOT NULL DEFAULT 'user',
|
||||
`admin_level` ENUM('full','ops') DEFAULT NULL,
|
||||
`status` ENUM('active','disabled') NOT NULL DEFAULT 'active',
|
||||
`created_at` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `email` (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `soon_files` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT UNSIGNED NOT NULL,
|
||||
`name` VARCHAR(190) NOT NULL,
|
||||
`json` LONGTEXT NOT NULL,
|
||||
`size` INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
`version` INT UNSIGNED NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME NOT NULL,
|
||||
`updated_at` DATETIME NOT NULL,
|
||||
`deleted_at` DATETIME DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user` (`user_id`, `deleted_at`, `updated_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `plans` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`code` VARCHAR(64) NOT NULL,
|
||||
`name` VARCHAR(120) NOT NULL,
|
||||
`description` VARCHAR(255) DEFAULT NULL,
|
||||
`price_cents` INT UNSIGNED NOT NULL,
|
||||
`quota_mb` INT UNSIGNED NOT NULL,
|
||||
`max_files` INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
`duration_days` INT UNSIGNED NOT NULL,
|
||||
`features` TEXT DEFAULT NULL,
|
||||
`sort_order` INT NOT NULL DEFAULT 0,
|
||||
`is_recommended` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `code` (`code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT INTO `plans` (`code`,`name`,`description`,`price_cents`,`quota_mb`,`max_files`,`duration_days`,`features`,`sort_order`,`is_recommended`,`is_active`) VALUES
|
||||
('free','免费版','免费体验设计与编辑',0,2048,200,0,
|
||||
'["设计与编辑工具免费使用"]',0,0,1),
|
||||
('member_monthly','月度订阅','按月灵活使用,随时续订',1999,2048,200,30,
|
||||
'["高清预览","成品打印","云端保存","导出设计文件","订阅周期:1 个月"]',10,1,1),
|
||||
('member_quarterly','季度订阅','连续三个月,更省心',5299,2048,200,90,
|
||||
'["高清预览","成品打印","云端保存","导出设计文件","订阅周期:1 季"]',15,0,1),
|
||||
('member_yearly','年度订阅','全年畅享,性价比更高',19999,2048,200,365,
|
||||
'["高清预览","成品打印","云端保存","导出设计文件","订阅周期:1 年"]',20,0,1)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name=VALUES(name),
|
||||
description=VALUES(description),
|
||||
price_cents=VALUES(price_cents),
|
||||
quota_mb=VALUES(quota_mb),
|
||||
max_files=VALUES(max_files),
|
||||
duration_days=VALUES(duration_days),
|
||||
features=VALUES(features),
|
||||
sort_order=VALUES(sort_order),
|
||||
is_recommended=VALUES(is_recommended);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `subscriptions` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT UNSIGNED NOT NULL,
|
||||
`plan_id` INT UNSIGNED NOT NULL,
|
||||
`source_order_id` BIGINT UNSIGNED DEFAULT NULL,
|
||||
`status` ENUM('active','expired','cancelled') NOT NULL DEFAULT 'active',
|
||||
`started_at` DATETIME NOT NULL,
|
||||
`expires_at` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user` (`user_id`, `status`, `expires_at`),
|
||||
KEY `source_order` (`source_order_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pay_orders` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`order_no` VARCHAR(64) NOT NULL,
|
||||
`user_id` INT UNSIGNED NOT NULL,
|
||||
`plan_id` INT UNSIGNED NOT NULL,
|
||||
`channel` ENUM('alipay','wechat') NOT NULL,
|
||||
`amount_cents` INT UNSIGNED NOT NULL,
|
||||
`status` ENUM('pending','paid','cancelled','refunded') NOT NULL DEFAULT 'pending',
|
||||
`refund_status` ENUM('none','pending','approved','rejected') NOT NULL DEFAULT 'none',
|
||||
`refund_reason` TEXT DEFAULT NULL,
|
||||
`refund_note` TEXT DEFAULT NULL,
|
||||
`txn_id` VARCHAR(120) DEFAULT NULL,
|
||||
`client_ip` VARCHAR(64) DEFAULT NULL,
|
||||
`created_at` DATETIME NOT NULL,
|
||||
`paid_at` DATETIME DEFAULT NULL,
|
||||
`cancelled_at` DATETIME DEFAULT NULL,
|
||||
`refunded_at` DATETIME DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `order_no` (`order_no`),
|
||||
KEY `user` (`user_id`),
|
||||
KEY `status` (`status`),
|
||||
KEY `refund_status` (`refund_status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `audit_logs` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`admin_id` INT UNSIGNED NOT NULL,
|
||||
`action` VARCHAR(120) NOT NULL,
|
||||
`target` VARCHAR(190) NOT NULL,
|
||||
`context` TEXT,
|
||||
`ip` VARCHAR(64) DEFAULT NULL,
|
||||
`created_at` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `admin` (`admin_id`, `created_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `settings` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`key` VARCHAR(120) NOT NULL,
|
||||
`value` TEXT NOT NULL,
|
||||
`updated_at` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `k` (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
Reference in New Issue
Block a user