From 37f09828098bd872873d424a23b8a9d62c2640ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=A0=E7=9A=84=E5=A7=93=E5=90=8D?= <你的邮箱@example.com> Date: Thu, 15 Jan 2026 23:34:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(security):=20=E7=A7=BB=E9=99=A4=E7=A1=AC?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E7=9A=84API=E5=AF=86=E9=92=A5=E5=B9=B6?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将硬编码的API密钥替换为从环境变量中读取,并添加未配置时的模拟响应 为Streamlit组件添加唯一key属性以避免重复渲染问题 --- bigwork/final_models/crisis_index_model.pkl | Bin 245347 -> 245199 bytes .../final_models/propagation_risk_model.pkl | Bin 252817 -> 252641 bytes bigwork/final_models/trend_analysis_model.pkl | Bin 597869 -> 597117 bytes bigwork/src/crisis_warning_app.py | 12 ++++---- bigwork/src/smart_care_system.py | 23 +++++++++++++- bigwork/src/smart_customer_service.py | 28 +++++++++++++++--- 6 files changed, 53 insertions(+), 10 deletions(-) diff --git a/bigwork/final_models/crisis_index_model.pkl b/bigwork/final_models/crisis_index_model.pkl index c0be13baeacb7200dd35bb14dd904378bdbcb582..85528b5c971d99106b05c7b8e30e2bfeb9050356 100644 GIT binary patch delta 446 zcmb`Dze)o^5XN&Zl9+^OlUUd+Hc53THn!$Okc%MxDJ5(!%Vo*lZrI(6q|zcmgzX#& z_z1RIC0L73!gl6d!7xx+7NiNkU@R*+}Eq39uXUnRw3_ zD%wOC9LS`{2@^(xU3YHiR^qypT_$3DtYnMR#94&~F?2yxY)EbXre@DYSIA2Nc7;n3 Ob0(;U-*3IWpobsPVy8?1 delta 714 zcmc&x%}(1u5O%Ws1c!$3-;yHb)|?`>mvTc&5eEz@im0>_LebjUI#xEj8G8*xsuYCy zRgro^zH#U?^i<$naq2_#F+gg^w%`enI)~kvZ@zD4cjotf;m*bxmsjXBzqEnudx0sUh#E zZ~Dp>yc@tvn#b%q)BN!*ujqJ;s6ao}TS(URNp_^#lTe~#NDxZ8!jn9J*SN1m+}Afm VV{7lX`=Nc2`^=dRqm5f~_z%hU;&T81 diff --git a/bigwork/final_models/propagation_risk_model.pkl b/bigwork/final_models/propagation_risk_model.pkl index cfc0bb815b8023e6072bd3c0dd102a7e4dc06919..e128c572f6ad7812cccff0ebe3f24c3282bc5f65 100644 GIT binary patch delta 472 zcmbQZo&Vuh{tY`AnJx4THt%M9%gDt#brAyuOrFguWyup?l$xBMS6ot5np`qv@{}Id zywco)$|*hUc`1oSMTwO_F>i*}Db9>ZQ`)BlP0{dX^k!O5i!;H3Ko?C{xWT*%X!AEpZDxbnEC#ljwJ~_WMuVhM(%=Gy;nPnWO^l)e7mlnn6r^TlLgR+MkNP;*(rP)(@xH5~utkk@e tDLsP4sd*)txj-Tw7z3$AnaNW??&Z71tim1O%mH?<*wafqj delta 789 zcmchVze~eF6vuP9{xVhTk6In-=FmydL7jAP(m)GUA&Z7IIW^c``jU%M5FDh|4hrH> zoShT|L9~MSM>t7G!NtMVRbQifoqBNZ?)!c39ej@WcAq$FCT<@Iot>P%dm^7imd(b% zD@`3Jy30(5d&2cip@3v^zf`U$+%jC(s3<^GsS2{Gn~udyPhq@$QGjYhlB5EJv zL)d%@!bcFvL$n65JoIE#qRLfJ{vNbMrHp-XO~(4%9Q4+YYtWZpg8q#9``A7tvf1qN zH?AP43jziT^>rA`Xg%2U{&@3odHQj21w+63`Sec@GXcr-eCUgi!(6zQ3lrROGZ&`! zFWmv99YNRr2O2|A&bIJBcNua<1L+IbD8jJTPL>_d4w6ZP9%($h((CRZMmi$S{|~Vb zDO@J@7!x>EJ{QQDMz29yG`)hDaTME*@9NH`ZW$Fw1`giZ2Da_Mh^AnT?FEW)3sTx3 m8Xn`qE@9Adh?#4fFp8fv*4Sv#iMX~Hn;FLEVelN=?qsD=sN2O)i--c}fp!UTJPY z<&+-wyp+VEqQpv|m^VY~6lcbyDeY5&rf7IGdNa39$zbkbO)04?NCjzO^0$~AuvVtt zzGO;LXY3S>42B-I;^f4f#3G<<22T%Drp1)b4v22%9!8rfetv#l|A7EZcryUCIdec= z#xSJ~XbaE+kqmKX4o0XbSP&w_ge=rHB|{|@s9kSr8Uw>*g_}7*KXySCQ07NQ?0)2i z`q3{D7+5~HGAC!;6Wo0A)+bh=#XVH9mbPnRL>aJ&bX8bh?#+y1&CRJm~A`bQudZ&pqp1v z#mzVpgeJ_*J?zCLi6yCe2Eb$mVHv_%MpJZJGT_aZOcLAtP3F=9fQa@ zz)&)oUKYlYxOp?vR@UtuF&t)+gUER+$~aoNc|aK(0=Dawb2u0eA_qpS=7<|a&RMXA l!=I65`=2!&O>%?CSs7>0qVe6C(P+d|c0r?Y4-@A`835=7%18hJ delta 2898 zcmeynL*?y0l?}76GchGk-zd%@R?ih*l$xBMS6ot5nq0zF$dH^@np;rGm6wuORFqiB zRmkYg&|1ip9G{$@lA2u1m6``)a1}B~FfuSOBo(qmumS0u#FETB!$Q`!Lbjkn_Vz-K zph8X!Z$@wC)Y;m!)glo{rvpA{sRG+ z@U|~06iDifEfmy%xwSYsF(Omg9>F@3uQBeGDM-OKwblZLOGBs`Jh6DwnD|ALR}>!H6U+* zK%p{7jY?3VYFnXNP@#HTp+<&AYDuByfh=o89}1VdSqm{9ghEGZP4JpX3qQ?8C;|*2(dp|#I83H@N^m5ybAvM5|Nq-xOK{w_9M*m=3+Ct;)*b{# z>QqLK?H-{V&*X-+NAHzzv@$Yn&nx9{Fdo((ja$hPH>^FFvx>ui^M9XRtlKj;a9oub e)_#3=5}a!5PK~Bo`ZX?TQhOp&Z6zxwi#P!3d5^pR diff --git a/bigwork/src/crisis_warning_app.py b/bigwork/src/crisis_warning_app.py index 9846da2..409a087 100644 --- a/bigwork/src/crisis_warning_app.py +++ b/bigwork/src/crisis_warning_app.py @@ -573,7 +573,8 @@ class CrisisWarningApp: user_input = st.text_area( "请输入推文内容或事件描述", "", # 默认空白 - height=150 + height=150, + key="crisis_input_text" ) # 自动情感分析 @@ -641,7 +642,7 @@ class CrisisWarningApp: st.metric("传播风险等级", result['propagation_analysis']['risk_level']) st.write("**生成的公关声明:**") - st.text_area("", result['ai_solutions']['pr_statement'], height=100, disabled=True) + st.text_area("", result['ai_solutions']['pr_statement'], height=100, disabled=True, key=f"history_pr_{i}") def _perform_integrated_analysis(self, text_content, retweet_count=0, sentiment="negative"): """执行整合分析,调用所有模块并生成综合结果""" @@ -723,7 +724,7 @@ class CrisisWarningApp: # 4. 危机公关方案 st.markdown("

📝 危机公关方案

", unsafe_allow_html=True) - st.text_area("生成的公关声明", result['ai_solutions']['pr_statement'], height=300) + st.text_area("生成的公关声明", result['ai_solutions']['pr_statement'], height=300, key="result_pr") # 风险等级解释 if result['crisis_analysis']['risk_level'] == "高风险": @@ -744,7 +745,8 @@ class CrisisWarningApp: st.subheader("公关声明生成") event_details = st.text_area( "请输入事件详情", - "因天气原因,我公司今日有200多个航班延误,影响乘客约3000人" + "因天气原因,我公司今日有200多个航班延误,影响乘客约3000人", + key="event_details" ) target_audience = st.text_input("目标受众", "乘客") tone = st.text_input("语气要求", "道歉且负责任") @@ -756,7 +758,7 @@ class CrisisWarningApp: target_audience, tone ) - st.text_area("生成的公关声明", pr_statement, height=400) + st.text_area("生成的公关声明", pr_statement, height=400, key="ai_pr") # 运行应用 if __name__ == "__main__": diff --git a/bigwork/src/smart_care_system.py b/bigwork/src/smart_care_system.py index 66323ce..e8024dd 100644 --- a/bigwork/src/smart_care_system.py +++ b/bigwork/src/smart_care_system.py @@ -47,7 +47,13 @@ USER_TYPES = { } # DeepSeek API配置 -DEEPSEEK_API_KEY = "sk-eb8cc78f22ef443491d4199e56bde9a7" +import os +from dotenv import load_dotenv + +# 加载环境变量 +load_dotenv() + +DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY") DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions" @@ -56,6 +62,21 @@ def call_deepseek_api(prompt: str, max_tokens: int = 500, temperature: float = 0 import time import requests + # 检查API Key是否配置 + if not DEEPSEEK_API_KEY: + print("DeepSeek API密钥未配置,返回模拟响应") + # 返回模拟响应 + if "问题分类" in prompt: + return json.dumps({"primary_category": "其他", "secondary_category": "其他"}, ensure_ascii=False) + elif "用户类型" in prompt: + return json.dumps({ + "main_type": "效率型", + "type_probabilities": {"效率型": 0.6, "舒适型": 0.2, "经济型": 0.1, "情感型": 0.1}, + "type_characteristics": USER_TYPES["效率型"] + }, ensure_ascii=False) + else: + return "API密钥未配置,返回模拟响应。这是一个智能生成的关怀方案描述。" + max_retries = 3 retry_delay = 2 timeout = 60 # 增加超时时间到60秒 diff --git a/bigwork/src/smart_customer_service.py b/bigwork/src/smart_customer_service.py index 8be34bc..484f62b 100644 --- a/bigwork/src/smart_customer_service.py +++ b/bigwork/src/smart_customer_service.py @@ -1068,11 +1068,21 @@ class SmartCustomerService: import requests import json + import os + from dotenv import load_dotenv + + # 加载环境变量 + load_dotenv() # DeepSeek API配置 - api_key = "sk-eb8cc78f22ef443491d4199e56bde9a7" + api_key = os.getenv("DEEPSEEK_API_KEY") api_url = "https://api.deepseek.com/v1/chat/completions" + # 检查API密钥是否配置 + if not api_key: + print("DeepSeek API密钥未配置,返回默认响应") + return "感谢您的反馈。我们的客服团队将尽快处理您的问题,并与您联系。" + # 构建系统提示 system_prompt = """ 你是一个专业的航空公司客服助手,需要基于用户的反馈和流失分析结果生成结构化的响应。 @@ -1299,11 +1309,21 @@ class SmartCustomerService: import requests import json + import os + from dotenv import load_dotenv + + # 加载环境变量 + load_dotenv() # 使用用户提供的DeepSeek API密钥 - api_key = "sk-eb8cc78f22ef443491d4199e56bde9a7" + api_key = os.getenv("DEEPSEEK_API_KEY") api_url = "https://api.deepseek.com/v1/chat/completions" + # 检查API密钥是否配置 + if not api_key: + print("DeepSeek API密钥未配置,返回默认情感分析结果") + return "neutral" + # 构建系统提示 system_prompt = """ 你是一个专业的情感分析助手,需要分析用户反馈的情感倾向。 @@ -1915,7 +1935,7 @@ def show_chat_interface(customer_service: SmartCustomerService): # 用户输入 st.markdown("### 💭 请输入您的查询") - user_query = st.text_area("您的消息", placeholder="请输入您的问题或反馈...", value=user_content) + user_query = st.text_area("您的消息", placeholder="请输入您的问题或反馈...", value=user_content, key="user_query") if st.button("发送", type="primary") and user_query: with st.spinner("正在分析您的查询并生成响应..."): @@ -1961,7 +1981,7 @@ def show_churn_analysis(customer_service: SmartCustomerService): # 手动输入区域 st.markdown("### 👤 手动输入分析") user_id = st.text_input("用户ID", placeholder="请输入用户ID,例如:user_001") - user_content = st.text_area("用户反馈内容", placeholder="请输入用户反馈内容...") + user_content = st.text_area("用户反馈内容", placeholder="请输入用户反馈内容...", key="user_feedback") if st.button("🔍 进行流失分析", type="secondary") and user_id and user_content: with st.spinner("正在基于输入内容分析用户流失风险..."):