5 changed files with 16066 additions and 734 deletions
File diff suppressed because it is too large
Load Diff
@ -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