Skip to content

Человеко-ориентированная страница подписки с QR и кнопками импорта в приложения #106

Description

@Postlog

Категория: feature · Приоритет: high · Размер: L · Ранг: 4/10

Что построить

Публичный HTML-лендинг по тому же токену (content-negotiation: браузер → страница, клиент-приложение → конфиг). На странице: прогресс-бар трафика, дата истечения, копируемая ссылка подписки, QR-код ссылки, и сетка кнопок «Добавить в » (Clash/Mihomo, sing-box, Hiddify, v2rayNG, Streisand, Happ) через их URL-схемы (clash://install-config?url=, sing-box://import-remote-profile?url=, hiddify://import/, streisand://import/, happ://add/), фильтруемых по ОС из User-Agent.

Паритет с конкурентами

Marzban (marz-sub-page), Marzneshin/Remnawave (subscription page + deep-links), 3x-ui (встроенный sub-сервер со страницей), Hiddify (new.html self-service portal). Лендинг подписки есть у всех.

Чего не хватает сейчас (код)

Браузер, открывший /sub/mihomo/{token}, получает голый YAML (sub/handler.go отдаёт raw config без UA-разбора). Subgen уже считает Up/Down/Total/Expiry в entity.Subscriber, но визуально их конечному пользователю нигде не показывает. Нет HTML-страницы, нет QR, нет deep-link кнопок.

Зачем

Сегодня конечный пользователь получает лишь YAML и не видит ни остатка квоты, ни срока без приложения, парсящего заголовок. Лендинг даёт нетехническому пользователю самостоятельную проверку статуса, копирование ссылки, скан QR и установку в один тап — самая запрашиваемая user-facing поверхность во всех конкурентах.

Предлагаемая реализация

Новая ogen-операция, отдающая сырой HTML (как admin_shell), вне /admin/api/* (токен = секрет, без auth). В sub-хендлере — UA-гейт: известные клиентские UA (clash, sing-box, v2rayN, hiddify, streisand, happ) получают конфиг как сейчас, браузер — страницу. Каталог приложений (id, имя, иконка, платформы, шаблон URL-схемы, store-ссылки) — типизированный Go-источник с read-эндпоинтом (по образцу config_schema), фронт ничего не хардкодит. QR — вендорной JS-либой (как vue/Sortable/js-yaml, без сборки). Переиспользует QR из #100.

Затронутые файлы

  • openapi/sub.yaml (UA-ветвление / новая sub_page операция), openapi/clients_catalog.yaml (новый)
  • internal/handlers/sub/handler.go (UA-гейт), internal/handlers/sub_page/ (новый, HTML), internal/handlers/clients_catalog/ (новый)
  • internal/entity/ (каталог клиентских приложений)
  • internal/handlers/web/static/ (sub-page.html, qr.min.js вендорный), internal/handlers/web/render.go

Продуктовый ресёрч: изучены аналоги (Marzban/Marzneshin, 3x-ui, Remnawave, Hiddify, sub-store + клиентские стандарты импорта). Паритет и subgen-gap код-обоснованы. Ранг = продуктовый приоритет.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions