feat: публичные лендинг-страницы для быстрой покупки VPN-подписок

- QuickPurchase: публичная страница покупки с выбором тарифа/периода/оплаты
- PurchaseSuccess: статус покупки с поллингом и копированием ссылки
- AdminLandings: управление лендингами (создание, сортировка, удаление)
- AdminLandingEditor: полнофункциональный редактор лендинга
- API-клиент landings.ts для всех эндпоинтов
- Роутинг /buy/:slug и /buy/success/:token
- Локализация ru/en/zh/fa для всех текстов лендинга
- Санитизация HTML/CSS, rate limit защита, DOMPurify
This commit is contained in:
Fringg
2026-03-06 07:02:21 +03:00
parent e278fec506
commit 8b5d777f0a
16 changed files with 3813 additions and 766 deletions

View File

@@ -866,7 +866,8 @@
"roleAssign": "角色分配",
"policies": "访问策略",
"auditLog": "审计日志",
"salesStats": "销售统计"
"salesStats": "销售统计",
"landings": "落地页"
},
"panel": {
"title": "管理面板",
@@ -899,7 +900,8 @@
"roleAssignDesc": "分配和撤销用户角色",
"policiesDesc": "配置ABAC访问控制策略",
"auditLogDesc": "查看系统活动和访问历史",
"salesStatsDesc": "销售分析与趋势"
"salesStatsDesc": "销售分析与趋势",
"landingsDesc": "快速购买落地页"
},
"salesStats": {
"title": "销售统计",
@@ -2863,6 +2865,51 @@
"loadFailed": "加载审计日志失败",
"retry": "重试"
}
},
"landings": {
"title": "落地页",
"create": "创建落地页",
"edit": "编辑",
"slug": "URL标识符",
"slugHint": "小写字母、数字和连字符",
"pageTitle": "标题",
"subtitle": "副标题",
"footerText": "底部文本 (HTML)",
"features": "功能特点",
"addFeature": "添加",
"featureIcon": "图标",
"featureTitle": "标题",
"featureDesc": "描述",
"tariffs": "套餐",
"selectTariffs": "选择套餐",
"periods": "周期",
"paymentMethods": "支付方式",
"addMethod": "添加方式",
"methodId": "方式ID",
"methodName": "名称",
"methodDesc": "描述",
"methodIcon": "图标URL",
"gifts": "礼物",
"giftEnabled": "礼物购买",
"customCss": "CSS",
"seo": "SEO",
"metaTitle": "Meta标题",
"metaDesc": "Meta描述",
"active": "已激活",
"inactive": "未激活",
"purchases": "次购买",
"copyUrl": "复制URL",
"urlCopied": "URL已复制",
"deleteConfirm": "删除落地页「{{title}}」?",
"created": "落地页已创建",
"updated": "落地页已更新",
"deleted": "落地页已删除",
"saveOrder": "保存排序",
"orderSaved": "排序已保存",
"general": "基本设置",
"content": "内容",
"save": "保存",
"back": "返回"
}
},
"adminUpdates": {
@@ -3415,5 +3462,44 @@
"error": "合并失败,请稍后重试。",
"expiresIn": "剩余 {{minutes}} 分钟",
"merging": "合并中..."
},
"landing": {
"notFound": "页面未找到",
"forMe": "为自己",
"asGift": "作为礼物",
"contactLabel": "您的邮箱或 @用户名",
"yourContact": "您的邮箱或 @用户名",
"contactPlaceholder": "email@example.com 或 @username",
"contactHint": "输入邮箱或 Telegram @用户名",
"recipientLabel": "赠送对象",
"recipientPlaceholder": "收件人邮箱或 @用户名",
"giftMessageLabel": "祝福语(可选)",
"giftMessagePlaceholder": "写一段祝福语...",
"chooseTariff": "选择套餐",
"devices": "设备",
"paymentMethod": "支付方式",
"processing": "处理中...",
"payButton": "支付 {{price}}",
"accessFor": "{{period}} 访问权限",
"purchaseError": "创建支付失败",
"purchaseNotFound": "未找到购买记录",
"awaitingPayment": "等待支付",
"awaitingPaymentDesc": "请在打开的窗口中完成支付",
"purchaseSuccess": "支付成功!",
"keySentTo": "订阅密钥已发送至 {{contact}}",
"giftSentTo": "礼物已发送至 {{contact}}",
"purchaseFailed": "支付失败",
"purchaseFailedDesc": "支付未成功,请重试。",
"subscriptionLink": "订阅链接",
"daysAccess": "天访问权限",
"error": "错误",
"gb": "GB",
"selectedTariff": "套餐",
"period": "时长",
"total": "总计",
"pay": "支付",
"choosePeriod": "选择时长",
"copied": "已复制!",
"copyLink": "复制链接"
}
}