search.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import streamlit as st
  2. import pandas as pd
  3. import time
  4. from datetime import datetime, timedelta
  5. import random
  6. st.title("🔍 Search Tool")
  7. st.markdown("全局搜索工具")
  8. # 模拟搜索数据
  9. @st.cache_data
  10. def load_search_data():
  11. categories = ["用户", "订单", "产品", "日志", "文档"]
  12. data = []
  13. for i in range(200):
  14. data.append({
  15. 'id': f"ITEM-{3000 + i}",
  16. 'title': f"项目 {i+1}: {random.choice(['用户管理', '订单处理', '产品信息', '系统日志', '帮助文档'])}",
  17. 'category': random.choice(categories),
  18. 'content': f"这是项目 {i+1} 的详细内容描述,包含相关信息和数据...",
  19. 'created_date': datetime.now() - timedelta(days=random.randint(1, 365)),
  20. 'tags': random.sample(['重要', '紧急', '已完成', '进行中', '待审核'], k=random.randint(1, 3))
  21. })
  22. return pd.DataFrame(data)
  23. # 加载数据
  24. search_df = load_search_data()
  25. # 搜索界面
  26. st.subheader("🔍 搜索查询")
  27. # 搜索选项
  28. col1, col2 = st.columns([3, 1])
  29. with col1:
  30. search_query = st.text_input(
  31. "搜索内容",
  32. placeholder="输入关键词进行搜索...",
  33. help="支持标题、内容、标签搜索"
  34. )
  35. with col2:
  36. search_button = st.button("🔍 搜索", type="primary")
  37. # 高级搜索选项
  38. with st.expander("🔧 高级搜索选项"):
  39. col1, col2, col3 = st.columns(3)
  40. with col1:
  41. selected_categories = st.multiselect(
  42. "类别筛选",
  43. options=search_df['category'].unique(),
  44. default=search_df['category'].unique()
  45. )
  46. with col2:
  47. date_range = st.date_input(
  48. "时间范围",
  49. value=(datetime.now() - timedelta(days=30), datetime.now()),
  50. max_value=datetime.now()
  51. )
  52. with col3:
  53. available_tags = ['重要', '紧急', '已完成', '进行中', '待审核']
  54. selected_tags = st.multiselect(
  55. "标签筛选",
  56. options=available_tags
  57. )
  58. # 执行搜索
  59. if search_query or search_button:
  60. with st.spinner("搜索中..."):
  61. time.sleep(0.5) # 模拟搜索延迟
  62. # 过滤数据
  63. filtered_df = search_df[search_df['category'].isin(selected_categories)]
  64. # 时间范围筛选
  65. if len(date_range) == 2:
  66. start_date, end_date = date_range
  67. filtered_df = filtered_df[
  68. (filtered_df['created_date'].dt.date >= start_date) &
  69. (filtered_df['created_date'].dt.date <= end_date)
  70. ]
  71. # 标签筛选
  72. if selected_tags:
  73. filtered_df = filtered_df[
  74. filtered_df['tags'].apply(lambda x: any(tag in x for tag in selected_tags))
  75. ]
  76. # 关键词搜索
  77. if search_query:
  78. mask = (
  79. filtered_df['title'].str.contains(search_query, case=False, na=False) |
  80. filtered_df['content'].str.contains(search_query, case=False, na=False) |
  81. filtered_df['tags'].astype(str).str.contains(search_query, case=False, na=False)
  82. )
  83. filtered_df = filtered_df[mask]
  84. # 显示搜索结果
  85. st.subheader(f"📋 搜索结果 ({len(filtered_df)} 项)")
  86. if len(filtered_df) > 0:
  87. # 结果统计
  88. col1, col2, col3 = st.columns(3)
  89. with col1:
  90. st.metric("总结果数", len(filtered_df))
  91. with col2:
  92. category_counts = filtered_df['category'].value_counts()
  93. st.metric("主要类别", category_counts.index[0] if len(category_counts) > 0 else "无")
  94. with col3:
  95. recent_count = len(filtered_df[filtered_df['created_date'] >= datetime.now() - timedelta(days=7)])
  96. st.metric("最近7天", recent_count)
  97. # 排序选项
  98. sort_option = st.selectbox(
  99. "排序方式",
  100. ["相关性", "时间(最新)", "时间(最旧)", "标题(A-Z)"]
  101. )
  102. if sort_option == "时间(最新)":
  103. filtered_df = filtered_df.sort_values('created_date', ascending=False)
  104. elif sort_option == "时间(最旧)":
  105. filtered_df = filtered_df.sort_values('created_date', ascending=True)
  106. elif sort_option == "标题(A-Z)":
  107. filtered_df = filtered_df.sort_values('title')
  108. # 分页显示
  109. items_per_page = st.selectbox("每页显示", [10, 20, 50], index=1)
  110. total_pages = (len(filtered_df) - 1) // items_per_page + 1
  111. if total_pages > 1:
  112. page = st.selectbox("选择页面", range(1, total_pages + 1))
  113. start_idx = (page - 1) * items_per_page
  114. end_idx = start_idx + items_per_page
  115. display_df = filtered_df.iloc[start_idx:end_idx]
  116. else:
  117. display_df = filtered_df
  118. # 显示结果
  119. for idx, row in display_df.iterrows():
  120. with st.container():
  121. st.markdown(f"### {row['title']}")
  122. col1, col2 = st.columns([3, 1])
  123. with col1:
  124. st.write(f"**类别:** {row['category']}")
  125. st.write(f"**内容预览:** {row['content'][:100]}...")
  126. # 显示标签
  127. if row['tags']:
  128. tags_html = " ".join([f"<span style='background-color: #e0e0e0; padding: 2px 6px; border-radius: 10px; font-size: 12px;'>{tag}</span>" for tag in row['tags']])
  129. st.markdown(tags_html, unsafe_allow_html=True)
  130. with col2:
  131. st.write(f"**ID:** {row['id']}")
  132. st.write(f"**创建时间:** {row['created_date'].strftime('%Y-%m-%d')}")
  133. if st.button("查看详情", key=f"view_{row['id']}"):
  134. st.session_state[f"selected_item_{row['id']}"] = True
  135. # 详情展示
  136. if st.session_state.get(f"selected_item_{row['id']}", False):
  137. with st.expander(f"详情: {row['title']}", expanded=True):
  138. st.write(f"**完整内容:** {row['content']}")
  139. st.write(f"**所有标签:** {', '.join(row['tags'])}")
  140. if st.button("收起详情", key=f"hide_{row['id']}"):
  141. st.session_state[f"selected_item_{row['id']}"] = False
  142. st.rerun()
  143. st.divider()
  144. else:
  145. st.warning("没有找到匹配的结果,请尝试其他搜索条件。")
  146. # 搜索建议
  147. st.subheader("💡 搜索建议")
  148. st.markdown("""
  149. - 尝试使用更简单的关键词
  150. - 检查拼写是否正确
  151. - 尝试使用同义词
  152. - 扩大时间范围
  153. - 取消一些筛选条件
  154. """)
  155. else:
  156. # 显示搜索提示
  157. st.info("👆 在上方输入关键词开始搜索")
  158. # 热门搜索词
  159. st.subheader("🔥 热门搜索")
  160. popular_searches = ["用户管理", "订单处理", "系统日志", "产品信息", "帮助文档"]
  161. cols = st.columns(len(popular_searches))
  162. for i, term in enumerate(popular_searches):
  163. with cols[i]:
  164. if st.button(f"#{term}", key=f"popular_{i}"):
  165. st.session_state.search_query = term
  166. st.rerun()