<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Struts2 Learning Scaffold</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 1100px; margin: 40px auto; padding: 20px; background:#f7f8fa; }
        .hero { background: linear-gradient(135deg,#ff7e5f,#feb47b); color:#fff; padding:30px; border-radius:16px; }
        .hero h1 { margin:0 0 10px; font-size:2.4em; }
        .hero p { font-size:1.1em; opacity: .95; }
        .grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap:18px; margin-top:24px; }
        .card { background:#fff; border-radius:14px; padding:20px; box-shadow:0 4px 14px rgba(0,0,0,.06); }
        .card h3 { margin-top:0; color:#e74c3c; }
        .btn { display:inline-block; background:#3498db; color:#fff; padding:10px 18px; margin-top:10px; text-decoration:none; border-radius:8px; }
        .btn:hover { background:#2980b9; }
        .btn.green { background:#27ae60; }
        .btn.purple { background:#9b59b6; }
        .lab { background:#fff7e6; border-left:4px solid #fa8c16; padding:16px; border-radius:10px; margin-top:24px; }
        .lab ul { line-height:1.8; }
        .timeline { background:#fff; border-radius:14px; padding:20px; margin-top:24px; box-shadow:0 4px 14px rgba(0,0,0,.06); }
        .timeline li { margin:10px 0; line-height:1.7; }
        code { background:#f0f0f0; padding:2px 6px; border-radius:4px; }
    </style>
</head>
<body>
    <div class="hero">
        <h1>🚀 Struts2 Learning Scaffold</h1>
        <p>不是单纯的 Struts2 演示页，而是一套带任务卡、表单实验、拦截器观察和 CRUD 流程的学习脚手架。</p>
        <a href="learn" class="btn green">进入学习中心</a>
    </div>

    <div class="lab">
        <strong>推荐学习顺序</strong>
        <ul>
            <li><strong>第一步：</strong> 进入 <a href="hello">Hello 示例</a>，理解 Action → JSP 的最小闭环</li>
            <li><strong>第二步：</strong> 进入 <a href="calc">计算器</a>，体验表单绑定、校验、错误回显</li>
            <li><strong>第三步：</strong> 进入 <a href="interceptor">拦截器演示</a>，观察请求被增强的过程</li>
            <li><strong>第四步：</strong> 进入 <a href="user">用户管理</a>，学习列表/表单/增删改的完整流程</li>
        </ul>
    </div>

    <div class="grid">
        <div class="card">
            <h3>👋 Hello 示例</h3>
            <p>最小 Action 示例，适合理解 Struts2 如何把请求映射到 Action，再把数据渲染到 JSP。</p>
            <a href="hello" class="btn">打开示例</a>
        </div>
        <div class="card">
            <h3>🔢 计算器实验</h3>
            <p>学习参数绑定、<code>validate()</code> 校验、字段错误回显，以及成功/失败两条分支。</p>
            <a href="calc" class="btn">开始实验</a>
        </div>
        <div class="card">
            <h3>🛡️ 拦截器观察</h3>
            <p>重点模块。能看到日志、执行时间、限流、监控等拦截器如何织入请求链路。</p>
            <a href="interceptor" class="btn purple">观察拦截器</a>
        </div>
        <div class="card">
            <h3>👥 用户 CRUD</h3>
            <p>从列表页到表单页，再到新增/编辑/删除，形成完整的 Struts2 业务流学习闭环。</p>
            <a href="user" class="btn green">进入 CRUD</a>
        </div>
        <div class="card">
            <h3>🧪 OGNL / 参数绑定实验</h3>
            <p>可视化体验普通字段、嵌套对象、多选列表是如何被 Struts2 自动绑定到 Action 的。</p>
            <a href="ognl" class="btn purple">进入实验室</a>
        </div>
        <div class="card">
            <h3>⚠️ 验证与错误流实验</h3>
            <p>通过错误示例/正确示例切换，直观看到字段错误、input 返回和成功路径的区别。</p>
            <a href="validation" class="btn">进入实验室</a>
        </div>
        <div class="card">
            <h3>🚀 AJAX 异步交互</h3>
            <p>学习Struts2如何处理AJAX请求，返回JSON数据，实现前后端分离交互。</p>
            <a href="ajax" class="btn purple">AJAX演示</a>
        </div>
        <div class="card">
            <h3>📁 文件上传</h3>
            <p>演示单文件、多文件上传，文件类型和大小验证，以及文件处理流程。</p>
            <a href="upload" class="btn green">文件上传</a>
        </div>
    </div>

    <div class="timeline">
        <h3>📚 你会学到什么</h3>
        <ul>
            <li><strong>请求入口：</strong><code>StrutsPrepareAndExecuteFilter</code> 如何接管请求</li>
            <li><strong>控制层：</strong>Action 如何接收参数、执行业务、返回 result</li>
            <li><strong>视图层：</strong>JSP + Struts 标签库如何绑定 Action 数据</li>
            <li><strong>增强机制：</strong>Interceptor Stack 如何像 AOP 一样织入日志、校验、限流</li>
            <li><strong>状态流转：</strong>输入错误、成功提交、重定向返回列表等典型页面流</li>
        </ul>
    </div>
</body>
</html>
