ai-clone/frontend-ai/pages/api-test/api-test.vue
2026-03-05 14:29:21 +08:00

327 lines
6.2 KiB
Vue

<template>
<view class="api-test-container">
<view class="header">
<text class="title">🔧 API 配置测试</text>
</view>
<!-- 环境信息 -->
<env-switcher></env-switcher>
<!-- 测试列表 -->
<view class="test-section">
<view class="section-title">📋 API 端点测试</view>
<view
v-for="(test, index) in tests"
:key="index"
class="test-item"
>
<view class="test-header">
<text class="test-name">{{ test.name }}</text>
<text :class="['test-status', test.status]">
{{ test.statusText }}
</text>
</view>
<view class="test-url">{{ test.url }}</view>
<view v-if="test.result" class="test-result">
<text class="result-label">结果:</text>
<text class="result-value">{{ test.result }}</text>
</view>
<button
class="test-btn"
:disabled="test.loading"
@click="runTest(test)"
>
{{ test.loading ? '测试中...' : '运行测试' }}
</button>
</view>
</view>
<!-- 批量测试 -->
<view class="batch-actions">
<button class="batch-btn" @click="runAllTests">
🚀 运行所有测试
</button>
<button class="batch-btn clear" @click="clearResults">
<image src="/static/iconfont/delete.svg" class="delete-icon" mode="aspectFit"></image>
清空结果
</button>
</view>
</view>
</template>
<script>
import { API_BASE, API_ENDPOINTS, buildURL, request } from '@/config/api.js';
import EnvSwitcher from '@/components/env-switcher.vue';
export default {
components: {
EnvSwitcher
},
data() {
return {
tests: [
{
name: '获取视频列表',
url: buildURL(API_ENDPOINTS.revival.getList),
method: 'GET',
status: 'pending',
statusText: '待测试',
loading: false,
result: ''
},
{
name: '获取音色列表',
url: buildURL(API_ENDPOINTS.voice.getList),
method: 'GET',
status: 'pending',
statusText: '待测试',
loading: false,
result: ''
},
{
name: '视频URL构建',
url: buildURL(API_ENDPOINTS.static.video('test.mp4')),
method: 'URL',
status: 'pending',
statusText: '待测试',
loading: false,
result: ''
},
{
name: '音频URL构建',
url: buildURL(API_ENDPOINTS.conversation.getAudio('test.mp3')),
method: 'URL',
status: 'pending',
statusText: '待测试',
loading: false,
result: ''
}
]
}
},
methods: {
// 运行单个测试
async runTest(test) {
test.loading = true;
test.status = 'running';
test.statusText = '测试中';
test.result = '';
try {
if (test.method === 'URL') {
// URL 构建测试
test.status = 'success';
test.statusText = '✅ 成功';
test.result = 'URL构建正确';
} else {
// API 请求测试
const result = await request({
url: test.url,
method: test.method
});
test.status = 'success';
test.statusText = '✅ 成功';
test.result = JSON.stringify(result).substring(0, 100) + '...';
}
} catch (error) {
test.status = 'failed';
test.statusText = '❌ 失败';
test.result = error.message || '请求失败';
} finally {
test.loading = false;
}
},
// 运行所有测试
async runAllTests() {
uni.showLoading({
title: '测试中...'
});
for (const test of this.tests) {
await this.runTest(test);
}
uni.hideLoading();
const successCount = this.tests.filter(t => t.status === 'success').length;
const totalCount = this.tests.length;
uni.showToast({
title: `完成 ${successCount}/${totalCount}`,
icon: successCount === totalCount ? 'success' : 'none'
});
},
// 清空结果
clearResults() {
this.tests.forEach(test => {
test.status = 'pending';
test.statusText = '待测试';
test.result = '';
test.loading = false;
});
}
}
}
</script>
<style lang="scss" scoped>
.api-test-container {
min-height: 100vh;
background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
padding-bottom: 40rpx;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 60rpx 30rpx 40rpx;
text-align: center;
box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.3);
}
.title {
font-size: 48rpx;
font-weight: bold;
color: white;
}
.test-section {
padding: 30rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 24rpx;
}
.test-item {
background: white;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.test-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.test-name {
font-size: 30rpx;
font-weight: bold;
color: #333;
}
.test-status {
font-size: 24rpx;
padding: 8rpx 16rpx;
border-radius: 12rpx;
&.pending {
background: #e9ecef;
color: #6c757d;
}
&.running {
background: #fff3cd;
color: #856404;
}
&.success {
background: #d1e7dd;
color: #0f5132;
}
&.failed {
background: #f8d7da;
color: #842029;
}
}
.test-url {
font-size: 24rpx;
color: #666;
background: #f8f9fa;
padding: 16rpx;
border-radius: 8rpx;
margin-bottom: 16rpx;
word-break: break-all;
font-family: monospace;
}
.test-result {
background: #f8f9fa;
padding: 16rpx;
border-radius: 8rpx;
margin-bottom: 16rpx;
}
.result-label {
font-size: 24rpx;
color: #666;
display: block;
margin-bottom: 8rpx;
}
.result-value {
font-size: 24rpx;
color: #333;
word-break: break-all;
font-family: monospace;
}
.test-btn {
width: 100%;
padding: 24rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 12rpx;
font-size: 28rpx;
font-weight: bold;
&:active {
transform: translateY(2rpx);
}
&[disabled] {
opacity: 0.6;
}
}
.batch-actions {
padding: 0 30rpx;
display: flex;
gap: 20rpx;
}
.batch-btn {
flex: 1;
padding: 32rpx;
background: linear-gradient(135deg, #34d399 0%, #10b981 100%);
color: white;
border: none;
border-radius: 16rpx;
font-size: 30rpx;
font-weight: bold;
box-shadow: 0 8rpx 24rpx rgba(52, 211, 153, 0.3);
&.clear {
background: linear-gradient(135deg, #f87171 0%, #ef4444 100%);
box-shadow: 0 8rpx 24rpx rgba(248, 113, 113, 0.3);
}
&:active {
transform: translateY(2rpx);
}
}
</style>