Прокси на внутренний IP: анализ и скачивания через REST-эндпоинты WordPress (режим proxy/direct, настройки)
This commit is contained in:
1 parent
b3ac9491f6
commit
867fe7bc66
3 files changed
+190
-14
No files matched your search
@@ -37,23 +37,44 @@ zip -r med-diagnostics.zip . -x README.md
|
|||||||
|
|
||||||
## Настройки
|
## Настройки
|
||||||
|
|
||||||
**Настройки → Med Diagnostics** — поле «URL API-бэкенда» (по умолчанию `https://med.my-dpr.ru`).
|
**Настройки → Med Diagnostics**:
|
||||||
|
|
||||||
|
| Поле | Описание |
|
||||||
|
|---|---|
|
||||||
|
| **Режим подключения** | `Через сервер (внутренний IP)` — браузер шлёт видео на этот WordPress, PHP проксирует запрос на внутренний IP бэкенда (по умолчанию, рекомендуется когда WordPress и API на одном сервере). `Напрямую из браузера (CORS)` — браузер обращается к публичному URL API. |
|
||||||
|
| **Внутренний URL бэкенда** | Адрес API, доступный с этого сервера (по умолчанию `http://127.0.0.1:18018`). Используется в режиме «Через сервер». |
|
||||||
|
| **Публичный URL API-бэкенда** | Публичный адрес Flask-приложения (по умолчанию `https://med.my-dpr.ru`). Используется в режиме «Напрямую» и для ссылки «Поделиться». |
|
||||||
|
|
||||||
Можно также переопределить кодом:
|
Можно также переопределить кодом:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
add_filter('med_diag_api_url', fn() => 'https://другой-домен.ru');
|
add_filter('med_diag_api_url', fn() => 'https://другой-домен.ru');
|
||||||
|
add_filter('med_diag_internal_url', fn() => 'http://10.0.0.5:18018');
|
||||||
|
add_filter('med_diag_mode', fn() => 'direct');
|
||||||
```
|
```
|
||||||
|
|
||||||
## Как это работает
|
## Как это работает
|
||||||
|
|
||||||
- Плагин выводит ту же вёрстку, что и главная страница сервиса (стили с префиксом `med-`, чтобы не конфликтовать с темой).
|
- **Режим «Через сервер» (по умолчанию)**: JS отправляет видео на REST-эндпоинт этого же WordPress (`/wp-json/med-diag/v1/analyze`), PHP пересылает его на внутренний IP бэкенда (`http://127.0.0.1:18018/analyze`). Скачивания PDF/DOCX/видео идут через `/wp-json/med-diag/v1/download/<id>/<type>`. CORS не нужен — все запросы same-origin.
|
||||||
- JS отправляет видео на API-бэкенд (`POST /analyze`) с абсолютным URL — поэтому нужен CORS на стороне Flask.
|
- **Режим «Напрямую»**: JS отправляет видео на публичный URL API (`POST /analyze`) — тогда нужен CORS на стороне Flask.
|
||||||
- Результат (сводка, показатели, рекомендации, кнопки PDF/DOCX/видео/поделиться) рендерится на странице WordPress.
|
- Результат (сводка, показатели, рекомендации, кнопки PDF/DOCX/видео/поделиться) рендерится на странице WordPress.
|
||||||
- Сканирование с камеры работает на мобильных (canvas 720×720 + MediaRecorder).
|
- Сканирование с камеры работает на мобильных (canvas 720×720 + MediaRecorder).
|
||||||
|
|
||||||
|
## Требования к серверу WordPress (режим «Через сервер»)
|
||||||
|
|
||||||
|
Видео сначала загружается в PHP, поэтому в `php.ini` должны быть подняты лимиты:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
upload_max_filesize = 100M
|
||||||
|
post_max_size = 100M
|
||||||
|
max_execution_time = 300
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить текущие значения: `php -i | grep -E "upload_max_filesize|post_max_size|max_execution_time"`.
|
||||||
|
|
||||||
## Требования к бэкенду (Flask)
|
## Требования к бэкенду (Flask)
|
||||||
|
|
||||||
В `app.py` серверного репозитория уже добавлена поддержка CORS:
|
В `app.py` серверного репозитория уже добавлена поддержка CORS (нужна только в режиме «Напрямую»):
|
||||||
|
|
||||||
- `Access-Control-Allow-Origin` — по умолчанию `*`, можно ограничить через env `CORS_ORIGINS` (список через запятую, например `https://site1.ru,https://site2.ru`).
|
- `Access-Control-Allow-Origin` — по умолчанию `*`, можно ограничить через env `CORS_ORIGINS` (список через запятую, например `https://site1.ru,https://site2.ru`).
|
||||||
- Preflight `OPTIONS /analyze` возвращает `204`.
|
- Preflight `OPTIONS /analyze` возвращает `204`.
|
||||||
@@ -69,7 +90,8 @@ add_filter('med_diag_api_url', fn() => 'https://другой-домен.ru');
|
|||||||
|
|
||||||
- Шорткод используйте **один раз на странице** (id элементов фиксированы).
|
- Шорткод используйте **один раз на странице** (id элементов фиксированы).
|
||||||
- Для работы сканирования с камеры нужен HTTPS на сайте WordPress (getUserMedia требует secure context).
|
- Для работы сканирования с камеры нужен HTTPS на сайте WordPress (getUserMedia требует secure context).
|
||||||
- Загрузка видео идёт напрямую в API-бэкенд — убедитесь, что `client_max_body_size` в nginx бэкенда ≥ 100 МБ.
|
- В режиме «Через сервер» видео загружается в PHP — следите за лимитами `upload_max_filesize`/`post_max_size`/`max_execution_time` (см. выше).
|
||||||
|
- Ссылка «Поделиться» всегда ведёт на публичный URL API (`/r/<share_id>`).
|
||||||
|
|
||||||
## Структура
|
## Структура
|
||||||
|
|
||||||
|
|||||||
+19
-5
@@ -3,6 +3,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var API_URL = (window.MED_DIAG && MED_DIAG.apiUrl) || 'https://med.my-dpr.ru';
|
var API_URL = (window.MED_DIAG && MED_DIAG.apiUrl) || 'https://med.my-dpr.ru';
|
||||||
|
var PROXY_URL = (window.MED_DIAG && MED_DIAG.proxyUrl) || '';
|
||||||
|
var MODE = (window.MED_DIAG && MED_DIAG.mode) || 'proxy';
|
||||||
|
var USE_PROXY = (MODE === 'proxy') && !!PROXY_URL;
|
||||||
|
|
||||||
// Абсолютный URL: если ссылка относительная — добавляем домен API
|
// Абсолютный URL: если ссылка относительная — добавляем домен API
|
||||||
function absUrl(url) {
|
function absUrl(url) {
|
||||||
@@ -10,6 +13,13 @@
|
|||||||
return url.indexOf('http') === 0 ? url : API_URL + url;
|
return url.indexOf('http') === 0 ? url : API_URL + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URL для скачивания: в режиме прокси — через этот же WordPress (PHP → внутренний IP)
|
||||||
|
function downloadUrl(path) {
|
||||||
|
if (!path) return path;
|
||||||
|
if (path.indexOf('http') === 0) return path;
|
||||||
|
return USE_PROXY ? PROXY_URL + path : API_URL + path;
|
||||||
|
}
|
||||||
|
|
||||||
var uploadArea = document.getElementById('uploadArea');
|
var uploadArea = document.getElementById('uploadArea');
|
||||||
var fileInput = document.getElementById('fileInput');
|
var fileInput = document.getElementById('fileInput');
|
||||||
var analyzeBtn = document.getElementById('analyzeBtn');
|
var analyzeBtn = document.getElementById('analyzeBtn');
|
||||||
@@ -61,11 +71,15 @@
|
|||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
formData.append('video', blob, filename);
|
formData.append('video', blob, filename);
|
||||||
|
|
||||||
|
// В режиме прокси шлём на этот же WordPress (PHP перешлёт на внутренний IP бэкенда),
|
||||||
|
// иначе — напрямую на публичный URL API.
|
||||||
|
var analyzeUrl = USE_PROXY ? PROXY_URL + '/analyze' : API_URL + '/analyze';
|
||||||
|
|
||||||
// Автоповтор при обрыве соединения (нестабильная мобильная сеть)
|
// Автоповтор при обрыве соединения (нестабильная мобильная сеть)
|
||||||
var MAX_ATTEMPTS = 3;
|
var MAX_ATTEMPTS = 3;
|
||||||
for (var attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
for (var attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
||||||
try {
|
try {
|
||||||
var response = await fetch(API_URL + '/analyze', {
|
var response = await fetch(analyzeUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
});
|
});
|
||||||
@@ -119,7 +133,7 @@
|
|||||||
var html = '<div class="med-error-box"><strong>Ошибка:</strong> ' + msg + '</div>';
|
var html = '<div class="med-error-box"><strong>Ошибка:</strong> ' + msg + '</div>';
|
||||||
if (videoUrl) {
|
if (videoUrl) {
|
||||||
html += '<div style="text-align:center; margin-top:15px">' +
|
html += '<div style="text-align:center; margin-top:15px">' +
|
||||||
'<a class="med-btn-download" href="' + absUrl(videoUrl) + '">🎬 Скачать записанное видео</a>' +
|
'<a class="med-btn-download" href="' + downloadUrl(videoUrl) + '">🎬 Скачать записанное видео</a>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
resultContent.innerHTML = html;
|
resultContent.innerHTML = html;
|
||||||
@@ -134,10 +148,10 @@
|
|||||||
// Кнопки скачивания (вверху блока результатов)
|
// Кнопки скачивания (вверху блока результатов)
|
||||||
if (data.share_id) {
|
if (data.share_id) {
|
||||||
html += '<div class="med-download-buttons">' +
|
html += '<div class="med-download-buttons">' +
|
||||||
'<a class="med-btn-download" href="' + API_URL + '/download/' + data.share_id + '/pdf">📄 Скачать PDF</a>' +
|
'<a class="med-btn-download" href="' + downloadUrl('/download/' + data.share_id + '/pdf') + '">📄 Скачать PDF</a>' +
|
||||||
'<a class="med-btn-download" href="' + API_URL + '/download/' + data.share_id + '/docx">📝 Скачать DOCX</a>';
|
'<a class="med-btn-download" href="' + downloadUrl('/download/' + data.share_id + '/docx') + '">📝 Скачать DOCX</a>';
|
||||||
if (data.video_url) {
|
if (data.video_url) {
|
||||||
html += '<a class="med-btn-download" href="' + absUrl(data.video_url) + '">🎬 Скачать видео</a>';
|
html += '<a class="med-btn-download" href="' + downloadUrl(data.video_url) + '">🎬 Скачать видео</a>';
|
||||||
}
|
}
|
||||||
html += '<a class="med-btn-download" href="https://max.ru/miac_dnr_bot" target="_blank" rel="noopener">🏥 Запись на диспанцеризацию</a>' +
|
html += '<a class="med-btn-download" href="https://max.ru/miac_dnr_bot" target="_blank" rel="noopener">🏥 Запись на диспанцеризацию</a>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|||||||
+144
-4
@@ -2,7 +2,7 @@
|
|||||||
/**
|
/**
|
||||||
* Plugin Name: Med Diagnostics
|
* Plugin Name: Med Diagnostics
|
||||||
* Description: Интеграция сервиса «Диагностика по видео» (med.my-dpr.ru) в WordPress. Выводит вёрстку сервиса через шорткод [med_diagnostics].
|
* Description: Интеграция сервиса «Диагностика по видео» (med.my-dpr.ru) в WordPress. Выводит вёрстку сервиса через шорткод [med_diagnostics].
|
||||||
* Version: 1.0.0
|
* Version: 1.1.0
|
||||||
* Author: apuc
|
* Author: apuc
|
||||||
* License: GPL-2.0-or-later
|
* License: GPL-2.0-or-later
|
||||||
* Text Domain: med-diagnostics
|
* Text Domain: med-diagnostics
|
||||||
@@ -18,11 +18,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
exit; // Прямой доступ запрещён
|
exit; // Прямой доступ запрещён
|
||||||
}
|
}
|
||||||
|
|
||||||
define( 'MED_DIAG_VERSION', '1.0.0' );
|
define( 'MED_DIAG_VERSION', '1.1.0' );
|
||||||
define( 'MED_DIAG_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
define( 'MED_DIAG_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL API-бэкенда (Flask-приложение med.my-dpr.ru).
|
* URL API-бэкенда (Flask-приложение med.my-dpr.ru).
|
||||||
|
* Используется в режиме «напрямую» и для публичных ссылок (share).
|
||||||
* Можно переопределить фильтром: add_filter('med_diag_api_url', fn() => 'https://...');
|
* Можно переопределить фильтром: add_filter('med_diag_api_url', fn() => 'https://...');
|
||||||
*/
|
*/
|
||||||
function med_diag_api_url() {
|
function med_diag_api_url() {
|
||||||
@@ -30,6 +31,26 @@ function med_diag_api_url() {
|
|||||||
return apply_filters( 'med_diag_api_url', untrailingslashit( $url ) );
|
return apply_filters( 'med_diag_api_url', untrailingslashit( $url ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Внутренний URL API-бэкенда (для проксирования через PHP).
|
||||||
|
* По умолчанию — внутренний IP сервера, где стоит и WordPress, и API.
|
||||||
|
* Можно переопределить фильтром: add_filter('med_diag_internal_url', fn() => 'http://10.0.0.5:18018');
|
||||||
|
*/
|
||||||
|
function med_diag_internal_url() {
|
||||||
|
$url = get_option( 'med_diag_internal_url', 'http://127.0.0.1:18018' );
|
||||||
|
return apply_filters( 'med_diag_internal_url', untrailingslashit( $url ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Режим подключения к бэкенду:
|
||||||
|
* 'proxy' — браузер шлёт запрос на этот же WordPress, PHP проксирует на внутренний IP (по умолчанию);
|
||||||
|
* 'direct' — браузер шлёт запрос напрямую на публичный URL API (нужен CORS на бэкенде).
|
||||||
|
*/
|
||||||
|
function med_diag_mode() {
|
||||||
|
$mode = get_option( 'med_diag_mode', 'proxy' );
|
||||||
|
return apply_filters( 'med_diag_mode', in_array( $mode, array( 'proxy', 'direct' ), true ) ? $mode : 'proxy' );
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── Регистрация ассетов ─────────────────────────────────── */
|
/* ─── Регистрация ассетов ─────────────────────────────────── */
|
||||||
|
|
||||||
add_action( 'wp_enqueue_scripts', 'med_diag_register_assets' );
|
add_action( 'wp_enqueue_scripts', 'med_diag_register_assets' );
|
||||||
@@ -50,9 +71,100 @@ function med_diag_register_assets() {
|
|||||||
);
|
);
|
||||||
wp_localize_script( 'med-diag-js', 'MED_DIAG', array(
|
wp_localize_script( 'med-diag-js', 'MED_DIAG', array(
|
||||||
'apiUrl' => med_diag_api_url(),
|
'apiUrl' => med_diag_api_url(),
|
||||||
|
'proxyUrl' => rest_url( 'med-diag/v1' ),
|
||||||
|
'mode' => med_diag_mode(),
|
||||||
) );
|
) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ─── Прокси на внутренний IP (REST) ──────────────────────── */
|
||||||
|
|
||||||
|
add_action( 'rest_api_init', 'med_diag_register_routes' );
|
||||||
|
|
||||||
|
function med_diag_register_routes() {
|
||||||
|
// Анализ: браузер → этот WordPress → внутренний IP бэкенда
|
||||||
|
register_rest_route( 'med-diag/v1', '/analyze', array(
|
||||||
|
'methods' => 'POST',
|
||||||
|
'permission_callback' => '__return_true',
|
||||||
|
'callback' => 'med_diag_proxy_analyze',
|
||||||
|
) );
|
||||||
|
|
||||||
|
// Скачивания (PDF/DOCX/видео): /download/<id>/<pdf|docx|video>
|
||||||
|
register_rest_route( 'med-diag/v1', '/download/(?P<id>[^/]+)/(?P<type>[a-z]+)', array(
|
||||||
|
'methods' => 'GET',
|
||||||
|
'permission_callback' => '__return_true',
|
||||||
|
'callback' => 'med_diag_proxy_download',
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
function med_diag_proxy_analyze( $request ) {
|
||||||
|
$files = $request->get_file_params();
|
||||||
|
if ( empty( $files['video'] ) ) {
|
||||||
|
return new WP_Error( 'med_diag_no_video', 'Файл video не получен', array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
$file = $files['video'];
|
||||||
|
if ( $file['error'] !== UPLOAD_ERR_OK ) {
|
||||||
|
return new WP_Error( 'med_diag_upload_error', 'Ошибка загрузки файла (код ' . $file['error'] . ')', array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
if ( $file['size'] > 100 * 1024 * 1024 ) {
|
||||||
|
return new WP_Error( 'med_diag_too_large', 'Видео больше 100 МБ', array( 'status' => 413 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$boundary = wp_generate_password( 24, false );
|
||||||
|
$body = '--' . $boundary . "\r\n";
|
||||||
|
$body .= 'Content-Disposition: form-data; name="video"; filename="' . basename( $file['name'] ) . '"' . "\r\n";
|
||||||
|
$body .= 'Content-Type: ' . $file['type'] . "\r\n\r\n";
|
||||||
|
$body .= file_get_contents( $file['tmp_name'] ) . "\r\n";
|
||||||
|
$body .= '--' . $boundary . "--\r\n";
|
||||||
|
|
||||||
|
$response = wp_remote_post( med_diag_internal_url() . '/analyze', array(
|
||||||
|
'timeout' => 300,
|
||||||
|
'headers' => array( 'Content-Type' => 'multipart/form-data; boundary=' . $boundary ),
|
||||||
|
'body' => $body,
|
||||||
|
) );
|
||||||
|
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
return new WP_Error( 'med_diag_proxy_error', 'Бэкенд недоступен: ' . $response->get_error_message(), array( 'status' => 502 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = wp_remote_retrieve_response_code( $response );
|
||||||
|
$data = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||||
|
if ( json_last_error() !== JSON_ERROR_NONE ) {
|
||||||
|
return new WP_Error( 'med_diag_bad_response', 'Некорректный ответ бэкенда', array( 'status' => 502 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WP_REST_Response( $data, $status );
|
||||||
|
}
|
||||||
|
|
||||||
|
function med_diag_proxy_download( $request ) {
|
||||||
|
$id = rawurlencode( $request['id'] );
|
||||||
|
$type = $request['type'];
|
||||||
|
|
||||||
|
$response = wp_remote_get( med_diag_internal_url() . '/download/' . $id . '/' . $type, array(
|
||||||
|
'timeout' => 300,
|
||||||
|
) );
|
||||||
|
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
return new WP_Error( 'med_diag_proxy_error', 'Бэкенд недоступен', array( 'status' => 502 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = wp_remote_retrieve_response_code( $response );
|
||||||
|
if ( $status !== 200 ) {
|
||||||
|
return new WP_Error( 'med_diag_download_error', 'Ошибка скачивания (HTTP ' . $status . ')', array( 'status' => $status ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = wp_remote_retrieve_body( $response );
|
||||||
|
$headers = wp_remote_retrieve_headers( $response );
|
||||||
|
$content_type = isset( $headers['content-type'] ) ? $headers['content-type'] : 'application/octet-stream';
|
||||||
|
|
||||||
|
$filename = 'diagnostic_' . $request['id'] . '.' . ( 'video' === $type ? 'webm' : $type );
|
||||||
|
|
||||||
|
header( 'Content-Type: ' . $content_type );
|
||||||
|
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
|
||||||
|
header( 'Content-Length: ' . strlen( $body ) );
|
||||||
|
echo $body;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── Шорткод ─────────────────────────────────────────────── */
|
/* ─── Шорткод ─────────────────────────────────────────────── */
|
||||||
|
|
||||||
add_shortcode( 'med_diagnostics', 'med_diag_shortcode' );
|
add_shortcode( 'med_diagnostics', 'med_diag_shortcode' );
|
||||||
@@ -150,6 +262,16 @@ function med_diag_register_settings() {
|
|||||||
'sanitize_callback' => 'esc_url_raw',
|
'sanitize_callback' => 'esc_url_raw',
|
||||||
'default' => 'https://med.my-dpr.ru',
|
'default' => 'https://med.my-dpr.ru',
|
||||||
) );
|
) );
|
||||||
|
register_setting( 'med_diag_settings', 'med_diag_internal_url', array(
|
||||||
|
'type' => 'string',
|
||||||
|
'sanitize_callback' => 'esc_url_raw',
|
||||||
|
'default' => 'http://127.0.0.1:18018',
|
||||||
|
) );
|
||||||
|
register_setting( 'med_diag_settings', 'med_diag_mode', array(
|
||||||
|
'type' => 'string',
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
'default' => 'proxy',
|
||||||
|
) );
|
||||||
}
|
}
|
||||||
|
|
||||||
function med_diag_settings_page() {
|
function med_diag_settings_page() {
|
||||||
@@ -160,11 +282,29 @@ function med_diag_settings_page() {
|
|||||||
<?php settings_fields( 'med_diag_settings' ); ?>
|
<?php settings_fields( 'med_diag_settings' ); ?>
|
||||||
<table class="form-table" role="presentation">
|
<table class="form-table" role="presentation">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><label for="med_diag_api_url">URL API-бэкенда</label></th>
|
<th scope="row"><label for="med_diag_mode">Режим подключения</label></th>
|
||||||
|
<td>
|
||||||
|
<select id="med_diag_mode" name="med_diag_mode">
|
||||||
|
<option value="proxy" <?php selected( med_diag_mode(), 'proxy' ); ?>>Через сервер (внутренний IP)</option>
|
||||||
|
<option value="direct" <?php selected( med_diag_mode(), 'direct' ); ?>>Напрямую из браузера (CORS)</option>
|
||||||
|
</select>
|
||||||
|
<p class="description">«Через сервер» — браузер шлёт видео на этот WordPress, PHP проксирует запрос на внутренний IP бэкенда (рекомендуется, когда WordPress и API на одном сервере). «Напрямую» — браузер обращается к публичному URL API (нужен CORS на бэкенде).</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><label for="med_diag_internal_url">Внутренний URL бэкенда</label></th>
|
||||||
|
<td>
|
||||||
|
<input type="url" id="med_diag_internal_url" name="med_diag_internal_url"
|
||||||
|
value="<?php echo esc_attr( med_diag_internal_url() ); ?>" class="regular-text" />
|
||||||
|
<p class="description">Адрес API-бэкенда, доступный с этого сервера (по умолчанию http://127.0.0.1:18018). Используется в режиме «Через сервер».</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><label for="med_diag_api_url">Публичный URL API-бэкенда</label></th>
|
||||||
<td>
|
<td>
|
||||||
<input type="url" id="med_diag_api_url" name="med_diag_api_url"
|
<input type="url" id="med_diag_api_url" name="med_diag_api_url"
|
||||||
value="<?php echo esc_attr( med_diag_api_url() ); ?>" class="regular-text" />
|
value="<?php echo esc_attr( med_diag_api_url() ); ?>" class="regular-text" />
|
||||||
<p class="description">Адрес Flask-приложения, которое выполняет анализ (по умолчанию https://med.my-dpr.ru).</p>
|
<p class="description">Публичный адрес Flask-приложения (по умолчанию https://med.my-dpr.ru). Используется в режиме «Напрямую» и для ссылки «Поделиться».</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Reference in new issue
Block a user