| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>阶段导航状态测试工具</title>
- <style>
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
- body {
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- min-height: 100vh;
- padding: 20px;
- }
- .container {
- max-width: 1200px;
- margin: 0 auto;
- background: white;
- border-radius: 16px;
- box-shadow: 0 20px 60px rgba(0,0,0,0.3);
- padding: 40px;
- }
- h1 {
- text-align: center;
- color: #333;
- margin-bottom: 10px;
- font-size: 32px;
- }
- .subtitle {
- text-align: center;
- color: #666;
- margin-bottom: 40px;
- font-size: 14px;
- }
- .control-panel {
- background: #f8f9fa;
- border-radius: 12px;
- padding: 24px;
- margin-bottom: 32px;
- }
- .control-group {
- margin-bottom: 20px;
- }
- .control-group label {
- display: block;
- font-weight: 600;
- margin-bottom: 8px;
- color: #333;
- }
- .stage-buttons {
- display: grid;
- grid-template-columns: repeat(4, 1fr);
- gap: 12px;
- }
- .stage-btn {
- padding: 12px 20px;
- border: 2px solid #ddd;
- background: white;
- border-radius: 8px;
- cursor: pointer;
- transition: all 0.3s;
- font-size: 14px;
- font-weight: 500;
- }
- .stage-btn:hover {
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
- }
- .stage-btn.active {
- background: #eb445a;
- color: white;
- border-color: #eb445a;
- }
- /* 导航栏预览 */
- .navigation-preview {
- background: white;
- border: 2px solid #e0e0e0;
- border-radius: 12px;
- padding: 24px;
- margin-bottom: 32px;
- }
- .preview-title {
- font-size: 14px;
- font-weight: 600;
- color: #666;
- margin-bottom: 16px;
- text-transform: uppercase;
- letter-spacing: 1px;
- }
- .stage-navigation {
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
- .stage-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 8px;
- cursor: pointer;
- transition: all 0.3s;
- }
- .stage-item:hover {
- transform: translateY(-2px);
- }
- .stage-circle {
- width: 48px;
- height: 48px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-weight: 600;
- font-size: 18px;
- border: 3px solid #ddd;
- background: white;
- color: #999;
- transition: all 0.3s;
- }
- .stage-item.completed .stage-circle {
- background: linear-gradient(135deg, #2dd36f 0%, #28ba62 100%);
- border-color: #2dd36f;
- color: white;
- box-shadow: 0 2px 8px rgba(45, 211, 111, 0.3);
- }
- .stage-item.active .stage-circle {
- background: linear-gradient(135deg, #eb445a 0%, #d33850 100%);
- border-color: #eb445a;
- color: white;
- transform: scale(1.2);
- box-shadow: 0 0 0 4px rgba(235, 68, 90, 0.2),
- 0 4px 12px rgba(235, 68, 90, 0.4);
- animation: pulse 2s infinite;
- }
- .stage-item.pending .stage-circle {
- background: white;
- border-color: #ddd;
- color: #999;
- }
- @keyframes pulse {
- 0%, 100% {
- box-shadow: 0 0 0 4px rgba(235, 68, 90, 0.2),
- 0 4px 12px rgba(235, 68, 90, 0.4);
- }
- 50% {
- box-shadow: 0 0 0 8px rgba(235, 68, 90, 0.1),
- 0 4px 16px rgba(235, 68, 90, 0.5);
- }
- }
- .stage-label {
- font-size: 13px;
- font-weight: 500;
- color: #999;
- }
- .stage-item.completed .stage-label {
- color: #2dd36f;
- font-weight: 600;
- }
- .stage-item.active .stage-label {
- color: #eb445a;
- font-weight: 700;
- }
- .stage-connector {
- flex: 1;
- height: 3px;
- background: #e0e0e0;
- margin: 0 12px;
- margin-bottom: 32px;
- transition: background 0.3s;
- }
- .stage-connector.completed {
- background: #2dd36f;
- }
- /* 测试结果 */
- .test-results {
- background: #f8f9fa;
- border-radius: 12px;
- padding: 24px;
- }
- .result-item {
- background: white;
- border-left: 4px solid #ddd;
- padding: 16px;
- margin-bottom: 12px;
- border-radius: 4px;
- }
- .result-item.success {
- border-color: #2dd36f;
- background: #f0fdf4;
- }
- .result-item.error {
- border-color: #eb445a;
- background: #fef2f2;
- }
- .result-item.info {
- border-color: #3b82f6;
- background: #eff6ff;
- }
- .result-header {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-bottom: 8px;
- font-weight: 600;
- }
- .icon {
- width: 20px;
- height: 20px;
- }
- .btn {
- padding: 12px 24px;
- border: none;
- border-radius: 8px;
- font-size: 14px;
- font-weight: 600;
- cursor: pointer;
- transition: all 0.3s;
- margin-right: 12px;
- }
- .btn-primary {
- background: #667eea;
- color: white;
- }
- .btn-primary:hover {
- background: #5568d3;
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
- }
- .btn-secondary {
- background: #6c757d;
- color: white;
- }
- .btn-secondary:hover {
- background: #5a6268;
- }
- .actions {
- margin-top: 24px;
- text-align: center;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <h1>🎯 阶段导航状态测试工具</h1>
- <p class="subtitle">模拟项目详情页的阶段导航栏状态变化</p>
- <!-- 控制面板 -->
- <div class="control-panel">
- <div class="control-group">
- <label>选择当前项目阶段:</label>
- <div class="stage-buttons">
- <button class="stage-btn active" data-stage="order" onclick="setCurrentStage('order')">
- 订单分配
- </button>
- <button class="stage-btn" data-stage="requirements" onclick="setCurrentStage('requirements')">
- 确认需求
- </button>
- <button class="stage-btn" data-stage="delivery" onclick="setCurrentStage('delivery')">
- 交付执行
- </button>
- <button class="stage-btn" data-stage="aftercare" onclick="setCurrentStage('aftercare')">
- 售后归档
- </button>
- </div>
- </div>
- </div>
- <!-- 导航栏预览 -->
- <div class="navigation-preview">
- <div class="preview-title">导航栏预览</div>
- <div class="stage-navigation">
- <div class="stage-item" id="stage-order" onclick="testStageClick('order')">
- <div class="stage-circle">
- <span class="stage-number">1</span>
- <span class="checkmark" style="display:none;">✓</span>
- </div>
- <div class="stage-label">订单分配</div>
- </div>
- <div class="stage-connector" id="connector-1"></div>
- <div class="stage-item" id="stage-requirements" onclick="testStageClick('requirements')">
- <div class="stage-circle">
- <span class="stage-number">2</span>
- <span class="checkmark" style="display:none;">✓</span>
- </div>
- <div class="stage-label">确认需求</div>
- </div>
- <div class="stage-connector" id="connector-2"></div>
- <div class="stage-item" id="stage-delivery" onclick="testStageClick('delivery')">
- <div class="stage-circle">
- <span class="stage-number">3</span>
- <span class="checkmark" style="display:none;">✓</span>
- </div>
- <div class="stage-label">交付执行</div>
- </div>
- <div class="stage-connector" id="connector-3"></div>
- <div class="stage-item" id="stage-aftercare" onclick="testStageClick('aftercare')">
- <div class="stage-circle">
- <span class="stage-number">4</span>
- <span class="checkmark" style="display:none;">✓</span>
- </div>
- <div class="stage-label">售后归档</div>
- </div>
- </div>
- </div>
- <!-- 测试结果 -->
- <div class="test-results">
- <div class="preview-title">测试结果</div>
- <div id="results"></div>
- </div>
- <div class="actions">
- <button class="btn btn-primary" onclick="runAllTests()">🧪 运行全部测试</button>
- <button class="btn btn-secondary" onclick="clearResults()">🗑️ 清空结果</button>
- </div>
- </div>
- <script>
- let currentStage = 'order';
- const stages = ['order', 'requirements', 'delivery', 'aftercare'];
- const stageNames = {
- 'order': '订单分配',
- 'requirements': '确认需求',
- 'delivery': '交付执行',
- 'aftercare': '售后归档'
- };
- function setCurrentStage(stage) {
- currentStage = stage;
-
- // 更新按钮状态
- document.querySelectorAll('.stage-btn').forEach(btn => {
- btn.classList.toggle('active', btn.dataset.stage === stage);
- });
-
- updateNavigation();
- addResult('info', '阶段已切换', `当前阶段设置为:${stageNames[stage]}`);
- }
- function getStageStatus(stageId) {
- const currentIdx = stages.indexOf(currentStage);
- const idx = stages.indexOf(stageId);
-
- if (idx < currentIdx) return 'completed';
- if (idx === currentIdx) return 'active';
- return 'pending';
- }
- function updateNavigation() {
- stages.forEach((stageId, index) => {
- const item = document.getElementById(`stage-${stageId}`);
- const status = getStageStatus(stageId);
-
- // 移除所有状态类
- item.classList.remove('completed', 'active', 'pending');
- item.classList.add(status);
-
- // 更新图标显示
- const number = item.querySelector('.stage-number');
- const checkmark = item.querySelector('.checkmark');
- if (status === 'completed') {
- number.style.display = 'none';
- checkmark.style.display = 'block';
- } else {
- number.style.display = 'block';
- checkmark.style.display = 'none';
- }
-
- // 更新连接线
- if (index < stages.length - 1) {
- const connector = document.getElementById(`connector-${index + 1}`);
- const nextStatus = getStageStatus(stages[index + 1]);
- connector.classList.toggle('completed',
- nextStatus === 'completed' || nextStatus === 'active');
- }
- });
- }
- function testStageClick(stageId) {
- const status = getStageStatus(stageId);
- const stageName = stageNames[stageId];
- const currentName = stageNames[currentStage];
-
- if (status === 'pending') {
- addResult('error', '❌ 访问被阻止',
- `当前项目正在进行【${currentName}】阶段\n请完成当前阶段后再进入【${stageName}】`);
- } else {
- addResult('success', '✅ 访问成功',
- `允许访问【${stageName}】阶段(状态:${status === 'active' ? '进行中' : '已完成'})`);
- }
- }
- function addResult(type, title, message) {
- const results = document.getElementById('results');
- const item = document.createElement('div');
- item.className = `result-item ${type}`;
- item.innerHTML = `
- <div class="result-header">
- <span class="icon">${type === 'success' ? '✅' : type === 'error' ? '❌' : 'ℹ️'}</span>
- <span>${title}</span>
- </div>
- <div>${message}</div>
- `;
- results.insertBefore(item, results.firstChild);
- }
- function clearResults() {
- document.getElementById('results').innerHTML = '';
- }
- function runAllTests() {
- clearResults();
- addResult('info', '🧪 开始测试', '运行全部阶段访问测试...');
-
- // 测试场景1:order阶段
- setCurrentStage('order');
- setTimeout(() => {
- testStageClick('order');
- testStageClick('requirements');
- testStageClick('delivery');
- testStageClick('aftercare');
-
- // 测试场景2:requirements阶段
- setTimeout(() => {
- setCurrentStage('requirements');
- setTimeout(() => {
- testStageClick('order');
- testStageClick('requirements');
- testStageClick('delivery');
- testStageClick('aftercare');
-
- // 测试场景3:delivery阶段
- setTimeout(() => {
- setCurrentStage('delivery');
- setTimeout(() => {
- testStageClick('order');
- testStageClick('requirements');
- testStageClick('delivery');
- testStageClick('aftercare');
-
- // 测试场景4:aftercare阶段
- setTimeout(() => {
- setCurrentStage('aftercare');
- setTimeout(() => {
- testStageClick('order');
- testStageClick('requirements');
- testStageClick('delivery');
- testStageClick('aftercare');
-
- addResult('success', '✅ 测试完成', '所有测试场景执行完毕');
- }, 100);
- }, 500);
- }, 100);
- }, 500);
- }, 100);
- }, 500);
- }, 100);
- }
- // 初始化
- updateNavigation();
- </script>
- </body>
- </html>
|