上传文件至 templates
This commit is contained in:
		
							
								
								
									
										238
									
								
								templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								templates/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
 | 
			
		||||
{% block title %}录入成果 - 紫金·稷下薪火·云枢智海师生成果共创系统{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="card">
 | 
			
		||||
    <h2 style="color: var(--primary); border-bottom: 2px solid var(--primary); padding-bottom: 10px;">
 | 
			
		||||
        <i class="fas fa-cloud-upload-alt"></i> 成果录入
 | 
			
		||||
    </h2>
 | 
			
		||||
    <p class="mb-4">请上传包含成果信息的图片(如获奖证书、论文封面等),系统将自动识别关键信息</p>
 | 
			
		||||
 | 
			
		||||
    <form id="upload-form" enctype="multipart/form-data" class="mb-4">
 | 
			
		||||
        <div class="mb-3">
 | 
			
		||||
            <label for="file" class="form-label">选择图片文件</label>
 | 
			
		||||
            <input type="file" name="file" accept="image/*" id="file" class="form-control" required>
 | 
			
		||||
            <div class="form-text">支持JPG、PNG、GIF等格式,文件大小不超过10MB</div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <button type="submit" class="btn btn-primary btn-lg">
 | 
			
		||||
            <i class="fas fa-upload"></i> 上传图片
 | 
			
		||||
        </button>
 | 
			
		||||
    </form>
 | 
			
		||||
 | 
			
		||||
    <div id="result" class="mt-4"></div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    document.getElementById("upload-form").addEventListener("submit", function (e) {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        let formData = new FormData(this);
 | 
			
		||||
        const resultDiv = document.getElementById("result");
 | 
			
		||||
 | 
			
		||||
        // 显示上传进度动画
 | 
			
		||||
        resultDiv.innerHTML = `
 | 
			
		||||
            <div class="progress-container">
 | 
			
		||||
                <div class="progress-bar"></div>
 | 
			
		||||
                <p class="progress-text">正在处理图片,请稍候...</p>
 | 
			
		||||
            </div>
 | 
			
		||||
        `;
 | 
			
		||||
 | 
			
		||||
        fetch("/upload", { method: "POST", body: formData })
 | 
			
		||||
            .then(res => res.json())
 | 
			
		||||
            .then(data => {
 | 
			
		||||
                if(data.error) {
 | 
			
		||||
                    resultDiv.innerHTML = `
 | 
			
		||||
                        <div class="alert alert-danger">
 | 
			
		||||
                            <i class="fas fa-exclamation-circle"></i> 错误: ${data.error}
 | 
			
		||||
                        </div>
 | 
			
		||||
                    `;
 | 
			
		||||
                } else {
 | 
			
		||||
                    const resultHtml = `
 | 
			
		||||
                        <div class="result-card">
 | 
			
		||||
                            <div class="result-header">
 | 
			
		||||
                                <h3><i class="fas fa-check-circle"></i> 识别成功</h3>
 | 
			
		||||
                                <p class="timestamp">${new Date().toLocaleString()}</p>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="result-content">
 | 
			
		||||
                                ${Object.entries(data.data).map(([key, value]) => `
 | 
			
		||||
                                    <div class="result-item">
 | 
			
		||||
                                        <span class="result-label">${key.replace(/_/g, ' ')}</span>
 | 
			
		||||
                                        <span class="result-value">${value}</span>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                `).join('')}
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="result-footer">
 | 
			
		||||
                                <p class="success-message">${data.message}</p>
 | 
			
		||||
                                <button class="btn btn-outline-primary copy-btn" data-clipboard-text="${JSON.stringify(data.data)}">
 | 
			
		||||
                                    <i class="fas fa-copy"></i> 复制结果
 | 
			
		||||
                                </button>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    `;
 | 
			
		||||
                    resultDiv.innerHTML = resultHtml;
 | 
			
		||||
 | 
			
		||||
                    // 添加复制按钮功能
 | 
			
		||||
                    document.querySelector('.copy-btn').addEventListener('click', function() {
 | 
			
		||||
                        navigator.clipboard.writeText(this.getAttribute('data-clipboard-text'));
 | 
			
		||||
                        alert('结果已复制到剪贴板!');
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .catch(error => {
 | 
			
		||||
                resultDiv.innerHTML = `
 | 
			
		||||
                    <div class="alert alert-danger">
 | 
			
		||||
                        <i class="fas fa-exclamation-circle"></i> 上传失败: ${error}
 | 
			
		||||
                    </div>
 | 
			
		||||
                `;
 | 
			
		||||
            });
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
    .btn-primary {
 | 
			
		||||
        background: linear-gradient(135deg, var(--primary), var(--primary-light));
 | 
			
		||||
        border: none;
 | 
			
		||||
        border-radius: 30px;
 | 
			
		||||
        padding: 12px 24px;
 | 
			
		||||
        font-weight: 500;
 | 
			
		||||
        transition: var(--transition);
 | 
			
		||||
        box-shadow: 0 4px 8px rgba(67, 97, 238, 0.2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .btn-primary:hover {
 | 
			
		||||
        background: linear-gradient(135deg, var(--primary-light), var(--primary));
 | 
			
		||||
        transform: translateY(-2px);
 | 
			
		||||
        box-shadow: 0 6px 12px rgba(67, 97, 238, 0.3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .form-control {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        padding: 12px;
 | 
			
		||||
        border: 1px solid #ddd;
 | 
			
		||||
        border-radius: 8px;
 | 
			
		||||
        font-size: 16px;
 | 
			
		||||
        transition: var(--transition);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .form-control:hover {
 | 
			
		||||
        border-color: var(--primary);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .progress-container {
 | 
			
		||||
        background-color: #f8f9fa;
 | 
			
		||||
        border-radius: 8px;
 | 
			
		||||
        padding: 20px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .progress-bar {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 8px;
 | 
			
		||||
        background-color: #e9ecef;
 | 
			
		||||
        border-radius: 4px;
 | 
			
		||||
        margin-bottom: 15px;
 | 
			
		||||
        position: relative;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .progress-bar::after {
 | 
			
		||||
        content: "";
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        top: 0;
 | 
			
		||||
        left: -100%;
 | 
			
		||||
        width: 80%;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
        background: linear-gradient(90deg, transparent, #4cc9f0, transparent);
 | 
			
		||||
        animation: progress 1.5s infinite;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @keyframes progress {
 | 
			
		||||
        0% { left: -100%; }
 | 
			
		||||
        100% { left: 200%; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .progress-text {
 | 
			
		||||
        color: #6c757d;
 | 
			
		||||
        font-size: 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .alert {
 | 
			
		||||
        padding: 15px;
 | 
			
		||||
        border-radius: 8px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .alert-danger {
 | 
			
		||||
        background-color: #ffe3e3;
 | 
			
		||||
        color: #d32f2f;
 | 
			
		||||
        border-left: 4px solid #d32f2f;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .result-card {
 | 
			
		||||
        background: white;
 | 
			
		||||
        border-radius: 12px;
 | 
			
		||||
        box-shadow: var(--shadow);
 | 
			
		||||
        padding: 20px;
 | 
			
		||||
        border-left: 4px solid var(--success);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .result-header {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: space-between;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        padding-bottom: 15px;
 | 
			
		||||
        border-bottom: 1px solid #eee;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .result-header h3 {
 | 
			
		||||
        color: var(--success);
 | 
			
		||||
        margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .timestamp {
 | 
			
		||||
        color: #6c757d;
 | 
			
		||||
        font-size: 14px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .result-item {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: space-between;
 | 
			
		||||
        padding: 12px 0;
 | 
			
		||||
        border-bottom: 1px solid #f0f0f0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .result-label {
 | 
			
		||||
        font-weight: 500;
 | 
			
		||||
        color: #495057;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .result-value {
 | 
			
		||||
        color: #333;
 | 
			
		||||
        max-width: 70%;
 | 
			
		||||
        word-break: break-word;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .result-footer {
 | 
			
		||||
        margin-top: 20px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .success-message {
 | 
			
		||||
        color: var(--success);
 | 
			
		||||
        font-weight: 500;
 | 
			
		||||
        margin-bottom: 15px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .btn-outline-primary {
 | 
			
		||||
        border: 1px solid var(--primary);
 | 
			
		||||
        color: var(--primary);
 | 
			
		||||
        border-radius: 6px;
 | 
			
		||||
        padding: 8px 16px;
 | 
			
		||||
        transition: var(--transition);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .btn-outline-primary:hover {
 | 
			
		||||
        background-color: var(--primary);
 | 
			
		||||
        color: white;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
		Reference in New Issue
	
	Block a user