Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
CHANGED
|
@@ -31,6 +31,8 @@ def inject_custom_css():
|
|
| 31 |
[data-testid="stSidebarContent"] { padding-top: 1.5rem !important; }
|
| 32 |
[data-testid="stVerticalBlock"] > div { gap: 0.8rem !important; }
|
| 33 |
[data-testid="stSelectbox"] input { caret-color: transparent !important; }
|
|
|
|
|
|
|
| 34 |
[data-testid="stFileUploader"] section > div { display: none; }
|
| 35 |
[data-testid="stFileUploaderDropzoneInstructions"] { display: none !important; }
|
| 36 |
[data-testid="stFileUploader"] section::before {
|
|
@@ -54,7 +56,7 @@ def inject_custom_css():
|
|
| 54 |
}
|
| 55 |
/* 左上角侧边栏按钮:替换箭头为「☰ 菜单」 */
|
| 56 |
[data-testid="stSidebarCollapsedControl"] {
|
| 57 |
-
top: 0.
|
| 58 |
left: 0.5rem !important;
|
| 59 |
}
|
| 60 |
[data-testid="stSidebarCollapsedControl"] button {
|
|
@@ -87,7 +89,7 @@ def inject_custom_css():
|
|
| 87 |
/* 右上角三点菜单:替换为「⚙ 设置」按钮风格 */
|
| 88 |
[data-testid="stMainMenu"] {
|
| 89 |
position: fixed !important;
|
| 90 |
-
top: 0.
|
| 91 |
right: 0.5rem !important;
|
| 92 |
}
|
| 93 |
[data-testid="stMainMenu"] button {
|
|
@@ -294,9 +296,12 @@ if "current_role" not in st.session_state:
|
|
| 294 |
if "auth_mode" not in st.session_state:
|
| 295 |
st.session_state.auth_mode = "login"
|
| 296 |
|
|
|
|
|
|
|
| 297 |
with st.sidebar:
|
| 298 |
-
|
| 299 |
-
|
|
|
|
| 300 |
if st.session_state.login_attempts >= MAX_LOGIN_ATTEMPTS:
|
| 301 |
st.error("🚫 尝试次数过多,请刷新页面后重试。")
|
| 302 |
st.stop()
|
|
@@ -318,28 +323,22 @@ with st.sidebar:
|
|
| 318 |
if st.button("🔓 登录", use_container_width=True, type="primary", key="btn_login"):
|
| 319 |
if input_username == "" or input_password == "":
|
| 320 |
st.warning("请输入用户名和密码")
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
ok, role, reason = verify_user(input_username, input_password)
|
| 324 |
-
if not ok:
|
| 325 |
-
st.session_state.login_attempts += 1
|
| 326 |
-
remaining = MAX_LOGIN_ATTEMPTS - st.session_state.login_attempts
|
| 327 |
-
if reason == "not_found":
|
| 328 |
-
st.warning(f"⚠️ 用户不存在,请先注册(剩余 {remaining} 次)")
|
| 329 |
-
else:
|
| 330 |
-
st.warning(f"⚠️ 密码错误(剩余 {remaining} 次)")
|
| 331 |
-
st.stop()
|
| 332 |
else:
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
|
|
|
|
|
|
|
|
|
| 343 |
|
| 344 |
else: # 注册
|
| 345 |
reg_user = st.text_input("用户名", key="reg_user")
|
|
@@ -356,21 +355,30 @@ with st.sidebar:
|
|
| 356 |
st.session_state.current_user = reg_user
|
| 357 |
st.session_state.current_role = "user"
|
| 358 |
st.session_state.login_attempts = 0
|
| 359 |
-
st.success(f"✅ 注册成功,已自动登录")
|
| 360 |
st.rerun()
|
| 361 |
else:
|
| 362 |
st.error(f"❌ {msg}")
|
| 363 |
-
st.stop()
|
| 364 |
-
|
| 365 |
-
CURRENT_USER = st.session_state.current_user
|
| 366 |
-
IS_ADMIN = st.session_state.current_role == "admin"
|
| 367 |
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 371 |
|
| 372 |
# 登录后自动收起侧边栏(通过 JS 模拟点击收起按钮)
|
| 373 |
-
if not st.session_state.get("_sidebar_collapsed_once"):
|
| 374 |
st.session_state["_sidebar_collapsed_once"] = True
|
| 375 |
import streamlit.components.v1 as components
|
| 376 |
components.html(
|
|
@@ -891,6 +899,13 @@ model_mapping = {
|
|
| 891 |
"🏢 百度文心 (官方)": "ernie-3.5-8k",
|
| 892 |
}
|
| 893 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 894 |
|
| 895 |
with st.sidebar:
|
| 896 |
st.caption("👇 展开下方面板管理知识库和设置")
|
|
|
|
| 31 |
[data-testid="stSidebarContent"] { padding-top: 1.5rem !important; }
|
| 32 |
[data-testid="stVerticalBlock"] > div { gap: 0.8rem !important; }
|
| 33 |
[data-testid="stSelectbox"] input { caret-color: transparent !important; }
|
| 34 |
+
/* 隐藏 text_input 的 press enter to apply 提示 */
|
| 35 |
+
[data-testid="stTextInput"] div[data-testid="InputInstructions"] { display: none !important; }
|
| 36 |
[data-testid="stFileUploader"] section > div { display: none; }
|
| 37 |
[data-testid="stFileUploaderDropzoneInstructions"] { display: none !important; }
|
| 38 |
[data-testid="stFileUploader"] section::before {
|
|
|
|
| 56 |
}
|
| 57 |
/* 左上角侧边栏按钮:替换箭头为「☰ 菜单」 */
|
| 58 |
[data-testid="stSidebarCollapsedControl"] {
|
| 59 |
+
top: 0.4rem !important;
|
| 60 |
left: 0.5rem !important;
|
| 61 |
}
|
| 62 |
[data-testid="stSidebarCollapsedControl"] button {
|
|
|
|
| 89 |
/* 右上角三点菜单:替换为「⚙ 设置」按钮风格 */
|
| 90 |
[data-testid="stMainMenu"] {
|
| 91 |
position: fixed !important;
|
| 92 |
+
top: 0.4rem !important;
|
| 93 |
right: 0.5rem !important;
|
| 94 |
}
|
| 95 |
[data-testid="stMainMenu"] button {
|
|
|
|
| 296 |
if "auth_mode" not in st.session_state:
|
| 297 |
st.session_state.auth_mode = "login"
|
| 298 |
|
| 299 |
+
IS_GUEST = not bool(st.session_state.get("current_user"))
|
| 300 |
+
|
| 301 |
with st.sidebar:
|
| 302 |
+
# 未登录时不用 expander,直接显示登录表单(避免手动收起后无法自动展开)
|
| 303 |
+
if IS_GUEST:
|
| 304 |
+
st.subheader("🔑 账号")
|
| 305 |
if st.session_state.login_attempts >= MAX_LOGIN_ATTEMPTS:
|
| 306 |
st.error("🚫 尝试次数过多,请刷新页面后重试。")
|
| 307 |
st.stop()
|
|
|
|
| 323 |
if st.button("🔓 登录", use_container_width=True, type="primary", key="btn_login"):
|
| 324 |
if input_username == "" or input_password == "":
|
| 325 |
st.warning("请输入用户名和密码")
|
| 326 |
+
elif st.session_state.login_attempts >= MAX_LOGIN_ATTEMPTS:
|
| 327 |
+
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
else:
|
| 329 |
+
ok, role, reason = verify_user(input_username, input_password)
|
| 330 |
+
if not ok:
|
| 331 |
+
st.session_state.login_attempts += 1
|
| 332 |
+
remaining = MAX_LOGIN_ATTEMPTS - st.session_state.login_attempts
|
| 333 |
+
if reason == "not_found":
|
| 334 |
+
st.warning(f"⚠️ 用户不存在,请先注册(剩余 {remaining} 次)")
|
| 335 |
+
else:
|
| 336 |
+
st.warning(f"⚠️ 密码错误(剩余 {remaining} 次)")
|
| 337 |
+
else:
|
| 338 |
+
st.session_state.login_attempts = 0
|
| 339 |
+
st.session_state.current_user = input_username
|
| 340 |
+
st.session_state.current_role = role
|
| 341 |
+
st.rerun()
|
| 342 |
|
| 343 |
else: # 注册
|
| 344 |
reg_user = st.text_input("用户名", key="reg_user")
|
|
|
|
| 355 |
st.session_state.current_user = reg_user
|
| 356 |
st.session_state.current_role = "user"
|
| 357 |
st.session_state.login_attempts = 0
|
|
|
|
| 358 |
st.rerun()
|
| 359 |
else:
|
| 360 |
st.error(f"❌ {msg}")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
|
| 362 |
+
st.divider()
|
| 363 |
+
st.caption("💡 未登录可直接提问(游客模式),登录后解锁全部功能")
|
| 364 |
+
else:
|
| 365 |
+
with st.expander("🔑 账号"):
|
| 366 |
+
role_label = "管理员" if st.session_state.current_role == "admin" else "普通用户"
|
| 367 |
+
st.success(f"✅ {st.session_state.current_user}({role_label})")
|
| 368 |
+
|
| 369 |
+
# 设置全局用户标识
|
| 370 |
+
if st.session_state.get("current_user"):
|
| 371 |
+
CURRENT_USER = st.session_state.current_user
|
| 372 |
+
IS_ADMIN = st.session_state.current_role == "admin"
|
| 373 |
+
IS_GUEST = False
|
| 374 |
+
_welcome_hero.empty() # 登录成功,清除欢迎页
|
| 375 |
+
else:
|
| 376 |
+
CURRENT_USER = "_guest_"
|
| 377 |
+
IS_ADMIN = False
|
| 378 |
+
IS_GUEST = True
|
| 379 |
|
| 380 |
# 登录后自动收起侧边栏(通过 JS 模拟点击收起按钮)
|
| 381 |
+
if not IS_GUEST and not st.session_state.get("_sidebar_collapsed_once"):
|
| 382 |
st.session_state["_sidebar_collapsed_once"] = True
|
| 383 |
import streamlit.components.v1 as components
|
| 384 |
components.html(
|
|
|
|
| 899 |
"🏢 百度文心 (官方)": "ernie-3.5-8k",
|
| 900 |
}
|
| 901 |
|
| 902 |
+
# 游客模式:屏蔽收费模型
|
| 903 |
+
_GUEST_BLOCKED_MODELS = {"🛡️ DeepSeek (官方)", "🏢 百度文心 (官方)"}
|
| 904 |
+
if IS_GUEST:
|
| 905 |
+
_active_models = {k: v for k, v in model_mapping.items() if k not in _GUEST_BLOCKED_MODELS}
|
| 906 |
+
else:
|
| 907 |
+
_active_models = model_mapping
|
| 908 |
+
|
| 909 |
|
| 910 |
with st.sidebar:
|
| 911 |
st.caption("👇 展开下方面板管理知识库和设置")
|