5 changed files with 16066 additions and 734 deletions
File diff suppressed because it is too large
Load Diff
@ -1,548 +0,0 @@
@@ -1,548 +0,0 @@
|
||||
<template> |
||||
<div class="role-api-test"> |
||||
<div class="page-header"> |
||||
<h2>角色管理API测试</h2> |
||||
<div class="header-actions"> |
||||
<button |
||||
class="btn btn-secondary" |
||||
@click="toggleTestMode" |
||||
:title="testMode ? '当前为测试模式(无需认证)' : '当前为正式模式(需要认证)'" |
||||
> |
||||
<i class="fas fa-flask"></i> |
||||
{{ testMode ? '测试模式' : '正式模式' }} |
||||
</button> |
||||
<button class="btn btn-primary" @click="runAllTests"> |
||||
<i class="fas fa-play"></i> 运行所有测试 |
||||
</button> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="test-content"> |
||||
<!-- API配置信息 --> |
||||
<div class="test-section"> |
||||
<h3>API配置信息</h3> |
||||
<div class="config-info"> |
||||
<div class="config-item"> |
||||
<label>API基础地址:</label> |
||||
<span>{{ apiBaseUrl }}</span> |
||||
</div> |
||||
<div class="config-item"> |
||||
<label>当前模式:</label> |
||||
<span :class="testMode ? 'test-mode' : 'prod-mode'"> |
||||
{{ testMode ? '测试模式' : '正式模式' }} |
||||
</span> |
||||
</div> |
||||
<div class="config-item"> |
||||
<label>API路径:</label> |
||||
<span>{{ currentApiPath }}</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 测试结果 --> |
||||
<div class="test-section"> |
||||
<h3>测试结果</h3> |
||||
<div class="test-results"> |
||||
<div |
||||
v-for="(result, index) in testResults" |
||||
:key="index" |
||||
class="test-result-item" |
||||
:class="result.status" |
||||
> |
||||
<div class="test-header"> |
||||
<span class="test-name">{{ result.name }}</span> |
||||
<span class="test-status">{{ getStatusText(result.status) }}</span> |
||||
</div> |
||||
<div v-if="result.message" class="test-message"> |
||||
{{ result.message }} |
||||
</div> |
||||
<div v-if="result.data" class="test-data"> |
||||
<pre>{{ JSON.stringify(result.data, null, 2) }}</pre> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 手动测试 --> |
||||
<div class="test-section"> |
||||
<h3>手动测试</h3> |
||||
<div class="manual-tests"> |
||||
<div class="test-group"> |
||||
<h4>获取角色列表</h4> |
||||
<button @click="testGetRoles" :disabled="testing"> |
||||
{{ testing ? '测试中...' : '测试获取角色列表' }} |
||||
</button> |
||||
</div> |
||||
|
||||
<div class="test-group"> |
||||
<h4>创建角色</h4> |
||||
<div class="form-group"> |
||||
<label>角色名称:</label> |
||||
<input v-model="testRole.name" type="text" placeholder="测试角色" /> |
||||
</div> |
||||
<div class="form-group"> |
||||
<label>角色代码:</label> |
||||
<input v-model="testRole.code" type="text" placeholder="TEST_ROLE" /> |
||||
</div> |
||||
<div class="form-group"> |
||||
<label>描述:</label> |
||||
<input v-model="testRole.description" type="text" placeholder="测试角色描述" /> |
||||
</div> |
||||
<button @click="testCreateRole" :disabled="testing"> |
||||
{{ testing ? '测试中...' : '测试创建角色' }} |
||||
</button> |
||||
</div> |
||||
|
||||
<div class="test-group"> |
||||
<h4>更新角色</h4> |
||||
<div class="form-group"> |
||||
<label>角色ID:</label> |
||||
<input v-model="updateRoleId" type="number" placeholder="输入角色ID" /> |
||||
</div> |
||||
<button @click="testUpdateRole" :disabled="testing || !updateRoleId"> |
||||
{{ testing ? '测试中...' : '测试更新角色' }} |
||||
</button> |
||||
</div> |
||||
|
||||
<div class="test-group"> |
||||
<h4>删除角色</h4> |
||||
<div class="form-group"> |
||||
<label>角色ID:</label> |
||||
<input v-model="deleteRoleId" type="number" placeholder="输入角色ID" /> |
||||
</div> |
||||
<button @click="testDeleteRole" :disabled="testing || !deleteRoleId"> |
||||
{{ testing ? '测试中...' : '测试删除角色' }} |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { ref, reactive, computed, onMounted } from 'vue' |
||||
import { roleService } from '../services/roleService.js' |
||||
import { getFinalConfig } from '../../../../config/app.config.js' |
||||
|
||||
export default { |
||||
name: 'RoleApiTest', |
||||
setup() { |
||||
const testing = ref(false) |
||||
const testMode = ref(false) |
||||
const testResults = ref([]) |
||||
|
||||
const updateRoleId = ref('') |
||||
const deleteRoleId = ref('') |
||||
|
||||
const testRole = reactive({ |
||||
name: '测试角色', |
||||
code: 'TEST_ROLE', |
||||
description: '这是一个测试角色' |
||||
}) |
||||
|
||||
const apiBaseUrl = computed(() => getFinalConfig().apiBaseUrl) |
||||
const currentApiPath = computed(() => testMode.value ? '/auth/roles/test' : '/auth/roles') |
||||
|
||||
// 切换测试模式 |
||||
const toggleTestMode = () => { |
||||
testMode.value = roleService.toggleTestMode() |
||||
addTestResult('模式切换', 'success', `已切换到${testMode.value ? '测试' : '正式'}模式`) |
||||
} |
||||
|
||||
// 添加测试结果 |
||||
const addTestResult = (name, status, message, data = null) => { |
||||
testResults.value.unshift({ |
||||
name, |
||||
status, |
||||
message, |
||||
data, |
||||
timestamp: new Date().toLocaleString() |
||||
}) |
||||
} |
||||
|
||||
// 获取状态文本 |
||||
const getStatusText = (status) => { |
||||
const statusMap = { |
||||
'success': '成功', |
||||
'error': '失败', |
||||
'warning': '警告' |
||||
} |
||||
return statusMap[status] || status |
||||
} |
||||
|
||||
// 测试获取角色列表 |
||||
const testGetRoles = async () => { |
||||
testing.value = true |
||||
try { |
||||
const response = await roleService.getRoles(1, 10) |
||||
if (response.code === 200) { |
||||
addTestResult('获取角色列表', 'success', '获取角色列表成功', response.data) |
||||
} else { |
||||
addTestResult('获取角色列表', 'error', `获取失败: ${response.message}`, response) |
||||
} |
||||
} catch (error) { |
||||
addTestResult('获取角色列表', 'error', `请求失败: ${error.message || error.error}`, error) |
||||
} finally { |
||||
testing.value = false |
||||
} |
||||
} |
||||
|
||||
// 测试创建角色 |
||||
const testCreateRole = async () => { |
||||
testing.value = true |
||||
try { |
||||
const response = await roleService.createRole(testRole) |
||||
if (response.code === 200) { |
||||
addTestResult('创建角色', 'success', '创建角色成功', response.data) |
||||
} else { |
||||
addTestResult('创建角色', 'error', `创建失败: ${response.message}`, response) |
||||
} |
||||
} catch (error) { |
||||
addTestResult('创建角色', 'error', `请求失败: ${error.message || error.error}`, error) |
||||
} finally { |
||||
testing.value = false |
||||
} |
||||
} |
||||
|
||||
// 测试更新角色 |
||||
const testUpdateRole = async () => { |
||||
if (!updateRoleId.value) { |
||||
addTestResult('更新角色', 'warning', '请输入角色ID') |
||||
return |
||||
} |
||||
|
||||
testing.value = true |
||||
try { |
||||
const updateData = { |
||||
name: `${testRole.name}_更新`, |
||||
code: `${testRole.code}_UPDATED`, |
||||
description: `${testRole.description}_更新` |
||||
} |
||||
const response = await roleService.updateRole(updateRoleId.value, updateData) |
||||
if (response.code === 200) { |
||||
addTestResult('更新角色', 'success', '更新角色成功', response.data) |
||||
} else { |
||||
addTestResult('更新角色', 'error', `更新失败: ${response.message}`, response) |
||||
} |
||||
} catch (error) { |
||||
addTestResult('更新角色', 'error', `请求失败: ${error.message || error.error}`, error) |
||||
} finally { |
||||
testing.value = false |
||||
} |
||||
} |
||||
|
||||
// 测试删除角色 |
||||
const testDeleteRole = async () => { |
||||
if (!deleteRoleId.value) { |
||||
addTestResult('删除角色', 'warning', '请输入角色ID') |
||||
return |
||||
} |
||||
|
||||
testing.value = true |
||||
try { |
||||
const response = await roleService.deleteRole(deleteRoleId.value) |
||||
if (response.code === 200) { |
||||
addTestResult('删除角色', 'success', '删除角色成功', response.data) |
||||
} else { |
||||
addTestResult('删除角色', 'error', `删除失败: ${response.message}`, response) |
||||
} |
||||
} catch (error) { |
||||
addTestResult('删除角色', 'error', `请求失败: ${error.message || error.error}`, error) |
||||
} finally { |
||||
testing.value = false |
||||
} |
||||
} |
||||
|
||||
// 运行所有测试 |
||||
const runAllTests = async () => { |
||||
addTestResult('测试开始', 'success', '开始运行所有API测试') |
||||
|
||||
await testGetRoles() |
||||
await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒 |
||||
await testCreateRole() |
||||
await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒 |
||||
|
||||
addTestResult('测试完成', 'success', '所有API测试已完成') |
||||
} |
||||
|
||||
onMounted(() => { |
||||
testMode.value = roleService.getTestModeStatus() |
||||
addTestResult('页面加载', 'success', '角色管理API测试页面已加载') |
||||
}) |
||||
|
||||
return { |
||||
testing, |
||||
testMode, |
||||
testResults, |
||||
updateRoleId, |
||||
deleteRoleId, |
||||
testRole, |
||||
apiBaseUrl, |
||||
currentApiPath, |
||||
toggleTestMode, |
||||
testGetRoles, |
||||
testCreateRole, |
||||
testUpdateRole, |
||||
testDeleteRole, |
||||
runAllTests, |
||||
getStatusText |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.role-api-test { |
||||
padding: 20px; |
||||
height: 100%; |
||||
overflow-y: auto; |
||||
} |
||||
|
||||
.page-header { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.page-header h2 { |
||||
margin: 0; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
.header-actions { |
||||
display: flex; |
||||
gap: 12px; |
||||
align-items: center; |
||||
} |
||||
|
||||
.test-content { |
||||
max-width: 1200px; |
||||
} |
||||
|
||||
.test-section { |
||||
background: var(--card-bg); |
||||
border-radius: 8px; |
||||
padding: 24px; |
||||
margin-bottom: 24px; |
||||
box-shadow: 0 2px 8px var(--shadow-color); |
||||
} |
||||
|
||||
.test-section h3 { |
||||
margin: 0 0 20px 0; |
||||
color: var(--text-primary); |
||||
font-size: 18px; |
||||
border-bottom: 2px solid var(--border-color); |
||||
padding-bottom: 8px; |
||||
} |
||||
|
||||
.config-info { |
||||
display: grid; |
||||
gap: 12px; |
||||
} |
||||
|
||||
.config-item { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
padding: 12px; |
||||
background: var(--bg-secondary); |
||||
border-radius: 4px; |
||||
} |
||||
|
||||
.config-item label { |
||||
font-weight: 500; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
.config-item span { |
||||
color: var(--text-secondary); |
||||
font-family: monospace; |
||||
} |
||||
|
||||
.test-mode { |
||||
color: #ff9800 !important; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.prod-mode { |
||||
color: #4caf50 !important; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.test-results { |
||||
max-height: 400px; |
||||
overflow-y: auto; |
||||
} |
||||
|
||||
.test-result-item { |
||||
margin-bottom: 16px; |
||||
padding: 16px; |
||||
border-radius: 6px; |
||||
border-left: 4px solid; |
||||
} |
||||
|
||||
.test-result-item.success { |
||||
background: rgba(76, 175, 80, 0.1); |
||||
border-left-color: #4caf50; |
||||
} |
||||
|
||||
.test-result-item.error { |
||||
background: rgba(244, 67, 54, 0.1); |
||||
border-left-color: #f44336; |
||||
} |
||||
|
||||
.test-result-item.warning { |
||||
background: rgba(255, 152, 0, 0.1); |
||||
border-left-color: #ff9800; |
||||
} |
||||
|
||||
.test-header { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
margin-bottom: 8px; |
||||
} |
||||
|
||||
.test-name { |
||||
font-weight: 500; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
.test-status { |
||||
font-size: 12px; |
||||
padding: 4px 8px; |
||||
border-radius: 4px; |
||||
font-weight: 500; |
||||
} |
||||
|
||||
.test-result-item.success .test-status { |
||||
background: #4caf50; |
||||
color: white; |
||||
} |
||||
|
||||
.test-result-item.error .test-status { |
||||
background: #f44336; |
||||
color: white; |
||||
} |
||||
|
||||
.test-result-item.warning .test-status { |
||||
background: #ff9800; |
||||
color: white; |
||||
} |
||||
|
||||
.test-message { |
||||
color: var(--text-secondary); |
||||
margin-bottom: 8px; |
||||
} |
||||
|
||||
.test-data { |
||||
background: var(--bg-secondary); |
||||
padding: 12px; |
||||
border-radius: 4px; |
||||
overflow-x: auto; |
||||
} |
||||
|
||||
.test-data pre { |
||||
margin: 0; |
||||
font-size: 12px; |
||||
color: var(--text-secondary); |
||||
} |
||||
|
||||
.manual-tests { |
||||
display: grid; |
||||
gap: 24px; |
||||
} |
||||
|
||||
.test-group { |
||||
padding: 16px; |
||||
background: var(--bg-secondary); |
||||
border-radius: 6px; |
||||
} |
||||
|
||||
.test-group h4 { |
||||
margin: 0 0 16px 0; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
.form-group { |
||||
margin-bottom: 12px; |
||||
} |
||||
|
||||
.form-group label { |
||||
display: block; |
||||
margin-bottom: 4px; |
||||
font-weight: 500; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
.form-group input { |
||||
width: 100%; |
||||
padding: 8px 12px; |
||||
border: 1px solid var(--border-color); |
||||
border-radius: 4px; |
||||
background: var(--input-bg); |
||||
color: var(--input-text); |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
.btn { |
||||
padding: 8px 16px; |
||||
border: none; |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
font-size: 14px; |
||||
display: inline-flex; |
||||
align-items: center; |
||||
gap: 6px; |
||||
transition: all 0.2s; |
||||
} |
||||
|
||||
.btn-primary { |
||||
background: var(--accent-color); |
||||
color: white; |
||||
} |
||||
|
||||
.btn-primary:hover { |
||||
background: var(--accent-hover); |
||||
} |
||||
|
||||
.btn-secondary { |
||||
background: #757575; |
||||
color: white; |
||||
} |
||||
|
||||
.btn-secondary:hover { |
||||
background: #616161; |
||||
} |
||||
|
||||
.btn:hover { |
||||
opacity: 0.9; |
||||
} |
||||
|
||||
.btn:disabled { |
||||
opacity: 0.5; |
||||
cursor: not-allowed; |
||||
} |
||||
|
||||
button { |
||||
background: var(--accent-color); |
||||
color: white; |
||||
border: none; |
||||
padding: 8px 16px; |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
font-size: 14px; |
||||
transition: all 0.2s; |
||||
} |
||||
|
||||
button:hover:not(:disabled) { |
||||
background: var(--accent-hover); |
||||
} |
||||
|
||||
button:disabled { |
||||
opacity: 0.5; |
||||
cursor: not-allowed; |
||||
} |
||||
</style> |
Loading…
Reference in new issue