18 changed files with 520 additions and 1205 deletions
File diff suppressed because it is too large
Load Diff
@ -1,107 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="speed-test"> |
|
||||||
<h1>GoFaster Speed Test</h1> |
|
||||||
<button @click="startTest" :disabled="testing"> |
|
||||||
{{ testing ? 'Testing...' : 'Start Test' }} |
|
||||||
</button> |
|
||||||
|
|
||||||
<div v-if="result" class="results"> |
|
||||||
<h3>Test Results:</h3> |
|
||||||
<div class="result-item"> |
|
||||||
<span class="label">Download:</span> |
|
||||||
<span class="value">{{ result.download }} Mbps</span> |
|
||||||
</div> |
|
||||||
<div class="result-item"> |
|
||||||
<span class="label">Upload:</span> |
|
||||||
<span class="value">{{ result.upload }} Mbps</span> |
|
||||||
</div> |
|
||||||
<div class="result-item"> |
|
||||||
<span class="label">Ping:</span> |
|
||||||
<span class="value">{{ result.ping }} ms</span> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import { ref } from 'vue' |
|
||||||
import { useStore } from 'vuex' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'SpeedTest', |
|
||||||
setup() { |
|
||||||
const store = useStore() |
|
||||||
const testing = ref(false) |
|
||||||
const result = ref(null) |
|
||||||
|
|
||||||
const startTest = async () => { |
|
||||||
testing.value = true |
|
||||||
result.value = null |
|
||||||
|
|
||||||
// 模拟网络测试 (替换为真实测试逻辑) |
|
||||||
await new Promise(resolve => setTimeout(resolve, 2000)) |
|
||||||
|
|
||||||
const testResult = { |
|
||||||
download: (Math.random() * 100).toFixed(2), |
|
||||||
upload: (Math.random() * 50).toFixed(2), |
|
||||||
ping: (Math.random() * 100).toFixed(2), |
|
||||||
timestamp: new Date().toISOString() |
|
||||||
} |
|
||||||
|
|
||||||
// 保存结果 |
|
||||||
await store.dispatch('saveTestResult', testResult) |
|
||||||
result.value = testResult |
|
||||||
testing.value = false |
|
||||||
} |
|
||||||
|
|
||||||
return { testing, result, startTest } |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style scoped> |
|
||||||
.speed-test { |
|
||||||
padding: 20px; |
|
||||||
max-width: 600px; |
|
||||||
margin: 0 auto; |
|
||||||
text-align: center; |
|
||||||
} |
|
||||||
|
|
||||||
button { |
|
||||||
padding: 10px 20px; |
|
||||||
font-size: 16px; |
|
||||||
background-color: #42b983; |
|
||||||
color: white; |
|
||||||
border: none; |
|
||||||
border-radius: 4px; |
|
||||||
cursor: pointer; |
|
||||||
margin: 20px 0; |
|
||||||
} |
|
||||||
|
|
||||||
button:disabled { |
|
||||||
background-color: #cccccc; |
|
||||||
cursor: not-allowed; |
|
||||||
} |
|
||||||
|
|
||||||
.results { |
|
||||||
margin-top: 20px; |
|
||||||
padding: 15px; |
|
||||||
background-color: #f5f5f5; |
|
||||||
border-radius: 4px; |
|
||||||
text-align: left; |
|
||||||
} |
|
||||||
|
|
||||||
.result-item { |
|
||||||
margin: 10px 0; |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
} |
|
||||||
|
|
||||||
.label { |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
|
|
||||||
.value { |
|
||||||
color: #42b983; |
|
||||||
} |
|
||||||
</style> |
|
@ -1,11 +0,0 @@ |
|||||||
// 业务功能模块入口文件
|
|
||||||
|
|
||||||
// 速度测试功能
|
|
||||||
export { default as SpeedTest } from './components/SpeedTest.vue' |
|
||||||
|
|
||||||
// 历史记录功能
|
|
||||||
export { default as History } from './views/History.vue' |
|
||||||
|
|
||||||
// 业务服务
|
|
||||||
export { default as speedTestService } from './services/speedTest.js' |
|
||||||
export { default as historyService } from './services/history.js' |
|
@ -1,42 +0,0 @@ |
|||||||
// 历史记录服务
|
|
||||||
class HistoryService { |
|
||||||
constructor() { |
|
||||||
this.testResults = [] |
|
||||||
} |
|
||||||
|
|
||||||
// 加载测试结果
|
|
||||||
async loadTestResults() { |
|
||||||
// 从本地存储或数据库加载测试结果
|
|
||||||
const stored = localStorage.getItem('gofaster-test-results') |
|
||||||
if (stored) { |
|
||||||
this.testResults = JSON.parse(stored) |
|
||||||
} |
|
||||||
return this.testResults |
|
||||||
} |
|
||||||
|
|
||||||
// 保存测试结果
|
|
||||||
async saveTestResult(result) { |
|
||||||
this.testResults.push(result) |
|
||||||
localStorage.setItem('gofaster-test-results', JSON.stringify(this.testResults)) |
|
||||||
return result |
|
||||||
} |
|
||||||
|
|
||||||
// 获取测试结果
|
|
||||||
getTestResults() { |
|
||||||
return this.testResults |
|
||||||
} |
|
||||||
|
|
||||||
// 清除测试结果
|
|
||||||
async clearTestResults() { |
|
||||||
this.testResults = [] |
|
||||||
localStorage.removeItem('gofaster-test-results') |
|
||||||
} |
|
||||||
|
|
||||||
// 格式化日期
|
|
||||||
formatDate(timestamp) { |
|
||||||
return new Date(timestamp).toLocaleString() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default new HistoryService() |
|
||||||
|
|
@ -1,35 +0,0 @@ |
|||||||
// 速度测试服务
|
|
||||||
class SpeedTestService { |
|
||||||
constructor() { |
|
||||||
this.testResults = [] |
|
||||||
} |
|
||||||
|
|
||||||
// 开始速度测试
|
|
||||||
async startTest() { |
|
||||||
// 模拟网络测试 (替换为真实测试逻辑)
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 2000)) |
|
||||||
|
|
||||||
const testResult = { |
|
||||||
download: (Math.random() * 100).toFixed(2), |
|
||||||
upload: (Math.random() * 50).toFixed(2), |
|
||||||
ping: (Math.random() * 100).toFixed(2), |
|
||||||
timestamp: new Date().toISOString() |
|
||||||
} |
|
||||||
|
|
||||||
this.testResults.push(testResult) |
|
||||||
return testResult |
|
||||||
} |
|
||||||
|
|
||||||
// 获取测试结果
|
|
||||||
getTestResults() { |
|
||||||
return this.testResults |
|
||||||
} |
|
||||||
|
|
||||||
// 清除测试结果
|
|
||||||
clearTestResults() { |
|
||||||
this.testResults = [] |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default new SpeedTestService() |
|
||||||
|
|
@ -1,99 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="history-view"> |
|
||||||
<h1>Test History</h1> |
|
||||||
|
|
||||||
<div v-if="testResults.length === 0" class="empty-state"> |
|
||||||
No speed tests recorded yet. |
|
||||||
</div> |
|
||||||
|
|
||||||
<div v-else class="history-list"> |
|
||||||
<div v-for="(result, index) in testResults" :key="index" class="history-item"> |
|
||||||
<div class="history-date"> |
|
||||||
{{ formatDate(result.timestamp) }} |
|
||||||
</div> |
|
||||||
<div class="history-stats"> |
|
||||||
<span class="stat download">↓ {{ result.download }} Mbps</span> |
|
||||||
<span class="stat upload">↑ {{ result.upload }} Mbps</span> |
|
||||||
<span class="stat ping">↔ {{ result.ping }} ms</span> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import { computed, onMounted } from 'vue' |
|
||||||
import { useStore } from 'vuex' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'HistoryView', |
|
||||||
setup() { |
|
||||||
const store = useStore() |
|
||||||
|
|
||||||
onMounted(() => { |
|
||||||
store.dispatch('loadTestResults') |
|
||||||
}) |
|
||||||
|
|
||||||
const testResults = computed(() => store.state.testResults) |
|
||||||
|
|
||||||
const formatDate = (timestamp) => { |
|
||||||
return new Date(timestamp).toLocaleString() |
|
||||||
} |
|
||||||
|
|
||||||
return { testResults, formatDate } |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style scoped> |
|
||||||
.history-view { |
|
||||||
padding: 20px; |
|
||||||
max-width: 800px; |
|
||||||
margin: 0 auto; |
|
||||||
} |
|
||||||
|
|
||||||
.empty-state { |
|
||||||
text-align: center; |
|
||||||
padding: 40px; |
|
||||||
color: #888; |
|
||||||
} |
|
||||||
|
|
||||||
.history-list { |
|
||||||
margin-top: 20px; |
|
||||||
} |
|
||||||
|
|
||||||
.history-item { |
|
||||||
padding: 15px; |
|
||||||
margin-bottom: 10px; |
|
||||||
background-color: #f9f9f9; |
|
||||||
border-radius: 4px; |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
.history-date { |
|
||||||
color: #666; |
|
||||||
} |
|
||||||
|
|
||||||
.history-stats { |
|
||||||
display: flex; |
|
||||||
gap: 15px; |
|
||||||
} |
|
||||||
|
|
||||||
.stat { |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
|
|
||||||
.download { |
|
||||||
color: #42b983; |
|
||||||
} |
|
||||||
|
|
||||||
.upload { |
|
||||||
color: #3498db; |
|
||||||
} |
|
||||||
|
|
||||||
.ping { |
|
||||||
color: #e74c3c; |
|
||||||
} |
|
||||||
</style> |
|
Loading…
Reference in new issue