|
|
@@ -203,3 +203,131 @@ def get_card_list_with_images(
|
|
|
card['modified_image_path_list'][image_type] = image_data.get('modified_image_path')
|
|
|
|
|
|
return cards
|
|
|
+
|
|
|
+
|
|
|
+def get_card_list_and_count(
|
|
|
+ db_conn: PooledMySQLConnection,
|
|
|
+ card_id: Optional[int],
|
|
|
+ card_name: Optional[str],
|
|
|
+ card_type: Optional[CardType],
|
|
|
+ is_edited: Optional[bool],
|
|
|
+ min_detect_score: Optional[float],
|
|
|
+ max_detect_score: Optional[float],
|
|
|
+ min_mod_score: Optional[float],
|
|
|
+ max_mod_score: Optional[float],
|
|
|
+ created_start: Optional[date],
|
|
|
+ created_end: Optional[date],
|
|
|
+ updated_start: Optional[date],
|
|
|
+ updated_end: Optional[date],
|
|
|
+ sort_by: SortBy,
|
|
|
+ sort_order: SortOrder,
|
|
|
+ skip: int,
|
|
|
+ limit: int
|
|
|
+) -> Dict[str, Any]:
|
|
|
+ """
|
|
|
+ 同时获取符合条件的记录列表和总条数。
|
|
|
+ """
|
|
|
+ with db_conn.cursor(dictionary=True) as cursor:
|
|
|
+ # --- 第一部分:构建 WHERE 子句 (条件逻辑与之前保持一致) ---
|
|
|
+ conditions = []
|
|
|
+ params = []
|
|
|
+
|
|
|
+ if card_id is not None:
|
|
|
+ conditions.append("id = %s")
|
|
|
+ params.append(card_id)
|
|
|
+ if card_name:
|
|
|
+ conditions.append("card_name LIKE %s")
|
|
|
+ params.append(f"%{card_name}%")
|
|
|
+ if card_type:
|
|
|
+ conditions.append("card_type = %s")
|
|
|
+ params.append(card_type.value)
|
|
|
+ if is_edited is not None:
|
|
|
+ conditions.append("is_edited = %s")
|
|
|
+ params.append(is_edited)
|
|
|
+
|
|
|
+ # 分数筛选
|
|
|
+ if min_detect_score is not None:
|
|
|
+ conditions.append("detection_score >= %s")
|
|
|
+ params.append(min_detect_score)
|
|
|
+ if max_detect_score is not None:
|
|
|
+ conditions.append("detection_score <= %s")
|
|
|
+ params.append(max_detect_score)
|
|
|
+ if min_mod_score is not None:
|
|
|
+ conditions.append("modified_score >= %s")
|
|
|
+ params.append(min_mod_score)
|
|
|
+ if max_mod_score is not None:
|
|
|
+ conditions.append("modified_score <= %s")
|
|
|
+ params.append(max_mod_score)
|
|
|
+
|
|
|
+ # 日期筛选
|
|
|
+ if created_start:
|
|
|
+ conditions.append("DATE(created_at) >= %s")
|
|
|
+ params.append(created_start)
|
|
|
+ if created_end:
|
|
|
+ conditions.append("DATE(created_at) <= %s")
|
|
|
+ params.append(created_end)
|
|
|
+ if updated_start:
|
|
|
+ conditions.append("DATE(updated_at) >= %s")
|
|
|
+ params.append(updated_start)
|
|
|
+ if updated_end:
|
|
|
+ conditions.append("DATE(updated_at) <= %s")
|
|
|
+ params.append(updated_end)
|
|
|
+
|
|
|
+ where_clause = ""
|
|
|
+ if conditions:
|
|
|
+ where_clause = " WHERE " + " AND ".join(conditions)
|
|
|
+
|
|
|
+ # --- 第二部分:查询总数 (Total) ---
|
|
|
+ count_query = f"SELECT COUNT(*) as total FROM {settings.DB_CARD_TABLE_NAME}" + where_clause
|
|
|
+ cursor.execute(count_query, tuple(params))
|
|
|
+ total_count = cursor.fetchone()['total']
|
|
|
+
|
|
|
+ # --- 第三部分:查询当前页列表数据 (List) ---
|
|
|
+ data_query = f"SELECT * FROM {settings.DB_CARD_TABLE_NAME}" + where_clause
|
|
|
+
|
|
|
+ # 排序和分页
|
|
|
+ data_query += f" ORDER BY {sort_by.value} {sort_order.value}, id DESC"
|
|
|
+ data_query += " LIMIT %s OFFSET %s"
|
|
|
+
|
|
|
+ # 复制一份 params 用于数据查询,避免影响原来的列表
|
|
|
+ data_params = params.copy()
|
|
|
+ data_params.extend([limit, skip])
|
|
|
+
|
|
|
+ cursor.execute(data_query, tuple(data_params))
|
|
|
+ cards = cursor.fetchall()
|
|
|
+
|
|
|
+ # --- 第四部分:关联图片 (逻辑与之前一致) ---
|
|
|
+ if cards:
|
|
|
+ card_ids = [card['id'] for card in cards]
|
|
|
+ format_strings = ','.join(['%s'] * len(card_ids))
|
|
|
+ image_query = (
|
|
|
+ f"SELECT id, card_id, image_type, image_path, detection_image_path, modified_image_path "
|
|
|
+ f"FROM {settings.DB_IMAGE_TABLE_NAME} WHERE card_id IN ({format_strings})"
|
|
|
+ )
|
|
|
+ cursor.execute(image_query, tuple(card_ids))
|
|
|
+ images = cursor.fetchall()
|
|
|
+
|
|
|
+ images_by_card_id = {}
|
|
|
+ for image in images:
|
|
|
+ cid = image['card_id']
|
|
|
+ if cid not in images_by_card_id:
|
|
|
+ images_by_card_id[cid] = []
|
|
|
+ images_by_card_id[cid].append(image)
|
|
|
+
|
|
|
+ for card in cards:
|
|
|
+ card['image_path_list'] = {}
|
|
|
+ card['detection_image_path_list'] = {}
|
|
|
+ card['modified_image_path_list'] = {}
|
|
|
+ related_images = images_by_card_id.get(card['id'], [])
|
|
|
+ for image_data in related_images:
|
|
|
+ image_type = image_data['image_type']
|
|
|
+ if image_type:
|
|
|
+ card['image_path_list'][image_type] = image_data.get('image_path')
|
|
|
+ card['detection_image_path_list'][image_type] = image_data.get('detection_image_path')
|
|
|
+ card['modified_image_path_list'][image_type] = image_data.get('modified_image_path')
|
|
|
+
|
|
|
+ # 返回字典结构
|
|
|
+ return {
|
|
|
+ "total": total_count,
|
|
|
+ "list": cards
|
|
|
+ }
|