<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>文件上传 - Struts2</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f7fa; padding: 20px; }
        .container { max-width: 1000px; margin: 0 auto; }
        
        .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 15px; margin-bottom: 30px; text-align: center; }
        .header h1 { font-size: 2em; margin-bottom: 10px; }
        
        .card { background: white; border-radius: 12px; padding: 25px; margin-bottom: 20px; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }
        .card h3 { color: #333; margin-bottom: 15px; border-bottom: 2px solid #eee; padding-bottom: 10px; }
        
        .form-group { margin-bottom: 20px; }
        .form-group label { display: block; margin-bottom: 8px; color: #555; font-weight: 500; }
        .form-group input[type="text"] { width: 100%; padding: 10px 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 14px; }
        .form-group input[type="file"] { padding: 10px; border: 2px dashed #ddd; border-radius: 6px; width: 100%; cursor: pointer; }
        .form-group input[type="file"]:hover { border-color: #667eea; }
        
        .file-list { margin-top: 10px; }
        .file-item { background: #f8f9fa; padding: 10px; border-radius: 6px; margin-bottom: 8px; display: flex; align-items: center; }
        .file-item .name { flex: 1; }
        .file-item .size { color: #666; font-size: 12px; }
        .file-item .remove { color: #e74c3c; cursor: pointer; margin-left: 10px; }
        
        .btn { padding: 12px 24px; border: none; border-radius: 6px; cursor: pointer; font-size: 14px; transition: all 0.3s; }
        .btn-primary { background: #667eea; color: white; }
        .btn-primary:hover { background: #5a6fd6; }
        .btn-success { background: #27ae60; color: white; }
        .btn-success:hover { background: #219a52; }
        
        .result { background: #d4edda; color: #155724; padding: 15px; border-radius: 8px; margin-top: 15px; }
        .result.error { background: #f8d7da; color: #721c24; }
        
        .file-info { background: #f8f9fa; padding: 15px; border-radius: 8px; margin-top: 15px; }
        .file-info .item { display: flex; margin-bottom: 8px; }
        .file-info .label { width: 120px; color: #666; }
        .file-info .value { flex: 1; font-weight: 500; }
        
        .progress { width: 100%; height: 20px; background: #e0e0e0; border-radius: 10px; overflow: hidden; margin-top: 10px; }
        .progress-bar { height: 100%; background: linear-gradient(90deg, #667eea, #764ba2); width: 0%; transition: width 0.3s; }
        
        .lab { background: #fff7e6; border-left: 4px solid #fa8c16; padding: 15px; border-radius: 8px; margin-bottom: 20px; }
        .lab strong { color: #874d00; }
        
        .nav { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
        .nav a { padding: 10px 20px; background: white; border-radius: 20px; text-decoration: none; color: #333; font-size: 0.9em; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
        .nav a:hover { background: #667eea; color: white; }
        
        .tips { background: #e8f4f8; padding: 15px; border-radius: 8px; margin-top: 15px; }
        .tips ul { margin-left: 20px; }
        .tips li { margin-bottom: 5px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📁 文件上传演示</h1>
            <p>学习Struts2如何处理文件上传，包括单文件、多文件上传和文件验证</p>
        </div>
        
        <div class="nav">
            <a href="index.jsp">← 返回首页</a>
            <a href="learn">学习中心</a>
            <a href="ajax-demo">AJAX演示</a>
        </div>
        
        <div class="lab">
            <strong>🧪 实验任务</strong>
            <ul>
                <li>使用"单文件上传"上传一个图片或文档，观察上传结果</li>
                <li>使用"多文件上传"一次性选择多个文件</li>
                <li>尝试上传超过10MB的文件，观察验证错误</li>
                <li>尝试上传不支持的文件类型（如.exe），观察类型验证</li>
            </ul>
        </div>
        
        <!-- 单文件上传 -->
        <div class="card">
            <h3>📄 单文件上传</h3>
            <s:form action="uploadSingle" method="post" enctype="multipart/form-data">
                <div class="form-group">
                    <label>选择文件（支持图片、PDF、文本文件，最大10MB）:</label>
                    <s:file name="upload" accept="image/*,.pdf,.txt" />
                    <s:fielderror fieldName="upload" cssStyle="color: #e74c3c; font-size: 12px;" />
                </div>
                
                <div class="form-group">
                    <label>文件描述:</label>
                    <s:textfield name="description" placeholder="请输入文件描述" />
                </div>
                
                <s:submit value="上传文件" cssClass="btn btn-primary" />
            </s:form>
            
            <s:if test="uploadResult != null">
                <s:if test="uploadResult.success">
                    <div class="result">
                        <strong>✓ 上传成功</strong>
                    </div>
                    <div class="file-info">
                        <div class="item">
                            <span class="label">原始文件名:</span>
                            <span class="value"><s:property value="uploadResult.originalName"/></span>
                        </div>
                        <div class="item">
                            <span class="label">保存文件名:</span>
                            <span class="value"><s:property value="uploadResult.savedName"/></span>
                        </div>
                        <div class="item">
                            <span class="label">文件大小:</span>
                            <span class="value"><s:property value="uploadResult.fileSize"/> 字节</span>
                        </div>
                        <div class="item">
                            <span class="label">文件类型:</span>
                            <span class="value"><s:property value="uploadResult.contentType"/></span>
                        </div>
                        <div class="item">
                            <span class="label">描述:</span>
                            <span class="value"><s:property value="uploadResult.description"/></span>
                        </div>
                        <div class="item">
                            <span class="label">保存路径:</span>
                            <span class="value"><s:property value="uploadResult.filePath"/></span>
                        </div>
                    </div>
                </s:if>
                <s:else>
                    <div class="result error">
                        <strong>✗ 上传失败:</strong> <s:property value="uploadResult.error"/>
                    </div>
                </s:else>
            </s:if>
        </div>
        
        <!-- 多文件上传 -->
        <div class="card">
            <h3>📁 多文件上传</h3>
            <s:form action="uploadMultiple" method="post" enctype="multipart/form-data">
                <div class="form-group">
                    <label>选择多个文件（按住Ctrl或Cmd键多选）:</label>
                    <s:file name="uploads" multiple="true" accept="image/*,.pdf,.txt" />
                </div>
                
                <s:submit value="上传多个文件" cssClass="btn btn-success" />
            </s:form>
            
            <s:if test="uploadResult != null && uploadResult.files != null">
                <s:if test="uploadResult.success">
                    <div class="result">
                        <strong>✓ <s:property value="uploadResult.message"/></strong>
                    </div>
                    <div style="margin-top: 15px;">
                        <h4>上传的文件列表:</h4>
                        <table style="width: 100%; border-collapse: collapse; margin-top: 10px;">
                            <tr style="background: #3498db; color: white;">
                                <th style="padding: 10px; text-align: left;">文件名</th>
                                <th style="padding: 10px; text-align: left;">大小</th>
                                <th style="padding: 10px; text-align: left;">类型</th>
                                <th style="padding: 10px; text-align: left;">状态</th>
                            </tr>
                            <s:iterator value="uploadResult.files" var="file">
                                <tr style="border-bottom: 1px solid #ddd;">
                                    <td style="padding: 10px;"><s:property value="#file.originalName"/></td>
                                    <td style="padding: 10px;"><s:property value="#file.fileSize"/> 字节</td>
                                    <td style="padding: 10px;"><s:property value="#file.contentType"/></td>
                                    <td style="padding: 10px;">
                                        <s:if test="#file.success">
                                            <span style="color: #27ae60;">✓ 成功</span>
                                        </s:if>
                                        <s:else>
                                            <span style="color: #e74c3c;">✗ <s:property value="#file.error"/></span>
                                        </s:else>
                                    </td>
                                </tr>
                            </s:iterator>
                        </table>
                    </div>
                </s:if>
                <s:else>
                    <div class="result error">
                        <strong>✗ 上传失败:</strong> <s:property value="uploadResult.error"/>
                    </div>
                </s:else>
            </s:if>
        </div>
        
        <!-- 学习要点 -->
        <div class="card">
            <h3>📚 学习要点</h3>
            <ul>
                <li><strong>文件字段命名:</strong> 表单中的文件字段名必须与Action中的属性名一致（如 <code>upload</code>）</li>
                <li><strong>三个属性:</strong> Action需要提供 <code>File upload</code>、<code>String uploadFileName</code>、<code>String uploadContentType</code></li>
                <li><strong>多文件上传:</strong> 使用数组形式 <code>File[] uploads</code>、<code>String[] uploadsFileName</code> 等</li>
                <li><strong>表单enctype:</strong> 必须设置 <code>enctype="multipart/form-data"</code></li>
                <li><strong>文件验证:</strong> 可以在 <code>validate()</code> 方法中检查文件大小和类型</li>
                <li><strong>文件保存:</strong> 使用 <code>FileUtils.copyFile()</code> 或手动流操作保存文件</li>
            </ul>
            
            <div class="tips">
                <strong>💡 提示</strong>
                <ul>
                    <li>上传的文件默认保存在临时目录，需要手动移动到目标位置</li>
                    <li>建议生成唯一文件名避免冲突（如使用UUID）</li>
                    <li>生产环境应该限制上传目录的访问权限</li>
                    <li>大文件上传需要考虑分片上传和进度显示</li>
                </ul>
            </div>
        </div>
    </div>
</body>
</html>
