Web 端数据交互与 design2 布局修复
统一门户 JSON 契约:新增 GET /templates/{id},模板/云文件/保存/打开走虚拟 key;
layer 保存弹层替代 prompt,本地 .soon 已登录后台 POST 登记;修复保存静默失败与 design2 全宽布局。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -16,7 +16,7 @@ final class MembershipService
|
||||
$stmt = Db::pdo()->query(
|
||||
'SELECT id, code, name, description, price_cents, quota_mb, max_files, duration_days, '
|
||||
. 'features, sort_order, is_recommended, is_active FROM plans '
|
||||
. 'WHERE is_active = 1 AND code = "member_lifetime" AND price_cents > 0 '
|
||||
. 'WHERE is_active = 1 AND code = \'member_lifetime\' AND price_cents > 0 '
|
||||
. 'ORDER BY sort_order ASC, price_cents ASC'
|
||||
);
|
||||
$items = [];
|
||||
@@ -34,7 +34,7 @@ final class MembershipService
|
||||
$stmt = $pdo->prepare(
|
||||
'SELECT p.*, s.id AS subscription_id, s.expires_at AS subscription_expires_at, s.started_at AS subscription_started_at '
|
||||
. 'FROM subscriptions s JOIN plans p ON p.id = s.plan_id '
|
||||
. 'WHERE s.user_id = :u AND s.status = "active" AND s.expires_at > NOW() '
|
||||
. 'WHERE s.user_id = :u AND s.status = \'active\' AND s.expires_at > NOW() '
|
||||
. 'ORDER BY s.expires_at DESC LIMIT 1'
|
||||
);
|
||||
$stmt->execute(['u' => $userId]);
|
||||
@@ -70,7 +70,7 @@ final class MembershipService
|
||||
$memberQuota = (int)Config::get('limits.member_quota_mb', 2048);
|
||||
$memberFiles = (int)Config::get('limits.member_max_files', 200);
|
||||
$freeQuota = (int)Config::get('limits.free_quota_mb', $memberQuota);
|
||||
$freeStmt = $pdo->prepare('SELECT * FROM plans WHERE code = "free" AND is_active = 1 LIMIT 1');
|
||||
$freeStmt = $pdo->prepare('SELECT * FROM plans WHERE code = \'free\' AND is_active = 1 LIMIT 1');
|
||||
$freeStmt->execute();
|
||||
$freeRow = $freeStmt->fetch();
|
||||
if ($freeRow) {
|
||||
@@ -108,13 +108,32 @@ final class MembershipService
|
||||
{
|
||||
$stmt = Db::pdo()->prepare(
|
||||
'SELECT 1 FROM subscriptions s JOIN plans p ON p.id = s.plan_id '
|
||||
. 'WHERE s.user_id = :u AND s.status = "active" AND s.expires_at > NOW() '
|
||||
. 'AND p.code <> "free" AND p.price_cents > 0 LIMIT 1'
|
||||
. 'WHERE s.user_id = :u AND s.status = \'active\' AND s.expires_at > NOW() '
|
||||
. 'AND p.code <> \'free\' AND p.price_cents > 0 LIMIT 1'
|
||||
);
|
||||
$stmt->execute(['u' => $userId]);
|
||||
return (bool)$stmt->fetchColumn();
|
||||
}
|
||||
|
||||
/** @return array{is_member:bool,tier:string,name:string,subscription:array<string,mixed>} */
|
||||
public static function membershipSummary(int $userId): array
|
||||
{
|
||||
if (self::isActiveMember($userId)) {
|
||||
return [
|
||||
'is_member' => true,
|
||||
'tier' => 'member',
|
||||
'name' => '会员',
|
||||
'subscription' => ['status' => 'active'],
|
||||
];
|
||||
}
|
||||
return [
|
||||
'is_member' => false,
|
||||
'tier' => 'free',
|
||||
'name' => '普通用户',
|
||||
'subscription' => ['status' => 'free'],
|
||||
];
|
||||
}
|
||||
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
public static function recentOrders(int $userId, int $limit = 8): array
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user