上传文件至 templates
This commit is contained in:
		
							
								
								
									
										164
									
								
								templates/all.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								templates/all.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
 | 
			
		||||
{% block title %}数据操作 - 紫金·稷下薪火·云枢智海师生成果共创系统{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<style>
 | 
			
		||||
    /* 基础样式重置 */
 | 
			
		||||
    * { margin: 0; padding: 0; box-sizing: border-box; }
 | 
			
		||||
 | 
			
		||||
    /* 容器样式 - 调整为靠左靠上 */
 | 
			
		||||
    .container {
 | 
			
		||||
        max-width: 1200px;
 | 
			
		||||
        margin: 0; /* 移除自动居中 */
 | 
			
		||||
        padding: 20px 0 0 20px; /* 顶部和左侧留白 */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 标题样式 - 减少底部边距 */
 | 
			
		||||
    h2 {
 | 
			
		||||
        color: #2c3e50;
 | 
			
		||||
        border-bottom: 2px solid #3498db;
 | 
			
		||||
        padding-bottom: 8px;
 | 
			
		||||
        margin-bottom: 15px; /* 减少间距 */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 描述文字样式 */
 | 
			
		||||
    p {
 | 
			
		||||
        margin-bottom: 15px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 表格容器 - 顶部边距调整 */
 | 
			
		||||
    .table-container {
 | 
			
		||||
        overflow-x: auto;
 | 
			
		||||
        margin-top: 15px; /* 减少顶部间距 */
 | 
			
		||||
        border-radius: 8px;
 | 
			
		||||
        box-shadow: 0 4px 6px rgba(0,0,0,0.1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 表格样式 */
 | 
			
		||||
    table {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        border-collapse: collapse;
 | 
			
		||||
        font-family: 'Segoe UI', Arial, sans-serif;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 表头样式 */
 | 
			
		||||
    thead {
 | 
			
		||||
        background: linear-gradient(135deg, #3498db, #1a5276);
 | 
			
		||||
        color: white;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    th {
 | 
			
		||||
        padding: 16px 12px;
 | 
			
		||||
        text-align: left;
 | 
			
		||||
        font-weight: 600;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 表格行样式 */
 | 
			
		||||
    tbody tr {
 | 
			
		||||
        border-bottom: 1px solid #eef1f5;
 | 
			
		||||
        transition: background-color 0.3s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tbody tr:nth-child(even) {
 | 
			
		||||
        background-color: #f8fafc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tbody tr:hover {
 | 
			
		||||
        background-color: #e3f2fd;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    td {
 | 
			
		||||
        padding: 14px 12px;
 | 
			
		||||
        color: #4a5568;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 操作按钮样式 */
 | 
			
		||||
    .action-button {
 | 
			
		||||
        padding: 6px 16px;
 | 
			
		||||
        border: none;
 | 
			
		||||
        border-radius: 4px;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        font-weight: 500;
 | 
			
		||||
        transition: all 0.3s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .delete-btn {
 | 
			
		||||
        background: linear-gradient(to right, #ff416c, #ff4b2b);
 | 
			
		||||
        color: white;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .delete-btn:hover {
 | 
			
		||||
        transform: translateY(-2px);
 | 
			
		||||
        box-shadow: 0 4px 8px rgba(255, 75, 43, 0.3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 返回按钮样式 */
 | 
			
		||||
    .back-btn {
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
        padding: 10px 20px;
 | 
			
		||||
        background: linear-gradient(to right, #0066cc, #003399);
 | 
			
		||||
        color: white;
 | 
			
		||||
        text-decoration: none;
 | 
			
		||||
        border-radius: 6px;
 | 
			
		||||
        margin-top: 15px; /* 减少顶部间距 */
 | 
			
		||||
        margin-left: 20px; /* 左侧对齐 */
 | 
			
		||||
        transition: transform 0.3s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .back-btn:hover {
 | 
			
		||||
        transform: translateY(-3px);
 | 
			
		||||
        box-shadow: 0 5px 15px rgba(0, 102, 204, 0.4);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 空数据提示 */
 | 
			
		||||
    .no-data {
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        padding: 40px 0;
 | 
			
		||||
        color: #a0aec0;
 | 
			
		||||
        font-style: italic;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<div class="container">
 | 
			
		||||
    <h2>所有已录入的奖项信息</h2>
 | 
			
		||||
    <p>在此页面可以查看所有已录入的成果信息,并进行删除操作</p>
 | 
			
		||||
 | 
			
		||||
    <div class="table-container">
 | 
			
		||||
        <table>
 | 
			
		||||
            <thead>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <th>比赛/论文名称</th>
 | 
			
		||||
                    <th>项目名称</th>
 | 
			
		||||
                    <th>学生</th>
 | 
			
		||||
                    <th>指导老师</th>
 | 
			
		||||
                    <th style="text-align: center;">操作</th>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
            <tbody>
 | 
			
		||||
                {% if data %}
 | 
			
		||||
                    {% for item in data %}
 | 
			
		||||
                        <tr>
 | 
			
		||||
                            <td>{{ item.id or '无' }}</td>
 | 
			
		||||
                            <td>{{ item.name or '无' }}</td>
 | 
			
		||||
                            <td>{% if item.students is string %}{{ item.students or '无' }}{% else %}{{ item.students|join(', ') if item.students else '无' }}{% endif %}</td>
 | 
			
		||||
                            <td>{% if item.teacher is string %}{{ item.teacher or '无' }}{% else %}{{ item.teacher|join(', ') if item.teacher else '无' }}{% endif %}</td>
 | 
			
		||||
                            <td style="text-align: center;">
 | 
			
		||||
                                <form action="{{ url_for('delete_entry', doc_id=item._id) }}" method="POST" onsubmit="return confirm('确定要删除这条记录吗?')">
 | 
			
		||||
                                    <button type="submit" class="action-button delete-btn">删除</button>
 | 
			
		||||
                                </form>
 | 
			
		||||
                            </td>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                {% else %}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td colspan="5" class="no-data">暂无数据</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
            </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <a href="{{ url_for('index') }}" class="back-btn">返回首页</a>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										177
									
								
								templates/base.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								templates/base.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="zh">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>{% block title %}紫金·稷下薪火·云枢智海师生成果共创系统{% endblock %}</title>
 | 
			
		||||
    <style>
 | 
			
		||||
        :root {
 | 
			
		||||
            --primary: #4361ee;
 | 
			
		||||
            --primary-light: #4895ef;
 | 
			
		||||
            --secondary: #3f37c9;
 | 
			
		||||
            --accent: #f72585;
 | 
			
		||||
            --light: #f8f9fa;
 | 
			
		||||
            --dark: #212529;
 | 
			
		||||
            --success: #4cc9f0;
 | 
			
		||||
            --warning: #fcaa18;
 | 
			
		||||
            --radius: 8px;
 | 
			
		||||
            --shadow: 0 4px 12px rgba(0,0,0,0.1);
 | 
			
		||||
            --transition: all 0.3s ease;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        body {
 | 
			
		||||
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
            background-color: #f5f7fb;
 | 
			
		||||
            color: #333;
 | 
			
		||||
            line-height: 1.6;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .header {
 | 
			
		||||
            background: linear-gradient(135deg, var(--primary), var(--secondary));
 | 
			
		||||
            color: white;
 | 
			
		||||
            padding: 15px 20px;
 | 
			
		||||
            box-shadow: var(--shadow);
 | 
			
		||||
            position: relative;
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .header:before {
 | 
			
		||||
            content: "";
 | 
			
		||||
            position: absolute;
 | 
			
		||||
            top: -50%;
 | 
			
		||||
            left: -50%;
 | 
			
		||||
            width: 200%;
 | 
			
		||||
            height: 200%;
 | 
			
		||||
            background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 60%);
 | 
			
		||||
            pointer-events: none;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .header h1 {
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            display: flex;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
            font-size: 24px;
 | 
			
		||||
            position: relative;
 | 
			
		||||
            z-index: 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .header h1 span {
 | 
			
		||||
            color: #ffcc00;
 | 
			
		||||
            text-shadow: 0 0 5px rgba(0,0,0,0.2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .sidebar {
 | 
			
		||||
            width: 240px;
 | 
			
		||||
            height: calc(100vh - 60px);
 | 
			
		||||
            float: left;
 | 
			
		||||
            background: linear-gradient(to bottom, #ffffff, #f5f7fb);
 | 
			
		||||
            padding: 20px 0;
 | 
			
		||||
            box-shadow: 2px 0 10px rgba(0,0,0,0.05);
 | 
			
		||||
            transition: var(--transition);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .sidebar a {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
            padding: 15px 25px;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
            color: var(--dark);
 | 
			
		||||
            font-size: 16px;
 | 
			
		||||
            transition: var(--transition);
 | 
			
		||||
            border-left: 3px solid transparent;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .sidebar a:hover {
 | 
			
		||||
            background-color: rgba(67, 97, 238, 0.08);
 | 
			
		||||
            border-left-color: var(--primary);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .sidebar a.active {
 | 
			
		||||
            background-color: rgba(67, 97, 238, 0.15);
 | 
			
		||||
            border-left-color: var(--primary);
 | 
			
		||||
            font-weight: 500;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .sidebar a i {
 | 
			
		||||
            margin-right: 12px;
 | 
			
		||||
            font-size: 18px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .content {
 | 
			
		||||
            margin-left: 240px;
 | 
			
		||||
            padding: 30px;
 | 
			
		||||
            background-color: white;
 | 
			
		||||
            min-height: calc(100vh - 60px);
 | 
			
		||||
            box-shadow: -2px 0 10px rgba(0,0,0,0.05);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card {
 | 
			
		||||
            background: white;
 | 
			
		||||
            border-radius: var(--radius);
 | 
			
		||||
            box-shadow: var(--shadow);
 | 
			
		||||
            padding: 25px;
 | 
			
		||||
            margin-bottom: 20px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @media (max-width: 768px) {
 | 
			
		||||
            .sidebar {
 | 
			
		||||
                width: 100%;
 | 
			
		||||
                height: auto;
 | 
			
		||||
                position: fixed;
 | 
			
		||||
                bottom: 0;
 | 
			
		||||
                left: 0;
 | 
			
		||||
                display: flex;
 | 
			
		||||
                justify-content: space-around;
 | 
			
		||||
                padding: 10px 0;
 | 
			
		||||
                z-index: 100;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            .sidebar a {
 | 
			
		||||
                padding: 12px 15px;
 | 
			
		||||
                border-left: none;
 | 
			
		||||
                text-align: center;
 | 
			
		||||
                font-size: 14px;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            .sidebar a i {
 | 
			
		||||
                display: block;
 | 
			
		||||
                margin-right: 0;
 | 
			
		||||
                margin-bottom: 5px;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            .content {
 | 
			
		||||
                margin-left: 0;
 | 
			
		||||
                padding: 20px 15px;
 | 
			
		||||
                min-height: calc(100vh - 110px);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div class="header">
 | 
			
		||||
        <h1><span>紫金</span> 稷下薪火·云枢智海师生成果共创系统</h1>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="sidebar">
 | 
			
		||||
        <a href="{{ url_for('index') }}" {% if request.endpoint == 'index' %}class="active"{% endif %}>
 | 
			
		||||
            <i>📊</i> 录入成果
 | 
			
		||||
        </a>
 | 
			
		||||
        <a href="{{ url_for('results_page') }}" {% if request.endpoint == 'results_page' %}class="active"{% endif %}>
 | 
			
		||||
            <i>📈</i> 查询统计
 | 
			
		||||
        </a>
 | 
			
		||||
        <a href="{{ url_for('show_all') }}" {% if request.endpoint == 'show_all' %}class="active"{% endif %}>
 | 
			
		||||
            <i>📁</i> 数据操作
 | 
			
		||||
        </a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="content">
 | 
			
		||||
        {% block content %}
 | 
			
		||||
        {% endblock %}
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- 添加字体图标库 -->
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										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 %}
 | 
			
		||||
							
								
								
									
										182
									
								
								templates/results.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								templates/results.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,182 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
 | 
			
		||||
{% block title %}查询统计 - 紫金·稷下薪火·云枢智海师生成果共创系统{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<style>
 | 
			
		||||
    /* 基础样式重置 */
 | 
			
		||||
    * { margin: 0; padding: 0; box-sizing: border-box; }
 | 
			
		||||
    
 | 
			
		||||
    /* 主体布局 */
 | 
			
		||||
    .container {
 | 
			
		||||
        max-width: 1200px;
 | 
			
		||||
        margin: 0 auto;
 | 
			
		||||
        padding: 20px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /* 标题样式 */
 | 
			
		||||
    h2 {
 | 
			
		||||
        color: #2c3e50;
 | 
			
		||||
        border-bottom: 2px solid #3498db;
 | 
			
		||||
        padding-bottom: 10px;
 | 
			
		||||
        margin-bottom: 20px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /* 搜索区域样式 */
 | 
			
		||||
    .search-container {
 | 
			
		||||
        background: #f8f9fa;
 | 
			
		||||
        padding: 25px;
 | 
			
		||||
        border-radius: 10px;
 | 
			
		||||
        box-shadow: 0 4px 6px rgba(0,0,0,0.1);
 | 
			
		||||
        margin-bottom: 30px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .search-form {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        gap: 10px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .search-input {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        padding: 12px 15px;
 | 
			
		||||
        border: 1px solid #ddd;
 | 
			
		||||
        border-radius: 6px;
 | 
			
		||||
        font-size: 16px;
 | 
			
		||||
        transition: border-color 0.3s;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .search-input:focus {
 | 
			
		||||
        border-color: #3498db;
 | 
			
		||||
        outline: none;
 | 
			
		||||
        box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .search-button {
 | 
			
		||||
        padding: 12px 25px;
 | 
			
		||||
        background: linear-gradient(135deg, #3498db, #1a5276);
 | 
			
		||||
        color: white;
 | 
			
		||||
        border: none;
 | 
			
		||||
        border-radius: 6px;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        font-weight: bold;
 | 
			
		||||
        transition: transform 0.2s, box-shadow 0.2s;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .search-button:hover {
 | 
			
		||||
        transform: translateY(-2px);
 | 
			
		||||
        box-shadow: 0 4px 8px rgba(52, 152, 219, 0.4);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /* 结果区域样式 */
 | 
			
		||||
    .results-container {
 | 
			
		||||
        min-height: 300px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .result-item {
 | 
			
		||||
        background: white;
 | 
			
		||||
        border-radius: 8px;
 | 
			
		||||
        padding: 20px;
 | 
			
		||||
        margin-bottom: 20px;
 | 
			
		||||
        box-shadow: 0 2px 10px rgba(0,0,0,0.05);
 | 
			
		||||
        border-left: 4px solid #3498db;
 | 
			
		||||
        transition: transform 0.3s;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .result-item:hover {
 | 
			
		||||
        transform: translateY(-3px);
 | 
			
		||||
        box-shadow: 0 5px 15px rgba(0,0,0,0.1);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .result-item p {
 | 
			
		||||
        margin-bottom: 10px;
 | 
			
		||||
        line-height: 1.6;
 | 
			
		||||
        color: #34495e;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .result-item strong {
 | 
			
		||||
        color: #2c3e50;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /* 加载状态 */
 | 
			
		||||
    .loading {
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        padding: 40px;
 | 
			
		||||
        color: #7f8c8d;
 | 
			
		||||
        font-style: italic;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /* 错误信息 */
 | 
			
		||||
    .error {
 | 
			
		||||
        color: #e74c3c;
 | 
			
		||||
        padding: 20px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        background: rgba(231, 76, 60, 0.1);
 | 
			
		||||
        border-radius: 6px;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<div class="container">
 | 
			
		||||
    <h2>奖项成果查询</h2>
 | 
			
		||||
    <p>输入关键词(如姓名、奖项名等)搜索已录入的成果信息</p>
 | 
			
		||||
    
 | 
			
		||||
    <div class="search-container">
 | 
			
		||||
        <form id="search-form" class="search-form">
 | 
			
		||||
            <input type="text" name="q" class="search-input" placeholder="输入关键词(如姓名、奖项名等)" required>
 | 
			
		||||
            <button type="submit" class="search-button">搜索</button>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div id="results" class="results-container">
 | 
			
		||||
        <!-- 结果将通过JS动态加载 -->
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    document.getElementById("search-form").addEventListener("submit", function (e) {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        const q = this.q.value;
 | 
			
		||||
        const resultsContainer = document.getElementById("results");
 | 
			
		||||
        
 | 
			
		||||
        // 显示加载状态
 | 
			
		||||
        resultsContainer.innerHTML = '<div class="loading">正在搜索,请稍候...</div>';
 | 
			
		||||
        
 | 
			
		||||
        fetch(`/search?q=${encodeURIComponent(q)}`)
 | 
			
		||||
            .then(res => res.json())
 | 
			
		||||
            .then(data => {
 | 
			
		||||
                const realData = data.hits?.hits || data;
 | 
			
		||||
                
 | 
			
		||||
                if (!Array.isArray(realData) || realData.length === 0) {
 | 
			
		||||
                    resultsContainer.innerHTML = '<div class="error">未找到相关结果</div>';
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                const html = realData.map(item => {
 | 
			
		||||
                    const source = item._source || {};
 | 
			
		||||
                    const students = Array.isArray(source.students)
 | 
			
		||||
                        ? source.students.join(', ')
 | 
			
		||||
                        : (source.students || '无');
 | 
			
		||||
                    
 | 
			
		||||
                    const teacher = Array.isArray(source.teacher)
 | 
			
		||||
                        ? source.teacher.join(', ')
 | 
			
		||||
                        : (source.teacher || '无');
 | 
			
		||||
                    
 | 
			
		||||
                    return `
 | 
			
		||||
                        <div class="result-item">
 | 
			
		||||
                            <p><strong>比赛/论文名称:</strong>${source.id || '无'}</p>
 | 
			
		||||
                            <p><strong>项目名称:</strong>${source.name || '无'}</p>
 | 
			
		||||
                            <p><strong>学生:</strong>${students}</p>
 | 
			
		||||
                            <p><strong>指导老师:</strong>${teacher}</p>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    `;
 | 
			
		||||
                }).join('');
 | 
			
		||||
                
 | 
			
		||||
                resultsContainer.innerHTML = html;
 | 
			
		||||
            })
 | 
			
		||||
            .catch(err => {
 | 
			
		||||
                resultsContainer.innerHTML = '<div class="error">搜索过程中发生错误</div>';
 | 
			
		||||
            });
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
		Reference in New Issue
	
	Block a user