添加WVP日志

This commit is contained in:
孙小云 2025-12-10 13:16:29 +08:00
parent de81b78cdc
commit d7436e0229
1 changed files with 435 additions and 11 deletions

View File

@ -1,36 +1,460 @@
<script setup lang="ts">
import { ref } from 'vue'
const GATEWAY_URL = 'http://127.0.0.1:8080'
// getPushList
const pushPage = ref(1)
const pushCount = ref(10)
const pushQuery = ref('')
const pushPushing = ref(true)
const pushMediaServerId = ref('')
const pushLoading = ref(false)
const pushError = ref('')
const pushResult = ref('')
const getPushList = async () => {
pushLoading.value = true
pushError.value = ''
pushResult.value = ''
try {
const params = new URLSearchParams({
page: pushPage.value.toString(),
count: pushCount.value.toString()
})
//
if (pushQuery.value) {
params.append('query', pushQuery.value)
}
if (pushPushing.value !== null && pushPushing.value !== undefined) {
params.append('pushing', pushPushing.value.toString())
}
if (pushMediaServerId.value) {
params.append('mediaServerId', pushMediaServerId.value)
}
const response = await fetch(`${GATEWAY_URL}/wvp/api/push/list?${params}`)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const data = await response.json()
pushResult.value = JSON.stringify(data, null, 2)
} catch (error) {
pushError.value = error instanceof Error ? error.message : '获取推流列表失败'
} finally {
pushLoading.value = false
}
}
// getPushStart
const startPushId = ref(4)
const startLoading = ref(false)
const startError = ref('')
const startResult = ref('')
const getPushStart = async () => {
startLoading.value = true
startError.value = ''
startResult.value = ''
try {
const params = new URLSearchParams({
id: startPushId.value.toString()
})
const response = await fetch(`${GATEWAY_URL}/wvp/api/push/start?${params}`)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const data = await response.json()
startResult.value = JSON.stringify(data, null, 2)
} catch (error) {
startError.value = error instanceof Error ? error.message : '获取播放地址失败'
} finally {
startLoading.value = false
}
}
</script>
<template>
<div class="wvp-container">
<h2>WVP 管理</h2>
<div class="content">
<p>WVP 视频平台管理界面</p>
<h2>WVP 视频平台管理</h2>
<div class="api-section">
<h3>1. 获取推流列表 (getPushList)</h3>
<div class="api-description">
<p>通过网关调用: <code>GET /wvp/api/push/list</code></p>
<p>实际转发到: <code>http://114.67.89.4:9090/api/push/list</code></p>
<p>网关会自动注入 access-token 请求头</p>
</div>
<div class="form-row">
<div class="form-group">
<label>当前页 (page):</label>
<input
v-model.number="pushPage"
type="number"
min="1"
placeholder="1"
/>
</div>
<div class="form-group">
<label>每页数量 (count):</label>
<input
v-model.number="pushCount"
type="number"
min="1"
placeholder="10"
/>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>查询内容 (query) - 可选:</label>
<input
v-model="pushQuery"
type="text"
placeholder="留空表示不过滤"
/>
</div>
<div class="form-group">
<label>流媒体ID (mediaServerId) - 可选:</label>
<input
v-model="pushMediaServerId"
type="text"
placeholder="留空表示不过滤"
/>
</div>
</div>
<div class="form-group">
<label>
<input
v-model="pushPushing"
type="checkbox"
/>
仅显示正在推流的 (pushing)
</label>
</div>
<div class="button-group">
<button @click="getPushList" :disabled="pushLoading">
{{ pushLoading ? '查询中...' : '获取推流列表' }}
</button>
</div>
<div v-if="pushError" class="error">
错误: {{ pushError }}
</div>
<div v-if="pushResult" class="result-preview">
<h4>响应结果:</h4>
<pre>{{ pushResult }}</pre>
</div>
</div>
<div class="api-section">
<h3>2. 获取播放地址 (getPushStart)</h3>
<div class="api-description">
<p>通过网关调用: <code>GET /wvp/api/push/start</code></p>
<p>实际转发到: <code>http://114.67.89.4:9090/api/push/start</code></p>
<p>网关会自动注入 access-token 请求头</p>
<p>返回包括 WebRTCFLVHLSRTMPRTSP 等多种播放地址</p>
</div>
<div class="form-group">
<label>推流ID (id) - 必填:</label>
<input
v-model.number="startPushId"
type="number"
min="1"
placeholder="从推流列表中获取的ID"
/>
<small style="color: #666; display: block; margin-top: 5px;">
提示从上面的推流列表接口返回的数据中获取 id 字段
</small>
</div>
<div class="button-group">
<button @click="getPushStart" :disabled="startLoading">
{{ startLoading ? '获取中...' : '获取播放地址' }}
</button>
</div>
<div v-if="startError" class="error">
错误: {{ startError }}
</div>
<div v-if="startResult" class="result-preview">
<h4>响应结果:</h4>
<pre>{{ startResult }}</pre>
<div class="play-urls-info">
<h4>播放地址说明:</h4>
<table class="urls-table">
<thead>
<tr>
<th>字段</th>
<th>协议</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>rtc</code></td>
<td>WebRTC (HTTP)</td>
<td>低延迟播放推荐</td>
</tr>
<tr>
<td><code>rtcs</code></td>
<td>WebRTC (HTTPS)</td>
<td>低延迟播放HTTPS</td>
</tr>
<tr>
<td><code>flv</code></td>
<td>HTTP-FLV</td>
<td>HTTP 流式播放</td>
</tr>
<tr>
<td><code>ws_flv</code></td>
<td>WebSocket-FLV</td>
<td>WebSocket 流式播放</td>
</tr>
<tr>
<td><code>hls</code></td>
<td>HLS</td>
<td>M3U8 播放</td>
</tr>
<tr>
<td><code>rtmp</code></td>
<td>RTMP</td>
<td>RTMP 播放</td>
</tr>
<tr>
<td><code>rtsp</code></td>
<td>RTSP</td>
<td>RTSP 播放</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.wvp-container {
max-width: 800px;
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
h2 {
margin-bottom: 20px;
margin-bottom: 30px;
color: #333;
}
.content {
.api-section {
background-color: #fff;
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 20px;
background-color: #f5f5f5;
border-radius: 4px;
min-height: 400px;
margin-bottom: 20px;
}
.content p {
.api-section h3 {
margin-top: 0;
margin-bottom: 15px;
color: #2196f3;
font-size: 18px;
}
.api-description {
background-color: #f5f5f5;
padding: 12px;
border-radius: 4px;
margin-bottom: 20px;
}
.api-description p {
margin: 5px 0;
font-size: 14px;
color: #666;
font-size: 16px;
}
.api-description code {
background-color: #e0e0e0;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
font-size: 13px;
color: #d32f2f;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: #333;
font-size: 14px;
}
.form-group input[type="text"],
.form-group input[type="number"] {
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
box-sizing: border-box;
}
.form-group input[type="checkbox"] {
margin-right: 8px;
}
.form-group input:focus {
outline: none;
border-color: #2196f3;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
}
.button-group {
display: flex;
gap: 10px;
margin-top: 20px;
}
button {
padding: 10px 20px;
background-color: #2196f3;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: background-color 0.3s ease;
}
button:hover:not(:disabled) {
background-color: #1976d2;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.error {
margin-top: 15px;
padding: 12px;
background-color: #ffebee;
color: #c62828;
border-radius: 4px;
font-size: 14px;
}
.result-preview {
margin-top: 20px;
padding: 15px;
background-color: #f5f5f5;
border-radius: 4px;
}
.result-preview h4 {
margin-top: 0;
margin-bottom: 10px;
color: #333;
}
.result-preview pre {
background-color: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 13px;
line-height: 1.5;
margin: 0;
}
.play-urls-info {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #ddd;
}
.play-urls-info h4 {
margin-top: 0;
margin-bottom: 15px;
color: #333;
}
.urls-table {
width: 100%;
border-collapse: collapse;
background-color: white;
border-radius: 4px;
overflow: hidden;
}
.urls-table thead {
background-color: #2196f3;
color: white;
}
.urls-table th,
.urls-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #e0e0e0;
}
.urls-table th {
font-weight: 600;
font-size: 14px;
}
.urls-table td {
font-size: 13px;
color: #333;
}
.urls-table tbody tr:hover {
background-color: #f5f5f5;
}
.urls-table tbody tr:last-child td {
border-bottom: none;
}
.urls-table code {
background-color: #e0e0e0;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
font-size: 12px;
color: #d32f2f;
}
</style>