Переглянути джерело

Add filter functionality for audit questions page: creator and date filters, remove sync to questions table, fix code formatting

linh 3 тижнів тому
батько
коміт
4a693a4317
5 змінених файлів з 397 додано та 74 видалено
  1. 5 4
      README.md
  2. 35 50
      app.py
  3. 0 1
      requirements.txt
  4. 0 14
      run_web.py
  5. 357 5
      templates/audit_questions.html

+ 5 - 4
README.md

@@ -192,21 +192,22 @@ python run_web.py
 
 ## 数据同步机制
 
-### questions_tem → questions 同步规则
+### questions_tem 表操作说明
+
+**重要变更**:所有操作(包括录入、编辑、审核)都只在 `questions_tem` 表中进行,**不再同步到 `questions` 表**。
 
 1. **未审核题目**(`audit_reason` 为 NULL 或空):
    - 只存在于 `questions_tem` 表
-   - **不会**同步到 `questions` 表
 
 2. **审核通过**(`audit_reason = "合格"`):
    - 更新 `questions_tem` 表的审核状态
-   - **自动同步**到 `questions` 表(INSERT 或 UPDATE)
+   - **不会**同步到 `questions` 表
 
 3. **审核不通过**(`audit_reason = "不合格"`):
    - 更新 `questions_tem` 表的审核状态
    - **不会**同步到 `questions` 表
 
-**总结**:只有审核通过("合格")的题目才会同步到正式的 `questions` 表。
+**总结**:所有题目操作都只在 `questions_tem` 表中进行,无论审核状态如何都不会同步到 `questions` 表。
 
 ## 项目结构
 

+ 35 - 50
app.py

@@ -809,6 +809,10 @@ def _api_questions_by_kp(kp_code, audit_only=False):
         
         # 获取年级筛选参数(可选)
         grade_filter = request.args.get('grade', type=int)
+        # 获取创建人筛选参数(可选)
+        create_by_filter = request.args.get('create_by', type=str)
+        # 获取创建时间筛选参数(可选,格式:YYYY-MM-DD)
+        created_at_filter = request.args.get('created_at', type=str)
         # 获取分页参数(可选)
         page = request.args.get('page', type=int, default=1)
         page_size = 20  # 每页显示20道题
@@ -825,7 +829,11 @@ def _api_questions_by_kp(kp_code, audit_only=False):
         params = []
         
         # 知识点条件
-        if kp_code == 'null' or kp_code == '':
+        # 如果kp_code为'all',表示查询所有题目(不限制知识点)
+        if kp_code == 'all':
+            kp_name = "全部题目"
+            # 不添加知识点条件,查询所有题目
+        elif kp_code == 'null' or kp_code == '':
             where_conditions.append("(kp_code IS NULL OR kp_code = '' OR kp_code = 'null')")
             kp_name = "其他题目"
         else:
@@ -843,6 +851,16 @@ def _api_questions_by_kp(kp_code, audit_only=False):
             where_conditions.append("grade IS NOT NULL AND CAST(grade AS UNSIGNED) = %s")
             params.append(grade_filter)
         
+        # 创建人筛选条件
+        if create_by_filter:
+            where_conditions.append("create_by = %s")
+            params.append(create_by_filter)
+        
+        # 创建时间筛选条件(按天筛选)
+        if created_at_filter:
+            where_conditions.append("DATE(created_at) = %s")
+            params.append(created_at_filter)
+        
         where_clause = " AND ".join(where_conditions)
         
         # 先查询总数(用于分页)
@@ -875,7 +893,9 @@ def _api_questions_by_kp(kp_code, audit_only=False):
                 answer,
                 solution,
                 options,
-                grade
+                grade,
+                create_by,
+                created_at
             FROM questions_tem 
             WHERE {where_clause}
             ORDER BY id DESC
@@ -1128,6 +1148,15 @@ def audit_questions():
         pass_rate = (pass_count / audited_count * 100) if audited_count > 0 else 0
         audit_rate = (audited_count / total * 100) if total > 0 else 0
         
+        # 查询所有创建人列表(用于筛选)
+        cursor.execute("""
+            SELECT DISTINCT create_by 
+            FROM questions_tem 
+            WHERE create_by IS NOT NULL AND create_by != '' 
+            ORDER BY create_by
+        """)
+        creators = [row['create_by'] for row in cursor.fetchall()]
+        
         conn.close()
         
         return render_template('audit_questions.html', 
@@ -1139,7 +1168,8 @@ def audit_questions():
                              pending_count=pending_count,
                              audited_count=audited_count,
                              pass_rate=round(pass_rate, 1),
-                             audit_rate=round(audit_rate, 1))
+                             audit_rate=round(audit_rate, 1),
+                             creators=creators)
     except Exception as e:
         return render_db_error(e)
 
@@ -1443,56 +1473,11 @@ def audit():
         cursor = conn.cursor(dictionary=True)
         
         # 更新 questions_tem 表的审核状态
+        # 注意:所有操作只在 questions_tem 表,不再同步到 questions 表
         cursor.execute("UPDATE questions_tem SET audit_reason=%s, audit_status=%s WHERE question_code=%s", 
                        (status_text, status_val, q_code))
         
-        # 如果审核通过(合格),将题目插入到 questions 表
-        if status_text == "合格":
-            # 从 questions_tem 表获取所有字段数据
-            cursor.execute("SELECT * FROM questions_tem WHERE question_code = %s", (q_code,))
-            question_data = cursor.fetchone()
-            
-            if question_data:
-                # 检查 questions 表是否已存在该 question_code
-                cursor.execute("SELECT question_code FROM questions WHERE question_code = %s", (q_code,))
-                existing = cursor.fetchone()
-                
-                # 准备要插入/更新的字段(排除 id 和 is_repeat,因为 questions 表没有 is_repeat 字段)
-                fields_to_copy = [
-                    'question_code', 'kp_id', 'textbook_catalog_nodes_id', 'stem', 'options',
-                    'answer', 'solution', 'difficulty', 'question_category', 'source', 'tags',
-                    'question_type', 'source_file_id', 'source_paper_id', 'paper_part_id',
-                    'textbook_id', 'meta', 'created_at', 'updated_at', 'audit_status',
-                    'audit_reason', 'title_1', 'title_2', 'title_3', 'create_by',
-                    'kp_code', 'kp_name', 'kp_reference'
-                ]
-                
-                if existing:
-                    # 如果已存在,更新数据
-                    update_fields = []
-                    update_values = []
-                    for field in fields_to_copy:
-                        if field in question_data:
-                            update_fields.append(f"{field} = %s")
-                            update_values.append(question_data[field])
-                    update_values.append(q_code)
-                    
-                    update_sql = f"UPDATE questions SET {', '.join(update_fields)} WHERE question_code = %s"
-                    cursor.execute(update_sql, tuple(update_values))
-                else:
-                    # 如果不存在,插入新数据
-                    insert_fields = []
-                    insert_values = []
-                    placeholders = []
-                    
-                    for field in fields_to_copy:
-                        if field in question_data:
-                            insert_fields.append(field)
-                            insert_values.append(question_data[field])
-                            placeholders.append('%s')
-                    
-                    insert_sql = f"INSERT INTO questions ({', '.join(insert_fields)}) VALUES ({', '.join(placeholders)})"
-                    cursor.execute(insert_sql, tuple(insert_values))
+        # 已移除同步到 questions 表的逻辑,所有操作只在 questions_tem 表
         
         conn.commit()
         conn.close()

+ 0 - 1
requirements.txt

@@ -3,4 +3,3 @@ mysql-connector-python>=9.0.0,<10
 waitress>=2.1.2,<3
 python-dotenv>=1.0.0,<2
 
-

+ 0 - 14
run_web.py

@@ -6,7 +6,6 @@ from waitress import serve
 
 
 def _load_dotenv_if_exists():
- 
     try:
         from dotenv import load_dotenv
     except Exception:
@@ -40,19 +39,6 @@ def main():
     # 正式服务(比 Flask debug 更稳定)
     try:
         serve(webapp.app, host=host, port=port, threads=8)
-    except KeyboardInterrupt:
-        print("\n服务已停止")
-    except OSError as e:
-        if "Address already in use" in str(e) or "只允许使用一次" in str(e):
-            print(f"端口 {port} 已被占用,请修改 config.env 中的 WEB_PORT")
-        else:
-            print(f"服务启动失败: {e}")
-        import traceback
-        traceback.print_exc()
-    except Exception as e:
-        print(f"服务启动失败: {e}")
-        import traceback
-        traceback.print_exc()
     except KeyboardInterrupt:
         print("\n\n服务已停止")
     except OSError as e:

+ 357 - 5
templates/audit_questions.html

@@ -92,13 +92,42 @@
     
     <!-- 右侧题目列表区域 -->
     <div class="flex-1">
+        <!-- 筛选栏 -->
+        <div id="filter-bar" class="apple-card p-4 mb-4">
+            <div class="flex items-center gap-4 flex-wrap">
+                <span class="text-sm font-medium text-gray-700">筛选:</span>
+                
+                <!-- 创建人筛选 -->
+                <div class="flex items-center gap-2">
+                    <label class="text-sm text-gray-600">创建人:</label>
+                    <select id="filter-create-by" class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
+                        <option value="">全部</option>
+                        {% for creator in creators|default([]) %}
+                        <option value="{{ creator }}">{{ creator }}</option>
+                        {% endfor %}
+                    </select>
+                </div>
+                
+                <!-- 创建时间筛选 -->
+                <div class="flex items-center gap-2">
+                    <label class="text-sm text-gray-600">创建时间:</label>
+                    <input type="date" id="filter-created-at" class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
+                </div>
+                
+                <!-- 重置按钮 -->
+                <button onclick="resetFilters()" class="px-4 py-1.5 bg-gray-100 text-gray-700 rounded-lg text-sm hover:bg-gray-200 transition-colors">
+                    重置
+                </button>
+            </div>
+        </div>
+        
         <div id="questions-container" class="space-y-4">
             <div class="apple-card p-12 text-center">
                 <div class="text-gray-400 mb-4">
                     <i class="ri-file-check-line text-6xl"></i>
                 </div>
-                <h3 class="text-lg font-bold text-gray-600 mb-2">请选择左侧知识点</h3>
-                <p class="text-sm text-gray-500 mb-6">点击知识点查看该知识点下的未审核题目</p>
+                <h3 class="text-lg font-bold text-gray-600 mb-2">请选择左侧知识点或设置筛选条件</h3>
+                <p class="text-sm text-gray-500 mb-6">点击知识点查看该知识点下的未审核题目,或使用筛选条件查看所有题目</p>
             </div>
         </div>
     </div>
@@ -136,7 +165,7 @@ function toggleKpNode(kpCode) {
 let currentKpCode = null;
 let currentKpName = null;
 
-// 加载指定知识点的未审核题目列表(支持分页)
+// 加载指定知识点的未审核题目列表(支持分页和筛选
 function loadPendingQuestionsByKp(kpCode, kpName, linkElement, page = null) {
     const container = document.getElementById('questions-container');
     if (!container) return;
@@ -170,10 +199,24 @@ function loadPendingQuestionsByKp(kpCode, kpName, linkElement, page = null) {
         page = pageParam ? parseInt(pageParam) : 1;
     }
     
-    // 构建请求URL(添加分页参数)
+    // 获取筛选参数
+    const createByFilter = document.getElementById('filter-create-by')?.value || '';
+    const createdAtFilter = document.getElementById('filter-created-at')?.value || '';
+    
+    // 构建请求URL(添加分页和筛选参数)
     let apiUrl = `/api/pending_questions_by_kp/${encodeURIComponent(kpCode)}`;
+    const params = new URLSearchParams();
     if (page > 1) {
-        apiUrl += `?page=${page}`;
+        params.append('page', page);
+    }
+    if (createByFilter) {
+        params.append('create_by', createByFilter);
+    }
+    if (createdAtFilter) {
+        params.append('created_at', createdAtFilter);
+    }
+    if (params.toString()) {
+        apiUrl += '?' + params.toString();
     }
     
     // 请求未审核题目列表
@@ -389,6 +432,315 @@ function loadPendingQuestionsByKpPage(kpCode, page) {
     loadPendingQuestionsByKp(kpCode, kpName, linkElement, page);
 }
 
+// 加载所有题目(根据筛选条件)
+function loadAllQuestionsByFilter(page = 1) {
+    const container = document.getElementById('questions-container');
+    if (!container) return;
+    
+    // 获取筛选参数
+    const createByFilter = document.getElementById('filter-create-by')?.value || '';
+    const createdAtFilter = document.getElementById('filter-created-at')?.value || '';
+    
+    // 如果没有筛选条件,不加载
+    if (!createByFilter && !createdAtFilter) {
+        // 如果有选择的知识点,加载该知识点;否则显示提示
+        if (currentKpCode !== null) {
+            const linkElement = document.querySelector(`.kp-link[data-kp-code="${currentKpCode}"]`);
+            const kpName = linkElement ? (linkElement.getAttribute('data-kp-name') || currentKpCode) : currentKpCode;
+            loadPendingQuestionsByKp(currentKpCode, kpName, linkElement, page);
+        } else {
+            container.innerHTML = `
+                <div class="apple-card p-12 text-center">
+                    <div class="text-gray-400 mb-4">
+                        <i class="ri-file-check-line text-6xl"></i>
+                    </div>
+                    <h3 class="text-lg font-bold text-gray-600 mb-2">请选择左侧知识点或设置筛选条件</h3>
+                    <p class="text-sm text-gray-500 mb-6">点击知识点查看该知识点下的未审核题目,或使用筛选条件查看所有题目</p>
+                </div>
+            `;
+        }
+        return;
+    }
+    
+    // 清除左侧选中状态
+    document.querySelectorAll('.kp-link').forEach(link => {
+        link.classList.remove('bg-orange-50', 'border-orange-400');
+    });
+    
+    // 显示加载状态
+    container.innerHTML = `
+        <div class="apple-card p-12 text-center">
+            <div class="text-orange-500 mb-4">
+                <i class="ri-loader-4-line text-6xl animate-spin"></i>
+            </div>
+            <p class="text-gray-600">正在加载未审核题目...</p>
+        </div>
+    `;
+    
+    // 构建请求URL(使用'all'表示所有题目)
+    let apiUrl = `/api/pending_questions_by_kp/all`;
+    const params = new URLSearchParams();
+    if (page > 1) {
+        params.append('page', page);
+    }
+    if (createByFilter) {
+        params.append('create_by', createByFilter);
+    }
+    if (createdAtFilter) {
+        params.append('created_at', createdAtFilter);
+    }
+    if (params.toString()) {
+        apiUrl += '?' + params.toString();
+    }
+    
+    // 请求题目列表
+    fetch(apiUrl)
+        .then(response => response.json())
+        .then(data => {
+            if (!data.success) {
+                throw new Error(data.error || '加载失败');
+            }
+            
+            const questions = data.questions || [];
+            const kpName = data.kp_name || '全部题目';
+            
+            // 获取分页信息
+            const pagination = data.pagination || {};
+            const currentPage = pagination.page || 1;
+            const totalPages = pagination.total_pages || 1;
+            const totalCount = pagination.total_count || questions.length;
+            const pageSize = pagination.page_size || 20;
+            const startIndex = (currentPage - 1) * pageSize;
+            const endIndex = Math.min(startIndex + pageSize, totalCount);
+            
+            // 渲染题目列表(复用相同的渲染逻辑)
+            let html = '';
+            
+            html += `<div class="space-y-3 mt-6">`;
+            
+            if (questions.length === 0) {
+                html += `
+                    <div class="apple-card p-12 text-center">
+                        <div class="text-gray-400 mb-4">
+                            <i class="ri-file-list-line text-6xl"></i>
+                        </div>
+                        <h3 class="text-lg font-bold text-gray-600 mb-2">没有找到符合条件的题目</h3>
+                        <p class="text-sm text-gray-500">请尝试调整筛选条件</p>
+                    </div>
+                `;
+            } else {
+                questions.forEach(q => {
+                    let auditBadge = '<span class="bg-orange-100 text-orange-700 px-2 py-0.5 rounded text-xs font-bold whitespace-nowrap">待审核</span>';
+                    
+                    let difficultyBadge = '';
+                    if (q.difficulty !== null && q.difficulty !== undefined) {
+                        const diff = parseFloat(q.difficulty);
+                        if (diff === 0.2 || Math.abs(diff - 0.2) < 0.1) {
+                            difficultyBadge = '<span class="px-2 py-0.5 rounded-full text-xs font-bold bg-green-100 text-green-700 border border-green-200 whitespace-nowrap">筑基</span>';
+                        } else if (diff === 0.4 || Math.abs(diff - 0.4) < 0.1) {
+                            difficultyBadge = '<span class="px-2 py-0.5 rounded-full text-xs font-bold bg-yellow-100 text-yellow-700 border border-yellow-200 whitespace-nowrap">提分</span>';
+                        } else if (diff === 0.7 || Math.abs(diff - 0.7) < 0.1) {
+                            difficultyBadge = '<span class="px-2 py-0.5 rounded-full text-xs font-bold bg-orange-100 text-orange-700 border border-orange-200 whitespace-nowrap">培优</span>';
+                        }
+                    }
+                    
+                    const typeMap = {'choice': '选择题', 'fill': '填空题', 'answer': '解答题'};
+                    const questionTypeText = typeMap[q.question_type] || q.question_type || '未分类';
+                    
+                    let gradeBadge = '';
+                    if (q.grade !== null && q.grade !== undefined) {
+                        const grade = parseInt(q.grade);
+                        if (grade === 1) {
+                            gradeBadge = '<span class="px-2 py-0.5 rounded-full text-xs font-bold bg-pink-100 text-pink-700 border border-pink-200 whitespace-nowrap">小学</span>';
+                        } else if (grade === 2) {
+                            gradeBadge = '<span class="px-2 py-0.5 rounded-full text-xs font-bold bg-blue-100 text-blue-700 border border-blue-200 whitespace-nowrap">初中</span>';
+                        } else if (grade === 3) {
+                            gradeBadge = '<span class="px-2 py-0.5 rounded-full text-xs font-bold bg-purple-100 text-purple-700 border border-purple-200 whitespace-nowrap">高中</span>';
+                        }
+                    }
+                    
+                    const stemText = (q.stem || '').replace(/<[^>]*>/g, '').substring(0, 150);
+                    
+                    html += `
+                        <a href="/detail/${q.question_code}" 
+                           class="apple-card p-4 block group hover:shadow-lg transition-all border-l-4 border-transparent hover:border-blue-500">
+                            <div class="flex items-center gap-4">
+                                <div class="flex-shrink-0">
+                                    <span class="text-xs font-mono text-gray-500 bg-gray-100 px-3 py-1.5 rounded font-semibold">${q.question_code}</span>
+                                </div>
+                                <div class="flex-1 min-w-0">
+                                    <div class="text-sm text-gray-800 group-hover:text-blue-600 transition-colors line-clamp-1">
+                                        ${stemText}${stemText.length >= 150 ? '...' : ''}
+                                    </div>
+                                </div>
+                                <div class="flex items-center gap-3 flex-shrink-0">
+                                    <span class="text-xs text-gray-500 bg-gray-50 px-2 py-1 rounded">${questionTypeText}</span>
+                                    ${gradeBadge}
+                                    ${difficultyBadge}
+                                    ${auditBadge}
+                                    <span class="text-xs text-blue-600 font-medium opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap">查看详情 →</span>
+                                </div>
+                            </div>
+                        </a>
+                    `;
+                });
+                
+                // 添加分页控件
+                if (totalPages > 1) {
+                    html += `
+                        <div class="mt-6 flex items-center justify-between">
+                            <div class="text-sm text-gray-600">
+                                显示第 ${startIndex + 1}-${endIndex} 题,共 ${totalCount} 题
+                            </div>
+                            <div class="flex items-center gap-2">
+                                <button 
+                                    onclick="loadAllQuestionsByFilterPage(${currentPage - 1})"
+                                    ${currentPage === 1 ? 'disabled' : ''}
+                                    class="px-4 py-2 rounded-lg text-sm font-medium transition-all border-2 ${
+                                        currentPage === 1 
+                                            ? 'border-gray-200 bg-gray-50 text-gray-400 cursor-not-allowed' 
+                                            : 'border-blue-300 bg-white text-blue-700 hover:bg-blue-50'
+                                    }">
+                                    <i class="ri-arrow-left-s-line"></i> 上一页
+                                </button>
+                                <div class="flex items-center gap-1">
+                                    ${Array.from({length: totalPages}, (_, i) => i + 1).map(p => {
+                                        if (p === 1 || p === totalPages || (p >= currentPage - 2 && p <= currentPage + 2)) {
+                                            return `
+                                                <button 
+                                                    onclick="loadAllQuestionsByFilterPage(${p})"
+                                                    class="px-3 py-2 rounded-lg text-sm font-medium transition-all border-2 ${
+                                                        p === currentPage
+                                                            ? 'border-blue-500 bg-blue-500 text-white'
+                                                            : 'border-gray-300 bg-white text-gray-700 hover:bg-gray-50'
+                                                    }">
+                                                    ${p}
+                                                </button>
+                                            `;
+                                        } else if (p === currentPage - 3 || p === currentPage + 3) {
+                                            return '<span class="px-2 text-gray-400">...</span>';
+                                        }
+                                        return '';
+                                    }).join('')}
+                                </div>
+                                <button 
+                                    onclick="loadAllQuestionsByFilterPage(${currentPage + 1})"
+                                    ${currentPage === totalPages ? 'disabled' : ''}
+                                    class="px-4 py-2 rounded-lg text-sm font-medium transition-all border-2 ${
+                                        currentPage === totalPages 
+                                            ? 'border-gray-200 bg-gray-50 text-gray-400 cursor-not-allowed' 
+                                            : 'border-blue-300 bg-white text-blue-700 hover:bg-blue-50'
+                                    }">
+                                    下一页 <i class="ri-arrow-right-s-line"></i>
+                                </button>
+                            </div>
+                        </div>
+                    `;
+                }
+            }
+            
+            html += '</div>';
+            container.innerHTML = html;
+            
+            // 渲染数学公式
+            if (window.renderMathInElement) {
+                container.querySelectorAll('.math-render').forEach(el => {
+                    try {
+                        window.renderMathInElement(el, {
+                            delimiters: [
+                                {left: "$$", right: "$$", display: true},
+                                {left: "$", right: "$", display: false},
+                                {left: "\\(", right: "\\)", display: false},
+                                {left: "\\[", right: "\\]", display: true}
+                            ],
+                            throwOnError: false
+                        });
+                    } catch (e) {
+                        console.warn('数学公式渲染失败:', e);
+                    }
+                });
+            }
+        })
+        .catch(error => {
+            container.innerHTML = `
+                <div class="apple-card p-12 text-center">
+                    <div class="text-red-400 mb-4">
+                        <i class="ri-error-warning-line text-6xl"></i>
+                    </div>
+                    <h3 class="text-lg font-bold text-gray-600 mb-2">加载失败</h3>
+                    <p class="text-sm text-red-500">${error.message || '未知错误'}</p>
+                </div>
+            `;
+        });
+}
+
+// 分页加载所有题目(根据筛选条件)
+function loadAllQuestionsByFilterPage(page) {
+    loadAllQuestionsByFilter(page);
+}
+
+// 重置筛选条件
+function resetFilters() {
+    document.getElementById('filter-create-by').value = '';
+    const dateInput = document.getElementById('filter-created-at');
+    if (dateInput) {
+        dateInput.value = '';
+    }
+    // 重新加载当前知识点的题目,如果没有选择知识点则显示提示
+    if (currentKpCode !== null) {
+        const linkElement = document.querySelector(`.kp-link[data-kp-code="${currentKpCode}"]`);
+        const kpName = linkElement ? (linkElement.getAttribute('data-kp-name') || currentKpCode) : currentKpCode;
+        loadPendingQuestionsByKp(currentKpCode, kpName, linkElement, 1);
+    } else {
+        const container = document.getElementById('questions-container');
+        if (container) {
+            container.innerHTML = `
+                <div class="apple-card p-12 text-center">
+                    <div class="text-gray-400 mb-4">
+                        <i class="ri-file-check-line text-6xl"></i>
+                    </div>
+                    <h3 class="text-lg font-bold text-gray-600 mb-2">请选择左侧知识点或设置筛选条件</h3>
+                    <p class="text-sm text-gray-500 mb-6">点击知识点查看该知识点下的未审核题目,或使用筛选条件查看所有题目</p>
+                </div>
+            `;
+        }
+    }
+}
+
+// 监听筛选条件变化
+document.addEventListener('DOMContentLoaded', function() {
+    const createByFilter = document.getElementById('filter-create-by');
+    const createdAtFilter = document.getElementById('filter-created-at');
+    
+    // 检查是否有筛选条件的函数
+    function checkAndLoad() {
+        const createBy = createByFilter?.value || '';
+        const createdAt = createdAtFilter?.value || '';
+        
+        // 如果有筛选条件,加载所有题目
+        if (createBy || createdAt) {
+            loadAllQuestionsByFilter(1);
+        } else {
+            // 如果没有筛选条件,加载当前知识点的题目
+            if (currentKpCode !== null) {
+                const linkElement = document.querySelector(`.kp-link[data-kp-code="${currentKpCode}"]`);
+                const kpName = linkElement ? (linkElement.getAttribute('data-kp-name') || currentKpCode) : currentKpCode;
+                loadPendingQuestionsByKp(currentKpCode, kpName, linkElement, 1);
+            }
+        }
+    }
+    
+    if (createByFilter) {
+        createByFilter.addEventListener('change', checkAndLoad);
+    }
+    
+    if (createdAtFilter) {
+        // 日期选择器支持 change 和 input 事件
+        createdAtFilter.addEventListener('change', checkAndLoad);
+        createdAtFilter.addEventListener('input', checkAndLoad);
+    }
+});
+
 // 页面加载完成后,初始化知识点目录
 document.addEventListener('DOMContentLoaded', function() {
     // 默认展开第一级节点