|
|
<!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; font-family: "Microsoft YaHei", sans-serif; } body { background-color: #f5f7fa; color: #333; } .container { display: flex; min-height: 100vh; }
/* 侧边栏样式 */ .sidebar { width: 220px; background-color: #2c3e50; color: #fff; padding: 20px 0; } .sidebar-logo { text-align: center; padding: 0 20px 20px; border-bottom: 1px solid rgba(255,255,255,0.1); margin-bottom: 20px; } .sidebar-logo h2 { font-size: 18px; margin-top: 10px; } .sidebar-menu { list-style: none; } .sidebar-menu li a { display: flex; align-items: center; padding: 12px 20px; color: rgba(255,255,255,0.8); text-decoration: none; transition: all 0.3s; } .sidebar-menu li a:hover, .sidebar-menu li a.active { background-color: #34495e; color: #fff; } .sidebar-menu li a i { margin-right: 10px; font-size: 16px; }
/* 主内容区样式 */ .main-content { flex: 1; padding: 20px; overflow-y: auto; } .page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #eee; } .page-header h2 { font-size: 20px; font-weight: 600; color: #333; } .btn { padding: 6px 12px; border: 1px solid #ddd; border-radius: 4px; background-color: #fff; cursor: pointer; color: #333; text-decoration: none; } .btn-primary { background-color: #3498db; color: #fff; border-color: #3498db; } .btn-danger { background-color: #e74c3c; color: #fff; border-color: #e74c3c; }
/* 查询区域样式 */ .search-area { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; /* 适配小屏幕 */ } .search-area input, .search-area select { padding: 6px 10px; border: 1px solid #ddd; border-radius: 4px; outline: none; } .search-area .date-picker { display: flex; align-items: center; gap: 5px; }
/* 表格样式 */ .table-container { background-color: #fff; border-radius: 4px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); overflow: hidden; } .data-table { width: 100%; border-collapse: collapse; } .data-table th, .data-table td { padding: 12px 15px; text-align: left; border-bottom: 1px solid #f0f0f0; } .data-table th { background-color: #f9fafb; font-weight: 600; color: #666; } .data-table tbody tr:hover { background-color: #f5f7fa; }
/* 分页样式 */ .pagination { display: flex; justify-content: space-between; align-items: center; padding: 15px; border-top: 1px solid #f0f0f0; } .pagination-info { color: #666; font-size: 14px; } .pagination-list { display: flex; list-style: none; padding: 0; margin: 0; } .pagination-list li { margin: 0 2px; } .pagination-list a, .pagination-list span { display: inline-block; width: 45px; height: 45px; line-height: 45px; text-align: center; border: 1px solid #ddd; border-radius: 4px; text-decoration: none; color: #333; font-size: 14px; box-sizing: border-box; } .pagination-list a { cursor: pointer; } .pagination-list a:hover, .pagination-list a.active { background-color: #3498db; color: #fff; border-color: #3498db; } .pagination-list span { background-color: #f5f5f5; color: #999; cursor: not-allowed; } .pagination-jump { display: flex; align-items: center; font-size: 14px; gap: 5px; } .pagination-jump input { width: 50px; height: 32px; margin: 0 5px; padding: 0 5px; border: 1px solid #ddd; border-radius: 4px; text-align: center; box-sizing: border-box; } .pagination-jump button { padding: 6px 12px; border: 1px solid #ddd; border-radius: 4px; background-color: #fff; cursor: pointer; height: 32px; box-sizing: border-box; } /* 加载中样式 */ .loading { text-align: center; padding: 50px 0; color: #666; } .loading i { font-size: 24px; margin-bottom: 10px; animation: spin 1s linear infinite; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"></head><body> <div class="container"> <div class="sidebar"> <div class="sidebar-logo"> <i class="fa fa-line-chart" style="font-size: 24px;"></i> <h2>后台管理系统</h2> </div> <ul class="sidebar-menu"> <li><a href="#" class="active"><i class="fa fa-file-text-o"></i> 落地页管理</a></li> </ul> </div>
<!-- 主内容区 --> <div class="main-content"> <div class="page-header"> <div class="page-header h2">详情</div> <a href="adminConfig.html" class="btn">返回上一级页面</a> </div>
<!-- 查询区域 --> <div class="search-area"> <label class="date-picker"> 打开网页时间 <input type="date" id="startTime" placeholder="请选择开始时间" /> 至 <input type="date" id="endTime" placeholder="请选择结束时间" /> </label> <div> <label for="statusSelect">收下状态</label> <select id="statusSelect"> <option value="">请选择状态</option> <option value="1">是</option> <option value="0">否</option> </select> </div> <button id="searchBtn" class="btn btn-primary">查询</button> <button class="btn btn-danger">导出</button> </div>
<!-- 数据表格 --> <div class="table-container"> <table class="data-table"> <thead> <tr> <th>序号</th> <th>打开网页时间</th> <th>收下状态</th> </tr> </thead> <tbody id="tableBody"> <tr> <td colspan="3" class="loading"> <!-- 注意:表格列数是3,colspan改为3 --> <i class="fa fa-spinner"></i> <p>加载中...</p> </td> </tr> </tbody> </table>
<!-- 分页控件 --> <div class="pagination" id="paginationContainer"> </div> </div> </div> </div>
<script type="module"> // 导入API函数(假设接口定义) import { getLandingDetailApi } from './src/api/member.js';
// DOM元素 const tableBody = document.getElementById('tableBody'); const paginationContainer = document.getElementById('paginationContainer'); const searchBtn = document.getElementById('searchBtn'); const startTimeInput = document.getElementById('startTime'); const endTimeInput = document.getElementById('endTime'); const statusSelect = document.getElementById('statusSelect');
// 分页参数 let currentPage = 1; const pageSize = 20; let totalCount = 0; let totalPages = 0;
// URL获取的id参数 let landingId = '';
// 初始化页面:从URL获取页码,请求后端数据 async function initPage() { const urlParams = new URLSearchParams(window.location.search); landingId = urlParams.get('id');
if (!landingId) { renderEmptyState('缺少必要的参数'); return; }
// 从后端请求数据 await fetchDataFromBackend(); }
// 核心:从后端API请求数据 async function fetchDataFromBackend() { // 显示加载状态 tableBody.innerHTML = ` <tr> <td colspan="3" class="loading"> <i class="fa fa-spinner"></i> <p>加载中...</p> </td> </tr> `; paginationContainer.innerHTML = '';
try { // 1. 构造请求参数(分页+查询条件) const requestParams = { id: landingId, page: currentPage, // 当前页码 size: pageSize, // 每页条数 startTime: startTimeInput.value || '', // 开始时间(查询条件) endTime: endTimeInput.value || '', // 结束时间(查询条件) receiveStatus: statusSelect.value || '' // 收下状态(查询条件) };
// 2. 调用导入的API函数 const result = await getLandingDetailApi(requestParams);
// 3. 处理API返回结果 if (result.code === 200) { const { list, total } = result.data; totalCount = total; totalPages = Math.ceil(totalCount / pageSize);
renderTable(list); renderPagination(); } else { renderEmptyState('获取数据失败'); }
} catch (error) { // 捕获异常 console.error('请求数据异常:', error); renderEmptyState('网络错误,请稍后重试'); } }
// 渲染表格数据 function renderTable(dataList) { if (!dataList || dataList.length === 0) { renderEmptyState('暂无符合条件的数据'); return; }
let html = ''; dataList.forEach((item, index) => { // 计算序号:(当前页-1)*每页条数 + 索引+1 const serialNumber = (currentPage - 1) * pageSize + index + 1; // 注意:item的字段名需与后端返回的字段一致 html += ` <tr> <td>${serialNumber}</td> <td>${formatDate(item.openTime || '')}</td> <td>${item.receiveStatus === '1' ? '是' : item.receiveStatus === '0' ? '否' : ''}</td> </tr> `; });
tableBody.innerHTML = html; }
// 渲染空状态 function renderEmptyState(message) { tableBody.innerHTML = ` <tr> <td colspan="3" style="text-align: center; padding: 30px;"> <i class="fa fa-inbox" style="font-size: 24px; color: #ddd; margin-bottom: 10px;"></i> <p>${message}</p> </td> </tr> `; paginationContainer.innerHTML = ''; }
// 渲染分页控件 function renderPagination() { if (totalCount === 0) return;
// 生成页码列表 const pageNumbers = []; let startPage = Math.max(1, currentPage - 2); let endPage = Math.min(totalPages, currentPage + 2); if (endPage - startPage < 4 && totalPages >= 5) { if (startPage === 1) endPage = 5; else if (endPage === totalPages) startPage = totalPages - 4; } for (let i = startPage; i <= endPage; i++) { pageNumbers.push(i); }
// 分页HTML const html = ` <div class="pagination-info"> 共 ${totalCount} 条记录,当前第 ${currentPage} / ${totalPages} 页 </div> <ul class="pagination-list"> <li> ${currentPage === 1 ? `<span>首页</span>` : `<a href="?page=1">首页</a>` } </li> <li> ${currentPage > 1 ? `<a href="?page=${currentPage - 1}">上一页</a>` : `<span>上一页</span>` } </li> ${pageNumbers.map(num => ` <li> <a href="?page=${num}" class="${num === currentPage ? 'active' : ''}"> ${num} </a> </li> `).join('')} <li> ${currentPage < totalPages ? `<a href="?page=${currentPage + 1}">下一页</a>` : `<span>下一页</span>` } </li> <li> ${currentPage === totalPages ? `<span>尾页</span>` : `<a href="?page=${totalPages}">尾页</a>` } </li> </ul> <div class="pagination-jump"> <span>跳至</span> <input type="number" min="1" max="${totalPages}" value="${currentPage}" id="jumpPageInput"> <span>页</span> <button id="jumpBtn">确定</button> </div> `;
paginationContainer.innerHTML = html;
// 绑定跳转事件 document.getElementById('jumpBtn').addEventListener('click', handlePageJump); document.getElementById('jumpPageInput').addEventListener('keypress', (e) => { if (e.key === 'Enter') handlePageJump(); }); }
// 处理页码跳转 function handlePageJump() { const pageInput = document.getElementById('jumpPageInput'); const page = parseInt(pageInput.value); if (page && !isNaN(page) && page >= 1 && page <= totalPages && page !== currentPage) { window.location.href = `?page=${page}`; } else { alert('请输入有效的页码'); } }
// 查询按钮事件:点击后重新请求数据 searchBtn.addEventListener('click', async () => { currentPage = 1; // 重置为第一页 await fetchDataFromBackend(); // 重新请求后端数据 });
// 工具函数:格式化日期(适配后端返回的时间格式) function formatDate(dateString) { if (!dateString) return ''; const date = new Date(dateString); // 处理无效日期 if (isNaN(date.getTime())) return dateString; // 格式化显示:年-月-日 时:分:秒 return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }).replace(/\//g, '-'); }
// 工具函数:HTML转义(防止XSS攻击) function escapeHtml(str) { if (!str) return ''; return str .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); }
// 页面加载时初始化 window.addEventListener('DOMContentLoaded', initPage); </script></body></html>
|