{"repo": "666woshinibab/aichat", "files": {"main.py": {"6f734b16dfccab1f2bfc951cdee936eb8cd385b5": {"t": 1785747501.0163882, "n": 69235, "h": "21772a7c59fcc713", "c": "import wave\r\nimport pandas as pd\r\nimport matplotlib.pyplot as plt\r\nimport uuid\r\nimport pickle\r\nimport json\r\nimport warnings\r\nimport sqlite3\r\nimport requests\r\nfrom PIL import Image\r\nimport base64\r\nfrom gtts import gTTS\r\nimport datetime\r\nimport pyaudio\r\nimport mysql.connector\r\nimport re\r\nimport wikipedia\r\nimport pytz\r\nfrom langchain.chains import ConversationalRetrievalChain, ConversationChain\r\nfrom langchain.chains.flare.prompts import PROMPT_TEMPLATE\r\nfrom langchain.memory import ConversationBufferMemory\r\nfrom langchain_community.chat_models import ChatOpenAI\r\nfrom langchain_community.document_loaders import TextLoader, PyPDFLoader, Docx2txtLoader\r\nfrom langchain_community.vectorstores import FAISS\r\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\r\nfrom langchain_experimental.agents import create_pandas_dataframe_agent\r\nfrom langchain_openai import ChatOpenAI\r\nfrom langchain.tools import Tool\r\nfrom langchain.agents import AgentType\r\nfrom langchain_experimental.utilities import PythonREPL\r\nfrom user_db import UserDB\r\nimport os\r\nimport speech_recognition as sr\r\nimport streamlit as st\r\nfrom io import BytesIO\r\n\r\nPROMPT_TEMPLATE = \"\"\"你是一位数据分析助手,你的回应内容取决于用户的请求内容,请按照下面的步骤处理用户请求:\r\n\r\n1. 思考阶段 (Thought) :先分析用户请求类型(文字回答/表格/图表),并验证数据类型是否匹配。\r\n2. 行动阶段 (Action) :根据分析结果选择以下严格对应的格式。\r\n - 纯文字回答: \r\n {\"answer\": \"不超过50个字符的明确答案\"}\r\n\r\n - 表格数据: \r\n {\"table\":{\"columns\":[\"列名1\", \"列名2\", ...], \"data\":[[\"第一行值1\", \"值2\", ...], [\"第二行值1\", \"值2\", ...]]}}\r\n\r\n - 柱状图 \r\n {\"bar\":{\"columns\": [\"A\", \"B\", \"C\", ...], \"data\":[35, 42, 29, ...]}}\r\n\r\n - 折线图 \r\n {\"line\":{\"columns\": [\"A\", \"B\", \"C\", ...], \"data\": [35, 42, 29, ...]}}\r\n\r\n3. 格式校验要求\r\n - 字符串值必须使用英文双引号\r\n - 数值类型不得添加引号\r\n - 确保数组闭合无遗漏\r\n\r\n 错误案例:{'columns':['Product', 'Sales'], data:[[A001, 200]]} \r\n 正确案例:{\"columns\":[\"product\", \"sales\"], \"data\":[[\"A001\", 200]]}\r\n\r\n注意:响应数据的\"output\"中不要有换行符、制表符以及其他格式符号。\r\n\r\n当前用户请求:\"\"\"\r\n\r\n\r\n# 从test1导入dataframe_agent函数\r\ndef dataframe_agent(df, query):\r\n try:\r\n # 确保 DataFrame 不是空的\r\n if df.empty:\r\n return {\"answer\": \"错误:数据集为空,无法进行分析\"}\r\n\r\n # 创建模型\r\n model = ChatOpenAI(\r\n model=\"deepseek-chat\",\r\n base_url='https://api.deepseek.com',\r\n api_key='sk-62d08d23019c4d74bdfb1495abe8f489',\r\n temperature=0,\r\n max_tokens=2048\r\n )\r\n\r\n # 创建代理\r\n agent = create_pandas_dataframe_agent(\r\n llm=model,\r\n df=df,\r\n agent_type=AgentType.OPENAI_FUNCTIONS, # 使用更可靠的代理类型\r\n agent_executor_kwargs={\"handle_parsing_errors\": True},\r\n max_iterations=8, # 减少迭代次数防止超时\r\n early_stopping_method='generate',\r\n allow_dangerous_code=True,\r\n verbose=True\r\n )\r\n\r\n # 使用正确的提示模板\r\n prompt = PROMPT_TEMPLATE + query\r\n\r\n # 调用代理\r\n response = agent.invoke({\"input\": prompt})\r\n return json.loads(response[\"output\"])\r\n\r\n # 处理响应\r\n try:\r\n output = response[\"output\"]\r\n # 尝试解析 JSON\r\n try:\r\n return json.loads(output)\r\n except json.JSONDecodeError:\r\n # 尝试提取可能的 JSON 部分\r\n start_idx = output.find('{')\r\n end_idx = output.rfind('}') + 1\r\n if start_idx != -1 and end_idx != 0:\r\n json_str = output[start_idx:end_idx]\r\n return json.loads(json_str)\r\n else:\r\n # 返回原始文本\r\n return {\"answer\": output}\r\n except KeyError:\r\n return {\"answer\": \"未获取到有效的分析结果\"}\r\n\r\n except Exception as e:\r\n # 返回详细错误信息\r\n return {\"answer\": f\"分析过程中发生错误: {str(e)}\"}\r\n\r\n\r\n\r\nwarnings.filterwarnings('ignore')\r\n\r\n# 页面设置\r\nst.set_page_config(\r\n page_title=\"六棵松互联智能分析平台\",\r\n layout=\"wide\",\r\n page_icon=\"🤖\",\r\n initial_sidebar_state=\"expanded\"\r\n)\r\n\r\n# 自定义CSS样式\r\n# 固定浅色主题 CSS\r\nst.markdown(\"\"\"\r\n\r\n\"\"\", unsafe_allow_html=True)\r\n\r\n\r\n\r\n\r\ndef get_chat_response(llm, memory, user_prompt):\r\n \"\"\"用于构建带有对话记忆功能的聊天应用\"\"\"\r\n chain = ConversationChain(llm=llm, memory=memory)\r\n return chain.invoke({'input': user_prompt})['response']\r\n\r\n\r\ndef generate_summary(text, max_length=300):\r\n \"\"\"生成文本摘要\"\"\"\r\n model = ChatOpenAI(\r\n # model='gpt-3.5-turbo',\r\n # base_url='https://twapi.openai-hk.com/v1',\r\n # api_key='hk-3n6lv81000055630609b77f801914238092bf036f0495aa1',\r\n # temperature=0\r\n model=\"deepseek-chat\",\r\n base_url='https://api.deepseek.com',\r\n api_key='sk-62d08d23019c4d74bdfb1495abe8f489',\r\n temperature=0\r\n )\r\n prompt = f\"请为以下文本生成一个简洁的摘要(不超过{max_length}字):\\n\\n{text}\"\r\n return model.invoke(prompt).content\r\n\r\n\r\ndef get_answer(thy_question, session_state):\r\n model = ChatOpenAI(\r\n model='gpt-3.5-turbo',\r\n base_url='https://twapi.openai-hk.com/v1',\r\n api_key='hk-yq4ipo100005562375c7c3ac31e70baadb11e09f2040908b',\r\n temperature=0\r\n )\r\n if session_state['is_new_file']:\r\n loader = TextLoader(f'{session_state[\"session_id\"]}.txt', encoding='utf-8')\r\n docs = loader.load()\r\n text_splitter = RecursiveCharacterTextSplitter(\r\n chunk_size=1000,\r\n chunk_overlap=50,\r\n separators=[\"\\n\", \"。\", \"!\", \"?\", \",\", \"、\", \"\"]\r\n )\r\n texts = text_splitter.split_documents(docs)\r\n db = FAISS.from_documents(texts, session_state['em_model'])\r\n session_state['db'] = db\r\n session_state['is_new_file'] = False\r\n if 'db' in session_state:\r\n retriever = session_state['db'].as_retriever()\r\n chain = ConversationalRetrievalChain.from_llm(\r\n llm=model,\r\n retriever=retriever,\r\n memory=session_state['memory']\r\n )\r\n resp = chain.invoke({'chat_history': session_state['memory'], 'question': thy_question})\r\n return resp\r\n return ''\r\n\r\n\r\ndef preprocess_data(df):\r\n \"\"\"数据预处理函数\"\"\"\r\n with st.expander(\"🔧 数据预处理\", expanded=False):\r\n # 创建两列布局\r\n col1, col2 = st.columns(2)\r\n\r\n with col1:\r\n # 处理缺失值\r\n st.markdown(\"### 缺失值处理\")\r\n missing_action = st.selectbox(\r\n \"选择缺失值处理方式\",\r\n [\"不处理\", \"删除包含缺失值的行\", \"填充缺失值\"],\r\n key=\"missing_action\"\r\n )\r\n\r\n if missing_action == \"填充缺失值\":\r\n fill_method = st.selectbox(\r\n \"选择填充方法\",\r\n [\"用平均值填充\", \"用中位数填充\", \"用众数填充\", \"用指定值填充\"],\r\n key=\"fill_method\"\r\n )\r\n if fill_method == \"用指定值填充\":\r\n fill_value = st.text_input(\"输入填充值\", key=\"fill_value\")\r\n\r\n with col2:\r\n # 数据类型转换\r\n st.markdown(\"### 数据类型转换\")\r\n if st.checkbox(\"转换数据类型\", key=\"convert_dtypes\"):\r\n column_to_convert = st.selectbox(\r\n \"选择要转换的列\",\r\n df.columns,\r\n key=\"column_to_convert\"\r\n )\r\n new_type = st.selectbox(\r\n \"选择新类型\",\r\n [\"int\", \"float\", \"str\", \"datetime\"],\r\n key=\"new_type\"\r\n )\r\n\r\n # 数据过滤\r\n st.markdown(\"### 数据过滤\")\r\n if st.checkbox(\"应用数据过滤\", key=\"apply_filter\"):\r\n filter_column = st.selectbox(\r\n \"选择过滤列\",\r\n df.columns,\r\n key=\"filter_column\"\r\n )\r\n if pd.api.types.is_numeric_dtype(df[filter_column]):\r\n min_val, max_val = st.slider(\r\n \"选择数值范围\",\r\n float(df[filter_column].min()),\r\n float(df[filter_column].max()),\r\n (float(df[filter_column].min()), float(df[filter_column].max())),\r\n key=\"numeric_filter\"\r\n )\r\n else:\r\n unique_values = df[filter_column].unique()\r\n selected_values = st.multiselect(\r\n \"选择要保留的值\",\r\n unique_values,\r\n default=list(unique_values),\r\n key=\"categorical_filter\"\r\n )\r\n\r\n # 执行预处理按钮\r\n if st.button(\"🚀 应用预处理\", key=\"apply_preprocessing\", use_container_width=True):\r\n processed_df = df.copy()\r\n\r\n # 处理缺失值\r\n if missing_action == \"删除包含缺失值的行\":\r\n processed_df = processed_df.dropna()\r\n st.success(f\"已删除包含缺失值的行,剩余 {len(processed_df)} 行数据\")\r\n elif missing_action == \"填充缺失值\":\r\n if fill_method == \"用平均值填充\":\r\n processed_df = processed_df.fillna(processed_df.mean(numeric_only=True))\r\n elif fill_method == \"用中位数填充\":\r\n processed_df = processed_df.fillna(processed_df.median(numeric_only=True))\r\n elif fill_method == \"用众数填充\":\r\n for col in processed_df.columns:\r\n processed_df[col] = processed_df[col].fillna(processed_df[col].mode()[0])\r\n elif fill_method == \"用指定值填充\" and fill_value:\r\n try:\r\n # 尝试转换为数值类型\r\n try:\r\n fill_val = float(fill_value)\r\n except ValueError:\r\n fill_val = fill_value\r\n processed_df = processed_df.fillna(fill_val)\r\n except Exception as e:\r\n st.error(f\"填充过程中出错: {str(e)}\")\r\n\r\n # 数据类型转换\r\n if st.session_state.get(\"convert_dtypes\"):\r\n try:\r\n if new_type == \"int\":\r\n processed_df[column_to_convert] = processed_df[column_to_convert].astype(int)\r\n elif new_type == \"float\":\r\n processed_df[column_to_convert] = processed_df[column_to_convert].astype(float)\r\n elif new_type == \"str\":\r\n processed_df[column_to_convert] = processed_df[column_to_convert].astype(str)\r\n elif new_type == \"datetime\":\r\n processed_df[column_to_convert] = pd.to_datetime(processed_df[column_to_convert])\r\n st.success(f\"已将列 '{column_to_convert}' 转换为 {new_type} 类型\")\r\n except Exception as e:\r\n st.error(f\"类型转换失败: {str(e)}\")\r\n\r\n # 数据过滤\r\n if st.session_state.get(\"apply_filter\"):\r\n if pd.api.types.is_numeric_dtype(processed_df[filter_column]):\r\n processed_df = processed_df[\r\n (processed_df[filter_column] >= min_val) &\r\n (processed_df[filter_column] <= max_val)\r\n ]\r\n st.success(f\"已过滤 '{filter_column}' 列,保留范围: {min_val} 到 {max_val}\")\r\n else:\r\n processed_df = processed_df[processed_df[filter_column].isin(selected_values)]\r\n st.success(f\"已过滤 '{filter_column}' 列,保留选定的类别\")\r\n\r\n # 显示处理后的数据\r\n st.subheader(\"🔄 预处理后的数据\")\r\n st.dataframe(processed_df)\r\n\r\n return processed_df\r\n\r\n return df\r\n\r\n\r\ndef render_chart(chart_type, data):\r\n \"\"\"渲染不同类型的图表\"\"\"\r\n try:\r\n if chart_type == \"bar\":\r\n df = pd.DataFrame({\r\n \"x\": data[\"columns\"],\r\n \"y\": data[\"data\"]\r\n }).set_index(\"x\")\r\n st.bar_chart(df)\r\n\r\n elif chart_type == \"line\":\r\n df = pd.DataFrame({\r\n \"x\": data[\"columns\"],\r\n \"y\": data[\"data\"]\r\n }).set_index(\"x\")\r\n st.line_chart(df)\r\n\r\n elif chart_type == \"pie\":\r\n fig, ax = plt.subplots()\r\n ax.pie(data[\"data\"], labels=data[\"columns\"], autopct='%1.1f%%', startangle=90)\r\n ax.axis('equal')\r\n st.pyplot(fig)\r\n\r\n elif chart_type == \"scatter\":\r\n if len(data[\"columns\"]) >= 2:\r\n df = pd.DataFrame({\r\n \"x\": data[\"data\"][0],\r\n \"y\": data[\"data\"][1]\r\n })\r\n if len(data[\"columns\"]) >= 3:\r\n df[\"size\"] = data[\"data\"][2]\r\n st.scatter_chart(df, x=\"x\", y=\"y\", size=\"size\")\r\n else:\r\n st.scatter_chart(df, x=\"x\", y=\"y\")\r\n else:\r\n st.warning(\"散点图需要至少两个维度的数据\")\r\n\r\n elif chart_type == \"heatmap\":\r\n try:\r\n import seaborn as sns\r\n df = pd.DataFrame(data[\"data\"], columns=data[\"columns\"])\r\n plt.figure(figsize=(10, 8))\r\n sns.heatmap(df.corr(), annot=True, cmap='coolwarm', fmt=\".2f\")\r\n st.pyplot(plt.gcf())\r\n except ImportError:\r\n st.warning(\"渲染热力图需要seaborn库,请先安装\")\r\n\r\n except Exception as e:\r\n st.error(f\"渲染图表时出错: {str(e)}\")\r\n\r\n\r\ndef text_to_speech(text, lang='zh'):\r\n \"\"\"将文本转换为语音\"\"\"\r\n tts = gTTS(text=text, lang=lang, slow=False)\r\n audio_bytes = BytesIO()\r\n tts.write_to_fp(audio_bytes)\r\n audio_bytes.seek(0)\r\n return audio_bytes\r\n\r\n\r\ndef setup_plugins():\r\n \"\"\"设置插件系统(移除Google搜索,添加替代功能)\"\"\"\r\n plugins = []\r\n\r\n # 1. 维基百科搜索插件\r\n def wikipedia_search(query, lang='zh'):\r\n try:\r\n wikipedia.set_lang(lang)\r\n result = wikipedia.summary(query, sentences=2)\r\n return result\r\n except:\r\n return f\"未找到关于'{query}'的信息\"\r\n\r\n wikipedia_tool = Tool(\r\n name=\"维基百科搜索\",\r\n func=lambda query: wikipedia_search(query),\r\n description=\"使用维基百科获取知识信息\"\r\n )\r\n plugins.append(wikipedia_tool)\r\n\r\n # 2. 计算器插件\r\n def calculator(expression):\r\n try:\r\n # 安全计算数学表达式\r\n allowed_chars = \"0123456789+-*/(). \"\r\n if all(c in allowed_chars for c in expression):\r\n return str(eval(expression))\r\n else:\r\n return \"表达式包含不安全字符\"\r\n except Exception as e:\r\n return f\"计算错误: {str(e)}\"\r\n\r\n calc_tool = Tool(\r\n name=\"计算器\",\r\n func=calculator,\r\n description=\"计算数学表达式\"\r\n )\r\n plugins.append(calc_tool)\r\n\r\n # 3. 时间日期插件\r\n def get_datetime(timezone='Asia/Shanghai'):\r\n try:\r\n tz = pytz.timezone(timezone)\r\n now = datetime.datetime.now(tz)\r\n return now.strftime(\"%Y-%m-%d %H:%M:%S %Z\")\r\n except:\r\n return \"无法获取时间信息\"\r\n\r\n datetime_tool = Tool(\r\n name=\"时间日期\",\r\n func=get_datetime,\r\n description=\"获取当前时间和日期\"\r\n )\r\n plugins.append(datetime_tool)\r\n\r\n # 4. 单位转换插件\r\n def unit_converter(query):\r\n try:\r\n # 简单的单位转换实现\r\n conversions = {\r\n '公里': 1000,\r\n '千克': 1000,\r\n '小时': 3600\r\n }\r\n\r\n # 匹配类似 \"10公里 to 米\" 的格式\r\n pattern = r'(\\d+\\.?\\d*)\\s*(\\S+)\\s+to\\s+(\\S+)'\r\n match = re.match(pattern, query)\r\n if match:\r\n value = float(match.group(1))\r\n from_unit = match.group(2)\r\n to_unit = match.group(3)\r\n\r\n # 简单转换逻辑\r\n if from_unit == '公里' and to_unit == '米':\r\n return f\"{value} 公里 = {value * 1000} 米\"\r\n elif from_unit == '米' and to_unit == '公里':\r\n return f\"{value} 米 = {value / 1000} 公里\"\r\n elif from_unit == '千克' and to_unit == '克':\r\n return f\"{value} 千克 = {value * 1000} 克\"\r\n elif from_unit == '克' and to_unit == '千克':\r\n return f\"{value} 克 = {value / 1000} 千克\"\r\n elif from_unit == '小时' and to_unit == '分钟':\r\n return f\"{value} 小时 = {value * 60} 分钟\"\r\n elif from_unit == '分钟' and to_unit == '小时':\r\n return f\"{value} 分钟 = {value / 60:.2f} 小时\"\r\n\r\n return \"无法转换该单位,支持的转换:公里↔米,千克↔克,小时↔分钟\"\r\n except Exception as e:\r\n return f\"单位转换错误: {str(e)}\"\r\n\r\n unit_tool = Tool(\r\n name=\"单位转换\",\r\n func=unit_converter,\r\n description=\"转换不同单位(公里/米,千克/克,小时/分钟)\"\r\n )\r\n plugins.append(unit_tool)\r\n\r\n # 5. 文本翻译插件\r\n def translate_text(text, target_lang='en'):\r\n model = ChatOpenAI(\r\n model='gpt-3.5-turbo',\r\n base_url='https://twapi.openai-hk.com/v1',\r\n api_key='hk-yq4ipo100005562375c7c3ac31e70baadb11e09f2040908b',\r\n temperature=0\r\n )\r\n prompt = f\"将以下文本翻译为{target_lang}:\\n\\n{text}\"\r\n return model.invoke(prompt).content\r\n\r\n translate_tool = Tool(\r\n name=\"文本翻译\",\r\n func=lambda text: translate_text(text),\r\n description=\"将文本翻译为其他语言\"\r\n )\r\n plugins.append(translate_tool)\r\n\r\n # 6. 代码执行插件\r\n python_repl = PythonREPL()\r\n repl_tool = Tool(\r\n name=\"Python REPL\",\r\n func=python_repl.run,\r\n description=\"执行Python代码并返回结果\"\r\n )\r\n plugins.append(repl_tool)\r\n\r\n return plugins\r\n\r\n# 初始化用户数据库\r\n\r\nif 'user_db' not in st.session_state:\r\n st.session_state.user_db = UserDB(db_path='ai_platform_users.db')\r\n\r\n # 初始化聊天应用的记忆和消息\r\n if 'chat_messages' not in st.session_state:\r\n st.session_state['chat_messages'] = [{'role': 'ai', 'content': '你好主人,我是你的AI助手,我叫小美', 'avatar': '🤖'}]\r\n st.session_state['chat_memory'] = ConversationBufferMemory(return_messages=True)\r\n\r\n # 初始化插件\r\n if 'plugins' not in st.session_state:\r\n st.session_state['plugins'] = setup_plugins()\r\n\r\n # 初始化当前用户\r\n if 'current_user' not in st.session_state:\r\n st.session_state['current_user'] = None\r\n\r\n\r\n\r\n\r\n# 用户认证函数\r\n\r\ndef authenticate(username, password):\r\n \"\"\"用户认证\"\"\"\r\n try:\r\n success, result = st.session_state.user_db.authenticate(username, password)\r\n if success:\r\n st.session_state['current_user'] = username\r\n return success, result\r\n except Exception as e:\r\n # 如果数据库连接失败,提供备用方案\r\n st.error(f\"数据库连接失败: {str(e)}\")\r\n return False, \"系统暂时无法访问用户数据库,请稍后再试\"\r\n\r\n\r\n\r\n\r\n\r\n# 在页面设置之后,初始化 session_state 之前添加注册和登录函数\r\ndef register_user(username, password, confirm_password):\r\n \"\"\"注册新用户\"\"\"\r\n\r\n if password != confirm_password:\r\n return False, \"两次输入的密码不一致\"\r\n success, message = st.session_state.user_db.register_user(username, password,confirm_password)\r\n\r\n # 添加调试代码\r\n if success:\r\n print(f\"注册成功,检查数据库内容...\")\r\n try:\r\n with sqlite3.connect('users.db') as conn:\r\n cursor = conn.cursor()\r\n cursor.execute(\"SELECT * FROM users\")\r\n rows = cursor.fetchall()\r\n print(f\"当前用户表内容: {rows}\")\r\n except Exception as e:\r\n print(f\"检查数据库内容失败: {str(e)}\")\r\n\r\n return success, message\r\n\r\n\r\n\r\n\r\n# 修改后的初始化 session_state\r\nif 'session_id' not in st.session_state:\r\n st.session_state['memory'] = ConversationBufferMemory(\r\n return_messages=True,\r\n memory_key='chat_history',\r\n output_key='answer'\r\n )\r\n st.session_state['session_id'] = uuid.uuid4().hex\r\n st.session_state['is_new_file'] = False\r\n try:\r\n with open('D:\\AppGallery\\Downloads\\DANSANXIASHIXUN\\DAY07\\em.pkl', 'rb') as file_obj:\r\n em_model = pickle.load(file_obj)\r\n st.session_state['em_model'] = em_model\r\n except:\r\n st.session_state['em_model'] = None\r\n st.warning(\"未找到嵌入模型文件,部分功能可能受限\")\r\n\r\n # 初始化聊天应用的记忆和消息\r\n if 'chat_messages' not in st.session_state:\r\n st.session_state['chat_messages'] = [{'role': 'ai', 'content': '你好主人,我是你的AI助手,我叫小美', 'avatar': '🤖'}]\r\n st.session_state['chat_memory'] = ConversationBufferMemory(return_messages=True)\r\n\r\n # 初始化插件\r\n if 'plugins' not in st.session_state:\r\n st.session_state['plugins'] = setup_plugins()\r\n\r\n # 初始化用户系统 - 不再有默认用户\r\n if 'users' not in st.session_state:\r\n st.session_state['users'] = {}\r\n st.session_state['current_user'] = None\r\n\r\n\r\n\r\n# 侧边栏导航\r\nwith st.sidebar:\r\n\r\n st.title(\"📊 导航菜单\")\r\n\r\n # 用户登录/注册\r\n if st.session_state.get('current_user') is None:\r\n # 添加注册/登录选项卡\r\n tab1, tab2 = st.tabs([\"登录\", \"注册\"])\r\n\r\n with tab1:\r\n st.title(\"🔒 用户登录\")\r\n username = st.text_input(\"用户名\", key=\"login_username\")\r\n password = st.text_input(\"密码\", type=\"password\", key=\"login_password\")\r\n if st.button(\"登录\"):\r\n if username and password: # 确保用户名和密码不为空\r\n success, message = authenticate(username, password)\r\n if success:\r\n st.success(message)\r\n st.rerun()\r\n else:\r\n st.error(message) # 显示登录失败的具体原因\r\n else:\r\n st.error(\"用户名和密码不能为空\")\r\n\r\n with tab2:\r\n st.title(\"📝 用户注册\")\r\n new_username = st.text_input(\"新用户名\", key=\"reg_username\")\r\n new_password = st.text_input(\"新密码\", type=\"password\", key=\"reg_password\")\r\n confirm_password = st.text_input(\"确认密码\", type=\"password\", key=\"confirm_password\")\r\n\r\n if st.button(\"注册\"):\r\n if not new_username or not new_password:\r\n st.error(\"用户名和密码不能为空\")\r\n else:\r\n success, message = register_user(new_username, new_password, confirm_password)\r\n if success:\r\n st.success(message)\r\n else:\r\n st.error(message)\r\n\r\n st.title(\"🌟 六棵松互联智能分析平台\")\r\n st.warning(\"请先登录或注册以使用平台功能\")\r\n st.stop() # 阻止后续页面内容渲染\r\n\r\n else:\r\n st.subheader(f\"👤 当前用户: {st.session_state['current_user']}\")\r\n if st.button(\"退出登录\"):\r\n st.session_state['current_user'] = None\r\n st.rerun()\r\n\r\n st.divider()\r\n page = st.radio(\r\n \"选择功能模块\",\r\n [\"首页\", \"Excel数据分析\", \"CSV数据分析\", \"文本问答\", \"AI聊天助手\", \"数据库分析\", \"图像分析\", \"Web爬虫\"],\r\n index=0\r\n )\r\n# 主页面\r\nif page == \"首页\":\r\n st.title(\"🌟 六棵松互联智能分析平台\")\r\n st.subheader(\"一站式智能数据分析与AI助手解决方案\")\r\n\r\n # 功能卡片\r\n col1, col2, col3 = st.columns(3)\r\n with col1:\r\n st.markdown(\"\"\"\r\n
支持Excel、CSV等多种数据格式,提供强大的数据预处理和分析功能
\r\nChatGPT式连续对话,支持自定义头像和多模态输入
\r\n集成搜索、翻译、代码执行等多种插件,扩展平台能力
\r\n支持语音输入和输出,提供更自然的交互体验
\r\n自动抓取网页内容并进行分析
\r\n多用户权限管理,支持团队协同工作
\r\n