From f19668ca3a200d8d6aa9d593d4fc5be3f14475d5 Mon Sep 17 00:00:00 2001 From: renjianbo <18691577328@163.com> Date: Thu, 2 Apr 2026 17:39:09 +0800 Subject: [PATCH] first commit --- .env.example | 107 +++++++++++ .env.test | 10 ++ .gitignore | 44 +++++ config.py | 72 +++++--- config/__pycache__/__init__.cpython-312.pyc | Bin 978 -> 969 bytes config/__pycache__/base.cpython-312.pyc | Bin 3939 -> 3824 bytes .../__pycache__/development.cpython-312.pyc | Bin 2004 -> 2519 bytes config/__pycache__/local.cpython-312.pyc | Bin 1280 -> 1271 bytes config/__pycache__/production.cpython-312.pyc | Bin 2675 -> 3584 bytes config/__pycache__/testing.cpython-312.pyc | Bin 1994 -> 1985 bytes config/base.py | 12 +- config/development.py | 16 ++ config/production.py | 26 ++- requirements.txt | 3 +- .../__pycache__/__init__.cpython-312.pyc | Bin 5643 -> 5634 bytes .../__pycache__/config.cpython-312.pyc | Bin 1288 -> 1733 bytes src/flask_prompt_master/admin/__init__.py | 2 +- .../__pycache__/__init__.cpython-312.pyc | Bin 7947 -> 7907 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 328 -> 319 bytes .../__pycache__/admin_forms.cpython-312.pyc | Bin 2399 -> 2390 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 289 -> 280 bytes .../__pycache__/admin_user.cpython-312.pyc | Bin 4025 -> 4016 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 474 -> 465 bytes .../analytics_admin.cpython-312.pyc | Bin 10873 -> 10864 bytes .../__pycache__/api_admin.cpython-312.pyc | Bin 9445 -> 9436 bytes .../__pycache__/backup_admin.cpython-312.pyc | Bin 24512 -> 24503 bytes .../__pycache__/batch_admin.cpython-312.pyc | Bin 9664 -> 9655 bytes .../__pycache__/monitor_admin.cpython-312.pyc | Bin 9180 -> 9171 bytes .../__pycache__/prompt_admin.cpython-312.pyc | Bin 1803 -> 1794 bytes .../__pycache__/report_admin.cpython-312.pyc | Bin 12321 -> 12312 bytes .../__pycache__/system_admin.cpython-312.pyc | Bin 4019 -> 4010 bytes .../template_admin.cpython-312.pyc | Bin 2039 -> 2030 bytes .../__pycache__/user_admin.cpython-312.pyc | Bin 2214 -> 2205 bytes src/flask_prompt_master/config.py | 37 ++-- .../__pycache__/__init__.cpython-312.pyc | Bin 309 -> 300 bytes .../forms/__pycache__/forms.cpython-312.pyc | Bin 1182 -> 1173 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 361 -> 352 bytes .../__pycache__/favorites.cpython-312.pyc | Bin 3185 -> 3176 bytes .../history_models.cpython-312.pyc | Bin 14832 -> 14823 bytes .../models/__pycache__/models.cpython-312.pyc | Bin 14831 -> 14822 bytes .../poetry_favorites.cpython-312.pyc | Bin 5035 -> 5026 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 301 -> 292 bytes .../__pycache__/android_tools.cpython-312.pyc | Bin 14609 -> 14600 bytes .../routes/__pycache__/auth.cpython-312.pyc | Bin 9753 -> 9744 bytes .../expert_generate_2.cpython-312.pyc | Bin 11044 -> 11035 bytes .../expert_generate_3.cpython-312.pyc | Bin 12372 -> 12363 bytes .../__pycache__/favorites.cpython-312.pyc | Bin 5131 -> 5122 bytes .../history_routes.cpython-312.pyc | Bin 18181 -> 18172 bytes .../__pycache__/meal_planning.cpython-312.pyc | Bin 14434 -> 14425 bytes .../meeting_minutes.cpython-312.pyc | Bin 10754 -> 10745 bytes .../placeholder_apps.cpython-312.pyc | Bin 20120 -> 20111 bytes .../routes/__pycache__/poetry.cpython-312.pyc | Bin 16994 -> 16985 bytes .../prompt_optimization.cpython-312.pyc | Bin 5924 -> 5915 bytes .../resume_optimization.cpython-312.pyc | Bin 11692 -> 11683 bytes .../routes/__pycache__/routes.cpython-312.pyc | Bin 52053 -> 52044 bytes .../smart_prompt_optimization.cpython-312.pyc | Bin 9853 -> 9844 bytes .../travel_planning.cpython-312.pyc | Bin 14073 -> 14064 bytes .../__pycache__/weekly_report.cpython-312.pyc | Bin 10627 -> 10618 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 251 -> 242 bytes .../__pycache__/auth_service.cpython-312.pyc | Bin 10633 -> 11541 bytes .../favorite_service.cpython-312.pyc | Bin 8801 -> 8792 bytes .../poetry_favorite_service.cpython-312.pyc | Bin 11087 -> 11078 bytes .../services/auth_service.py | 39 +++- .../__pycache__/__init__.cpython-312.pyc | Bin 248 -> 239 bytes .../performance_monitor.cpython-312.pyc | Bin 5011 -> 5002 bytes test_config.py | 166 ++++++++++++++++++ 66 files changed, 475 insertions(+), 59 deletions(-) create mode 100644 .env.example create mode 100644 .env.test create mode 100644 test_config.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4752a56 --- /dev/null +++ b/.env.example @@ -0,0 +1,107 @@ +# ======================================== +# Flask提示词大师应用环境变量配置示例 +# ======================================== +# 复制此文件为 .env 并根据实际情况修改配置 +# cp env.example .env + +# ======================================== +# Flask基础配置 +# ======================================== +# Flask应用密钥(必需) +SECRET_KEY=your-secret-key-here + +# 应用环境(development/production/testing) +FLASK_ENV=development + +# 调试模式(开发环境开启,生产环境关闭) +DEBUG=True + +# ======================================== +# 数据库配置 +# ======================================== +# 主数据库连接URL(必需) +# MySQL示例: mysql+pymysql://username:password@host:port/database_name?charset=utf8mb4 +DATABASE_URL=mysql+pymysql://username:password@localhost:3306/database_name?charset=utf8mb4 + +# 腾讯云数据库连接URL(可选) +# TENCENT_DATABASE_URL=mysql+pymysql://username:password@tencent-host:port/database_name?charset=utf8mb4 + +# ======================================== +# OpenAI兼容API配置 +# ======================================== +# API基础URL(必需) +LLM_API_URL=https://api.deepseek.com/v1 + +# API密钥(必需) +LLM_API_KEY=sk-your-api-key-here + +# ======================================== +# 微信小程序配置 +# ======================================== +# 小程序AppID(必需) +WX_APPID=your-wx-appid-here + +# 小程序Secret(必需) +WX_SECRET=your-wx-secret-here + +# ======================================== +# 跨域配置 +# ======================================== +# 允许跨域的域名,多个用逗号分隔 +# 开发环境: http://localhost:3000,http://127.0.0.1:3000 +# 生产环境: https://yourdomain.com,https://www.yourdomain.com +CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000 + +# ======================================== +# 日志配置 +# ======================================== +# 日志级别(DEBUG/INFO/WARNING/ERROR/CRITICAL) +LOG_LEVEL=INFO + +# 日志文件路径 +LOG_FILE=logs/app.log + +# ======================================== +# 缓存配置 +# ======================================== +# 缓存类型(simple/redis/memcached) +CACHE_TYPE=simple + +# 缓存默认超时时间(秒) +CACHE_DEFAULT_TIMEOUT=300 + +# Redis缓存URL(当CACHE_TYPE=redis时使用) +# REDIS_URL=redis://localhost:6379/0 + +# ======================================== +# 会话配置 +# ======================================== +# 会话生命周期(小时) +SESSION_LIFETIME_HOURS=24 + +# ======================================== +# 文件上传配置 +# ======================================== +# 最大文件上传大小(字节) +MAX_CONTENT_LENGTH=16777216 + +# 文件上传目录 +UPLOAD_FOLDER=uploads + +# ======================================== +# 安全配置 +# ======================================== +# 是否启用CSRF保护 +WTF_CSRF_ENABLED=True + +# CSRF令牌超时时间(秒) +WTF_CSRF_TIME_LIMIT=3600 + +# ======================================== +# 性能配置 +# ======================================== +# 数据库连接池大小 +DB_POOL_SIZE=20 + +# 数据库连接池最大溢出连接数 +DB_MAX_OVERFLOW=30 \ No newline at end of file diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..ed35e64 --- /dev/null +++ b/.env.test @@ -0,0 +1,10 @@ +# 测试环境变量文件 +FLASK_ENV=development +SECRET_KEY=test-secret-key-for-development +DATABASE_URL=sqlite:///test.db +LLM_API_URL=https://api.deepseek.com/v1 +LLM_API_KEY=sk-test-api-key-for-development +WX_APPID=test-wx-appid +WX_SECRET=test-wx-secret +CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000 +LOG_LEVEL=DEBUG \ No newline at end of file diff --git a/.gitignore b/.gitignore index f2bbe4f..ad08dd0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,47 @@ env/ ENV/ myenv/ +# 环境变量文件 +.env +.env.local +.env.*.local + +# 日志文件 +logs/ +*.log + +# 缓存文件 +__pycache__/ +*.py[cod] +*$py.class + +# 数据库文件 +*.db +*.sqlite3 + +# 上传文件 +uploads/ + +# 备份文件 +*.bak +*.backup + +# IDE配置文件 +.vscode/ +.idea/ +*.swp +*.swo + +# 操作系统文件 +.DS_Store +Thumbs.db + +# 测试覆盖率 +.coverage +htmlcov/ + +# 构建输出 +dist/ +build/ +*.egg-info/ + diff --git a/config.py b/config.py index 6bfaaea..de855c0 100644 --- a/config.py +++ b/config.py @@ -6,50 +6,68 @@ # class Config: # SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key' - + # # MySQL数据库配置 # SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'mysql+pymysql://root:123456@localhost:3306/pro_db?charset=utf8mb4' # SQLALCHEMY_TRACK_MODIFICATIONS = False - + # # OpenAI兼容API配置 # LLM_API_URL = os.environ.get('LLM_API_URL') or 'https://api.deepseek.com/v1' # LLM_API_KEY = os.environ.get('LLM_API_KEY') or 'sk-fdf7cc1c73504e628ec0119b7e11b8cc' - + # # 微信小程序配置 # WX_APPID = os.environ.get('WX_APPID') or 'wx2c65877d37fc29bf' # 替换为你的小程序 appid # WX_SECRET = os.environ.get('WX_SECRET') or '89aa97dda3c1347c6ae3d6ab4627f1f4' # 替换为你的小程序 secret - + # # 添加跨域支持 # CORS_ORIGINS = ['*'] # 生产环境建议设置具体域名 + +# 此文件已弃用,请使用 config/ 目录下的配置系统 +# 为了向后兼容,此文件重定向到新的配置系统 import os +import warnings from dotenv import load_dotenv # 在配置类定义前加载环境变量 load_dotenv() +# 警告:此文件已弃用,请使用 config/ 目录下的配置系统 +warnings.warn("config.py 已弃用,请使用新的配置系统 (config/ 目录)", DeprecationWarning) + class Config: - SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key' - - # ---------------------- 原有本地MySQL数据库配置 ---------------------- - SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'mysql+pymysql://root:123456@localhost:3306/pro_db?charset=utf8mb4' - SQLALCHEMY_TRACK_MODIFICATIONS = False # 关闭SQLAlchemy的修改跟踪(减少性能消耗) - - # ---------------------- 新增:腾讯云数据库配置 ---------------------- - # 腾讯云数据库连接URI(格式:mysql+pymysql://用户名:密码@数据库地址:端口/数据库名?charset=utf8mb4) - # 注意:需先在腾讯云控制台创建目标数据库(如命名为 pro_db_tencent,需替换为你的实际库名) - TENCENT_SQLALCHEMY_DATABASE_URI = os.environ.get('TENCENT_DATABASE_URL') or \ - 'mysql+pymysql://root:!Rjb12191@gz-cynosdbmysql-grp-d26pzce5.sql.tencentcdb.com:24936/pro_db?charset=utf8mb4' - # 腾讯云数据库同样关闭修改跟踪(与本地配置保持一致) + SECRET_KEY = os.environ.get('SECRET_KEY') + if not SECRET_KEY: + raise ValueError("SECRET_KEY 环境变量未设置,请设置环境变量或使用新的配置系统") + + # ---------------------- 数据库配置 ---------------------- + SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') + if not SQLALCHEMY_DATABASE_URI: + raise ValueError("DATABASE_URL 环境变量未设置,请设置环境变量或使用新的配置系统") + + SQLALCHEMY_TRACK_MODIFICATIONS = False + + # ---------------------- 腾讯云数据库配置 ---------------------- + TENCENT_SQLALCHEMY_DATABASE_URI = os.environ.get('TENCENT_DATABASE_URL') TENCENT_SQLALCHEMY_TRACK_MODIFICATIONS = False - - # ---------------------- 其他原有配置(保持不变) ---------------------- - # OpenAI兼容API配置 + + # ---------------------- OpenAI兼容API配置 ---------------------- LLM_API_URL = os.environ.get('LLM_API_URL') or 'https://api.deepseek.com/v1' - LLM_API_KEY = os.environ.get('LLM_API_KEY') or 'sk-fdf7cc1c73504e628ec0119b7e11b8cc' - - # 微信小程序配置 - WX_APPID = os.environ.get('WX_APPID') or 'wx2c65877d37fc29bf' # 替换为你的小程序 appid - WX_SECRET = os.environ.get('WX_SECRET') or '89aa97dda3c1347c6ae3d6ab4627f1f4' # 替换为你的小程序 secret - - # 添加跨域支持 - CORS_ORIGINS = ['*'] # 生产环境建议设置具体域名(如 ['https://your-domain.com']) \ No newline at end of file + LLM_API_KEY = os.environ.get('LLM_API_KEY') + if not LLM_API_KEY: + raise ValueError("LLM_API_KEY 环境变量未设置,请设置环境变量或使用新的配置系统") + + # ---------------------- 微信小程序配置 ---------------------- + WX_APPID = os.environ.get('WX_APPID') + WX_SECRET = os.environ.get('WX_SECRET') + if not WX_APPID or not WX_SECRET: + raise ValueError("WX_APPID 和 WX_SECRET 环境变量未设置,请设置环境变量或使用新的配置系统") + + # ---------------------- 跨域配置 ---------------------- + CORS_ORIGINS = os.environ.get('CORS_ORIGINS', '*').split(',') + + @staticmethod + def init_app(app): + """初始化应用配置(为兼容性保留)""" + # 创建必要的目录 + os.makedirs('logs', exist_ok=True) + os.makedirs('uploads', exist_ok=True) \ No newline at end of file diff --git a/config/__pycache__/__init__.cpython-312.pyc b/config/__pycache__/__init__.cpython-312.pyc index a5a3a2577de00fcf36ad6dc35fdfef28b8752d29..4211506fba4ac77510af4c7bf4b5b5bedab735c7 100644 GIT binary patch delta 49 zcmcb_ev+N{G%qg~0}!N2oXhmz$XmxGD(_+ylbDzolbBgjoE(#!pO==I9D?CBujC!A(Jq-09=J2NCmTCiqPb_Os2fTDIzeHQNmyu(G;=Cyv&x2 z;*;H(-6wM~bBn;Vu91SVq9i8AGdoRw&#cQVn<6(^p2d_|K1E@2IEyNy;^bNuQ%$85 zWtg#WJ+i5CDJm@tt0C@Uh?1{V)l{2&o8`6YEspSrc*lSMPnTPqKvuA;bC7GuEgon8 zpx}7_AWwHszu;R8o3+`dvxrK&Sj8kJCdMRYmJ}z)BmQ(lo2(bY^4{ZT?-d9f7n$$ObhnI%#r zCx2zKWR#k$&+I<=2(vKL8rjL+%$Ce@De{w#Gu!eiq$t9*N`bUap2fmF*_}m}T_szC zfgws}@_#0MP1O`Nm@1fqqGVI$Qq)@*RzvJ%h?1|=(A1oKnB{eSl}K^6Ze@OHk#1r^ zrfzm>rEW%QQR*#@@Q8TFfB;XIDxvZUn0!HI3PhF@C>!kR9ON2OB@EUJR8yRqT$EY@ zk>_#t4+@U=5At;P^b5YlsCA1`=N6}rzk9roYnZFgEf!BdH~(84Ac4(qS!-G3RP;0Q zb5r$;QuDGh6Z4Yt^%FBoij(z|^YhX&)Acvkb6GJl-krRQry=r^kmm(s&j#-gYzzWI z{Z*Y+{dJvnGqNu8YhL1ayrApY;BiAhXgb$KuIYRe`DRpK7SO&V;BrCVrNI-ZLqu%4 j)kLf5b`$Lu=xtEGENpgN*yf_J&5q#9!j798dGi?oGx?Ti diff --git a/config/__pycache__/development.cpython-312.pyc b/config/__pycache__/development.cpython-312.pyc index 2e05c342a0c27f57b7e3bdbf542feb4d5548fc06..a526d29e5566f69e6b972724c67f75a666004d51 100644 GIT binary patch delta 929 zcmZvaO-vI(6vt0E6(uu}PU%;8~uPVHt>2lbSBNV*~Zb6ozyY%CrnL z+Zrsx#nvV}T4mcCoSX~@%3zWEtB=o!l^LAR-efq+)zn8Tj0`!wdtsMGjdDFX@ zI+f1n7Sv4Y-$mG*F<2<-oJmsw_|WX9{A!i!uiJs!d%*kmd4J7+u@bIwJzu!)8t2`P zZN@&Gj#s(FH{P?owzXF48LosM#mH`bYrWdfcA0y&2<$aG8K1oaAL>4HjPb)!^ER^s zJIx==1-^^im7R?wXQS~OxcL!#C8~P}8Y`W%n@ius&c8unAnU%=V6Vk{}XpImWYjd0A5?^hKv!TYEf{cwF!$GOpaxPns&Pq9;i;Hml9gB=6rQ<1yLW%?vMjJHbZKbiZ!0CKX{#b_UD!=aN}*+GYj4n-?al?3EjnSE9*Q zcg}os=FHv5AN4wJi=q{f@zt)cqkq_5b-ZxU0|A%-H-G{ph=9Z(D6xoyha?CSZ z*lwSe3-iw8WMd1I0&G$WkfRe`ssaED3{c$2x$VCKkp<-<7s^BVZ*o$h;z0#tV16qZ zkcuY3i%=>K0c{)}J{QRlN_$O2vgF&SCf3*C4KR=i0$_?80#|vEO#=afL!g_>0rkSV2YM=Hz1f(`MZD`DciJx-no_h_;0?3PWd_{7nrff~PLX0e_pn-X99e zXImTN9>QS#wZu=KytjVs!{oa!C%+gUx%bYky9=MMf3^^(N6*-=&)%E3Zh-qI{vVLV zH?*{d+Ohk zss`5^?okZ>GL1AWvK)zpRaKT%(mbG)jL|>$1ZvyE;c$C6I-o|{X`CzC+1`))P&_ga z?dz@SAH+`WSCe~Wn<8bT(hhzw3f2U1%Dg0az7>j70&o=19!wmYJEq$oT@{OG11sL@ zC2zHE-@hsr&gLgd=1O#X<*MkJElbqQ)#!HLs#x(pw^9{YstV}#V9I9lT6Mv*;RN35 zsgsj|nQ|k~v*s?CM8hHx2CT*oGJjml^s^>v!MnAO z_*Y=D_PD76R%p+e>MI|k<_e0o_k^P{xhvd@VhUF2W1|(sw1e;gQlZ_@uZiYg%(#eH ze7m%N%tv@kJ6)?2_S&AHuqUag)uO^RTOC!?RC2Yyh5c;@$l4GyHxyA~Fr1 Z3nBatSiT3IP3|m&H8Yp*13ITe{{>XSe}e!3 delta 666 zcmZuvzi-n(7`=0B$Byl!O`Il`I;2QY($bhRpo$-rpsJ!SEozx=iJY8CoF=w)PK(k3 zGE@~T{Ll?BurMLW$Une>gv7$YP#GZsVniraVL=SsHM9~EpLFlOdw1`B-<_^EabPCj z8b$)J_Lg6vq-$9JOguTh3g}arM7} z- z7*5q8GO>b3@F-5>%o7o1oiS|gfd1cZP_CP$PvLo5m9Ec3`r_)^dS!KOxxBox9)Sp+ z*&b_jIzf2Bvbz2z!G7Czy;99@zkDMFFM59|-_)zOCpn#E5b5lE ztJ1JN+;T`LGOEDh*R<8}+m1yXuj$%e)wgW76V|Mn@7-|gRzQ5bS?jpIR|>kMz(m{Q z*N(Zx!$T$4b2}9~2xi%K_=Q0ad{vV7Q+HF3>26|AIbal6Ddwr8U8c{p6WSD86ZR^A z6zO~Io;<@-jkfjK`2tIy19FZta~$L&;2npr80>(3L6DSz42*PdX)l@Sl?O8Yu6LDB z`LpkGb9Zza8YegQg`89x8gY-JNO;*utlFVNxY^KpiD$>-MHl}kTTog-y$4m aFo;12KLGV3$o~+pKv;UP^%L;)G%qg~0}wo{Ta|H-Z6lvQi=4WCMt*Lpeo<;(R%T*eQoep-W=V0fesX?Z NT4uWb<{}n}6QlqD diff --git a/config/base.py b/config/base.py index 7ffe275..2b9ede5 100644 --- a/config/base.py +++ b/config/base.py @@ -23,14 +23,14 @@ class Config: # OpenAI兼容API配置 LLM_API_URL = os.environ.get('LLM_API_URL') or 'https://api.deepseek.com/v1' - LLM_API_KEY = os.environ.get('LLM_API_KEY') or 'sk-your-api-key-here' + LLM_API_KEY = os.environ.get('LLM_API_KEY') # 微信小程序配置 - WX_APPID = os.environ.get('WX_APPID') or 'wx-your-appid-here' - WX_SECRET = os.environ.get('WX_SECRET') or 'your-wx-secret-here' - - # 跨域配置 - CORS_ORIGINS = os.environ.get('CORS_ORIGINS', '*').split(',') + WX_APPID = os.environ.get('WX_APPID') + WX_SECRET = os.environ.get('WX_SECRET') + + # 跨域配置 - 默认值在具体环境配置中设置 + CORS_ORIGINS = os.environ.get('CORS_ORIGINS', '').split(',') # 日志配置 LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO') diff --git a/config/development.py b/config/development.py index e2b1129..09e4b4b 100644 --- a/config/development.py +++ b/config/development.py @@ -12,6 +12,22 @@ class DevelopmentConfig(Config): super().__init__() if not self.SQLALCHEMY_DATABASE_URI: self.SQLALCHEMY_DATABASE_URI = 'sqlite:///dev.db' + + # 开发环境API配置(如果未设置,使用示例值并给出警告) + if not self.LLM_API_KEY: + self.LLM_API_KEY = 'sk-dev-example-api-key' + import warnings + warnings.warn("LLM_API_KEY not set, using development example key") + + if not self.WX_APPID: + self.WX_APPID = 'wx-dev-example-appid' + + if not self.WX_SECRET: + self.WX_SECRET = 'wx-dev-example-secret' + + # 开发环境CORS配置(如果没有设置,使用开发默认值) + if not self.CORS_ORIGINS or self.CORS_ORIGINS == ['']: + self.CORS_ORIGINS = ['http://localhost:3000', 'http://127.0.0.1:3000', '*'] # 开发环境日志配置 LOG_LEVEL = 'DEBUG' diff --git a/config/production.py b/config/production.py index c40ff8d..ea9da6c 100644 --- a/config/production.py +++ b/config/production.py @@ -7,7 +7,27 @@ class ProductionConfig(Config): """ DEBUG = False TESTING = False - + + def __init__(self): + super().__init__() + + # 生产环境必须设置的关键配置检查 + required_configs = [ + ('SECRET_KEY', self.SECRET_KEY), + ('LLM_API_KEY', self.LLM_API_KEY), + ('WX_APPID', self.WX_APPID), + ('WX_SECRET', self.WX_SECRET), + ('SQLALCHEMY_DATABASE_URI', self.SQLALCHEMY_DATABASE_URI) + ] + + for name, value in required_configs: + if not value: + raise ValueError(f"生产环境必须设置{name}环境变量") + + # 生产环境CORS配置检查(在父类中已经设置) + if not self.CORS_ORIGINS or self.CORS_ORIGINS == ['']: + raise ValueError("生产环境必须设置CORS_ORIGINS环境变量,指定允许的域名") + # 生产环境日志配置 LOG_LEVEL = 'WARNING' LOG_FILE = 'logs/production.log' @@ -31,8 +51,8 @@ class ProductionConfig(Config): # 生产环境跨域配置(需要设置具体的域名) CORS_ORIGINS = os.environ.get('CORS_ORIGINS', '').split(',') if not CORS_ORIGINS or CORS_ORIGINS == ['']: - # 如果没有设置,使用默认值而不是抛出异常 - CORS_ORIGINS = ['https://yourdomain.com'] + # 生产环境必须设置CORS域名 + raise ValueError("生产环境必须设置CORS_ORIGINS环境变量,指定允许的域名") # 生产环境性能配置 SQLALCHEMY_ENGINE_OPTIONS = { diff --git a/requirements.txt b/requirements.txt index 9efa935..94360e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,5 @@ waitress>=3.0.0 redis>=5.0.1 pywin32>=306 requests>=2.28.0 -psutil>=5.9.0 \ No newline at end of file +psutil>=5.9.0 +bcrypt>=4.0.0 \ No newline at end of file diff --git a/src/flask_prompt_master/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/__pycache__/__init__.cpython-312.pyc index f9cec227c49b368d1ef3efaa60c2bb03b57d01a8..dd06a17cf6d9239b3095caa0c6bb7b5a5c22d0bd 100644 GIT binary patch delta 52 zcmeCyY0}|6&CAQh00ik0=Q5XVDJ*r&CAQh00gD)7G=t9Bo1~m zXpu^`6-|={RS=LCkXr3&qf$4)!;rSZAAp1mMxybAGzqe-PYm{e#1q$XoE9lO#1F^k zeD{2x&$+($d~dT^0D59i{E$A<1Hf-;pg*RT^XLq6s(=M7%mPY#LkgnUkTv9tlo0|0 z;EbEC^kxJzxGuBzW{q6Wra_Cmmcm38^^*a|EA7A_9&Xor@ZvDRf9rEvg zdb9D_^6vW|G`6=IU*B%rUUxsOQGD*k=UesdPdq8DD9yI}#!#(QzyY;a%D@>r^^_s@ zQ#GH3n^5y8jKf46?M^Ri(6I}!3nin@qHqpxDVcQa0%UtAa~Eou&U^=o1_;<*%F+cJ z*Vz=o5v^LxI@VQJ7M(>|yZAoQX4yEaVBl=68mv0rRShjzZ3wBSx zf`yu=OtB;)p?GADo{XF-xe;$KbT>Y{QNMbzzOuS|Y32SGUq0CS7M(c78V=3{j|USG z`n7nhG>jrL@F-?``ZGS!NX zB6*#O;?C*{e)0{ZJsS-xX5?udl#U^)j=Sq0U2(UU{zt_cnu#aqnRs+OI-OA9hyssI zd+Z8M(|IPx(X?Wr=^W3NvZ`;T>9$Je<72`Zt6fpF4#qv6nEpZV+ z;05Ke#H+DjEHn|BIz{i>u&CnNw=fqEh9>E$nQ-((G!&eR&P*o+b?^vg)u^LQQ17SG zBNnphqF_b-b?^vT@Q*h0>wPBU}pDn*qBM#Qc$EAUnWzsL<{)ZSia&$ejmRZlQ<*&UdyZn-As74GobH-#c zAmM>~PmM^XVU+1SSRJX1RJ|4N#$nmv`^hmYJwIEX+;JTE4_=)rewiGT@G(TS zJ60AiFRmj!+Y~d+45_d>8cn3S56;09u!A gs76SZ@k_SzHi^tg*`=Ssdw-h-;BojDP;FE8Uwo&zB>(^b delta 829 zcmZ8fOHUI~6uvWkm$tMeMji$*t_lvrblOha_<$fmgzzXP;>2V!bMH)fbUJmWAgu}1 z1QS_dotToiachXiAK=!No2G2Y7=M6qgR(Gj<(-xlck!M3edjyp=G>gG!B_s!w_wl@ z@R6Fo*1kCEpC(&n4aahNOCYmqb6`Wt+{9q;Kz{KEMZ1Fi-HoN+{NCxu>+EvYxm6E7McC>4(DH z^y8`r$=lSXT&ZrV72|1Pv{Y%wEKTd0R?c3}ZAeU<$uJZ7Dg`S=%|KGyK;`ukh2p7F z70SsmTsekkhH|kCku(N}G&LJfWY`p4(lr4|cj20-8*=&fR#{1_Qo=lPr1z>fj7>^G z3I`zrIW{?-kW=xr496KJBXKgrNNETy@1s>=a%pMyo)vwz6Njl}n&S}5DKMUq6w8OR zooTG$bVd|296}-s88*Selqj<(B}$1@oKqMjVG$z>v5@5zgrca*g89VBn(v&M2@n2q z-D`u-hAs?NU}`b9A}r=+XJ!{xK7ezqfqxvmrl~Tm%f*d#u_$S@xL!6OUH^359C7(? z+I@_-81}(wq^Hqe?{5s&2j2%yB2+7q{oGf3aOMU>^JLRGaB9AE(R;1vYLi{9&0#ql zJ**y74|flCk2X%aW3BGVCN){Re;ST9{B?gLR1Y0JKM9Yv!plv1xi*U{uJpc6zL?j0 z@q4-pL(Hj1aIoB+?bGdzYbW%p_O0#fvkl%`s)n`-@*P?qz}#Lq;~IuD2SE_uf$s+x U{OtxrU_bcR87BJv01WN&|G}Eu!2kdN diff --git a/src/flask_prompt_master/admin/__init__.py b/src/flask_prompt_master/admin/__init__.py index d0128e7..a4bd246 100644 --- a/src/flask_prompt_master/admin/__init__.py +++ b/src/flask_prompt_master/admin/__init__.py @@ -37,7 +37,7 @@ def init_admin(app): login_manager.login_message = '请先登录' # 创建Admin实例 - admin = Admin(app, name='提示词大师后台管理', template_mode='bootstrap4') + admin = Admin(app, name='提示词大师后台管理') # 注册视图 admin.add_view(UserAdminView(User, db.session, name='用户管理', endpoint='admin_user')) diff --git a/src/flask_prompt_master/admin/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/admin/__pycache__/__init__.cpython-312.pyc index 3d2a4b91ec019185111c62708ea6bb7532bdb597..29f25b932d9b40d8372e71b1a7125590335e1496 100644 GIT binary patch delta 660 zcmZ9I&1(}u7{)Wn&h93g&nBr&+%`=V?AD5rfR+*q+7zThO7T+ZLbC28C2ckvW;ZuM zMQ?%!2R*CT1XT9o$v?nC=|Mb%dh$;Y1TV#Tw>5$T^W&N4dEfbZzWU>4{2&&K1o(J) zz2-G*g2Zj0&$u{u4S)dd}WU_+rJ zjD%s3x)1k9V+4!dxA36(I^&WwC;zB*xVnQA-ryTo@!y624c#Ns>BCFPvsP zog!)OC8Y|^knCA{X_8KpbKHB((;1TE>XW2p^8~p|lZx|1-3^Xr*)ORWnj;04moLxG zlcHPxTQLlsDinB#?gg|GdmwL18X5~d!(zvB5nb_4HR7qUpRdmg}pZbo(8t59UrhjUiAQeCqkN`9Ri+}~dx({zV zlR;?Hv$E+BBHoi3jMP0yN`QU9MUF8x?Lp6_TkKtKS!;tm1xN!jfd86$;MweVPW1}; z&q&*aH3ozMj{r@;zYCeLG?}PY!yxP0GJVSKs?X5CJ5q0>jVd?C%D`#SM%Ok-i&70b i;IF9v4gUN6XZc$-A((7GmaCRc2Hn;weZ};-_kRGd29@>z delta 670 zcmZ9I&ubGw6vsQs&hBP6Kf8%GW^J2Pu&dIowuc_t2udmxDGddGfF*1)TNBAcD*Xe!nyGnD@S~JgBDMrBccm zUzYH?{j%^ZtqP^HX4`da)3bXwI##dgnpVdjw9J9mGND}5B-3I}r)NSnmfz3kB!w2(A?{YB1$vlG?B|boUSvnOdm?(*WOK}zfy?rhN~knl*B|(v)n7DXq0qA&J52eu)9+fo-Edq6FXS?r z3qHv^F=dUHp5}Y71%1_|Z}kt!OTn)CQ6LxLc6OVbhi}Anqdm`;Lv74PQ&k36$%`l6N0w z^n2u1@K`@b)~Y-V)#1SQ8eP|7w&xl60%zq#Lx{SMnu<#OTRxPR`H+WQyXrlJ#mT3C E08j~};s5{u diff --git a/src/flask_prompt_master/admin/forms/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/admin/forms/__pycache__/__init__.cpython-312.pyc index 8be1ada9e55c4ccf75a5969b25fc189cb931789b..8107976e2a5ae0aab976bbe9cb5879b0d4aa8a10 100644 GIT binary patch delta 76 zcmX@Xw4aIhG%qg~0}!N3oXhN*$h+Uj#>FZoF)=YFF|(vNIi|QMIVLS9u{b-vpeR4L epd>ywvA86)C?+u_H#09LEx#zYIA$_Cqay&=&l?>8 delta 84 zcmdnbbb^WZG%qg~0}!N6-J8)ek$1nftA0j)ZmND!YF<`mVqQ|deqv@xak74KQL=to mPGWI(d_hruZb3mXlbV9bZtC hpIcB8pPN`*l3Em#n39{B7n7D>lv^CLc@6VsRsi)a90~vc delta 88 zcmca6bYFywvA86)C?+u_H#09LH$Npcr#NQfV>d$orAi*xtn|CNVKFCNZ<5I60=cC^;rAC$Ts?zMv>S hx1c0GH?g=RwJ0VrB{wrKCO1DNHK#acvlUxCCjcr79A5wc delta 88 zcmdlWzf+#~G%qg~0}y=py)Q$4BkxC68xQ@A{M=OiqSU;s%*4E;eEr1ClHz3j;-X~z qw4B7^?D&GB{M>?)_}s+elGGyo#FX63JpJ7Kl+>JJ{mq7K^_&2K10X#B diff --git a/src/flask_prompt_master/admin/views/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/admin/views/__pycache__/__init__.cpython-312.pyc index f33e3309ae33cd078df47466a0b0f067f14d5222..9dad4c98ef46bbc386e19d8a48cc45d7afda35fc 100644 GIT binary patch delta 77 zcmcb`e36;=G%qg~0}!N3oXfP|$m`8$WaDBLlbDzolbBgjoE%eJlpK?mlUSS`Ur>~v fTTl|8n^;_uS`?F*lADxF}ga oEhn)!JHDVOKewPHJ~y$rB(+FCF(o%MProcPwY*q=au=gJ0N3^&RsaA1 diff --git a/src/flask_prompt_master/admin/views/__pycache__/analytics_admin.cpython-312.pyc b/src/flask_prompt_master/admin/views/__pycache__/analytics_admin.cpython-312.pyc index d20c28994e3cf8e0470b5f239128218100c08478..a5c13f32d2d957b2f74e35433150ffa3a20aecff 100644 GIT binary patch delta 65 zcmewv@*#xpG%qg~0}!N3oXcdF+sOBbS;*PNDkd>8F(xsyq&PXIxF|VhvZAIiZ%krJ TZf0IgS!QZ^am;3I7C$urx2_d# delta 88 zcmewm@-u|*G%qg~0}w2qc`(C8b|c>-W@{h)jQreG{i4*otjxr`qqWs)~lK9-j;*!)N{lt{q%slCQG%qg~0}!N3oXd=o-N<*3*~r$#Dkd>8F(xsyq&PXIxF|U$Ehn)!JHDVO hKewPHJ~y$rB(*3eF(o%MFQzOrwY)fHvpUN@1prAC9R2_R delta 88 zcmccP`P7r|G%qg~0}%9P?$4Mdvytx}v$dOkMt*Lpeo<;(R%T*eQoep-W=V0fesNK< qep*gqadvz`QGRYgNqlZ%aY<^Cequ^)W}bdoW@>q{{$@FreF^}65FlXy diff --git a/src/flask_prompt_master/admin/views/__pycache__/backup_admin.cpython-312.pyc b/src/flask_prompt_master/admin/views/__pycache__/backup_admin.cpython-312.pyc index 69d9c5428ac61b4e418521ca3748a095bfc96f43..7a9bd5792569e27cb1c7997235b822ca9149ae88 100644 GIT binary patch delta 67 zcmX@GpK<$sM!wU$yj%=GkS=j9^NsIDz5rGs2N$cD#Kgpy#LSZ7s+B^J2;}Q_G8EHqT^Lj{*P%su#up delta 90 zcmdnKpYgzcM!wU$yj%=GkUDj52CvUXz5rHhPyLMi+*JLd)V!?B#Jr?@{lv_Y;$;2e sqGbKFoW$bn_=2MR+=7z$+{EIN)FS=Fl-$fb{j$u|@?!nX6Ij)w0DQ0@Hvj+t diff --git a/src/flask_prompt_master/admin/views/__pycache__/batch_admin.cpython-312.pyc b/src/flask_prompt_master/admin/views/__pycache__/batch_admin.cpython-312.pyc index b79a5511a68cd91edcb90ef107932c7e0e46f9e4..0346d798048765cfb482c7cc88c0265801252ba9 100644 GIT binary patch delta 79 zcmX@$z1^GdG%qg~0}!N3oXaeb-N^Tp*~s3-Dkd>8F(xsyq&PXIxF|U$Ehn)!JHDVO hKewPHJ~y$rB(*3eF(o%MFQzOrwY)fHvmVPNMF2Y39J2rb delta 88 zcmdn)eZZUVG%qg~0}!N6-J7vpW+UHIW@``qjQreG{i4*otjxr`qqWs)~lK9-j;*!)N{lt{q%slS gx1c0GH?g=RwJ0VrB{wrKrYtkHyf|j_PG)5V07I1=@Bjb+ delta 87 zcmccYe#f2nG%qg~0}!N6-J4;#k++c9+DktpKQ~psC^auDGchkIUq3Okq&Qi>xF}ga pEhn)!JHDVOKewPHJ~y$rB(+FCF(o%MProcPwY*q=^9E*R1pqVGA6ozb diff --git a/src/flask_prompt_master/admin/views/__pycache__/prompt_admin.cpython-312.pyc b/src/flask_prompt_master/admin/views/__pycache__/prompt_admin.cpython-312.pyc index 73f99b44d2c6c3d1a78ed88004362c501cc77ca4..b0d04876bfe24e359001da95accdab17bff8ac0c 100644 GIT binary patch delta 78 zcmeC?YvSWQ&CAQh00ik0=Q1ld@@g|1Ik;HGBqk=tBxaTrC&v^QCC8-YBo=4K7Zl~^ g7L>&2CKi{Z7R4l{*nJ<&CAQh00gO1_h#5`vyp>~RZL=HVoYLYNpW&aaZz$iT25kdc6>om her`cYd~RZKNor9{VoGjiUQAhLYI$+YW_}hS9RNw09A*Fj delta 74 zcmbP{urPt|G%qg~0}!N6-J9`1eIws7W@%6TjQreG{i4*otjxr`q`em7^<;D7&*;s^h0IS3pvj6}9 diff --git a/src/flask_prompt_master/admin/views/__pycache__/system_admin.cpython-312.pyc b/src/flask_prompt_master/admin/views/__pycache__/system_admin.cpython-312.pyc index 089f00c6dedd9925d68069d4d3f07c7e78c727be..da31312bc50cb77f7323c9242a05cd85784c99cc 100644 GIT binary patch delta 78 zcmdlize=9>G%qg~0}!N3oXdQ@kvELl$ic-bCNVKFCNZ<5I60=cC^;rAC$Ts?zMv>S gx1c0GH?g=RwJ0VrB{wrKrYtkHyf|j_JZ4cI016cw>;M1& delta 73 zcmZ1_zgeF5G%qg~0}!N6-J3CEBX1b9w5NVXer~FMQEFaRW@27azJ6k6NpZ4%aZ$4V cmXlbV9bZtC hpIcB8pPN`*l3Em#n39{B7gLs*T3#Hp`4qD*3jh(b92Nio delta 74 zcmaFI|DB)jG%qg~0}!N6-J9`;Z6jYJv$VH`em7^<;D7&4>Ier005;r88!d_ diff --git a/src/flask_prompt_master/admin/views/__pycache__/user_admin.cpython-312.pyc b/src/flask_prompt_master/admin/views/__pycache__/user_admin.cpython-312.pyc index 8318981fc3601dc6ad75095a82dcb3b649912f69..ee830fb4368be260639a81c51a54fde75912c3a5 100644 GIT binary patch delta 78 zcmZ1`I9HJOG%qg~0}!N3oXbqz$h(T!$j-$oCNVKFCNZ<5I60=cC^;rAC$Ts?zMv>S gx1c0GH?g=RwJ0VrB{wrKrYtkHyf|j_C+00I0PhwYZ2$lO delta 87 zcmbO$xJ;1uG%qg~0}!N6-J7Ahk#`ldwYz>ser~FMQEFaRW@27azJ6k6NpZ4%aZ$2< pT25kdc6>omer`cYd~RZKNotXPVoGjio_<+oYI(8#=9kP{SOE4xA5#DT diff --git a/src/flask_prompt_master/config.py b/src/flask_prompt_master/config.py index 35d8da9..c771122 100644 --- a/src/flask_prompt_master/config.py +++ b/src/flask_prompt_master/config.py @@ -1,23 +1,36 @@ import os +import warnings from dotenv import load_dotenv # 在配置类定义前加载环境变量 load_dotenv() +# 警告:此文件已弃用,请使用 config/ 目录下的配置系统 +warnings.warn("src/flask_prompt_master/config.py 已弃用,请使用新的配置系统 (config/ 目录)", DeprecationWarning) + class Config: - SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key' - - # MySQL数据库配置 - 腾讯云数据库 - SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:!Rjb12191@gz-cynosdbmysql-grp-d26pzce5.sql.tencentcdb.com:24936/pro_db?charset=utf8mb4' + SECRET_KEY = os.environ.get('SECRET_KEY') + if not SECRET_KEY: + raise ValueError("SECRET_KEY 环境变量未设置") + + # MySQL数据库配置 - 从环境变量读取 + SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') + if not SQLALCHEMY_DATABASE_URI: + raise ValueError("DATABASE_URL 环境变量未设置") + SQLALCHEMY_TRACK_MODIFICATIONS = False - + # OpenAI兼容API配置 LLM_API_URL = os.environ.get('LLM_API_URL') or 'https://api.deepseek.com/v1' - LLM_API_KEY = os.environ.get('LLM_API_KEY') or 'sk-fdf7cc1c73504e628ec0119b7e11b8cc' - + LLM_API_KEY = os.environ.get('LLM_API_KEY') + if not LLM_API_KEY: + raise ValueError("LLM_API_KEY 环境变量未设置") + # 微信小程序配置 - WX_APPID = os.environ.get('WX_APPID') or 'wx2c65877d37fc29bf' # 替换为你的小程序 appid - WX_SECRET = os.environ.get('WX_SECRET') or '89aa97dda3c1347c6ae3d6ab4627f1f4' # 替换为你的小程序 secret - - # 添加跨域支持 - CORS_ORIGINS = ['*'] # 生产环境建议设置具体域名 + WX_APPID = os.environ.get('WX_APPID') + WX_SECRET = os.environ.get('WX_SECRET') + if not WX_APPID or not WX_SECRET: + raise ValueError("WX_APPID 和 WX_SECRET 环境变量未设置") + + # 跨域配置 + CORS_ORIGINS = os.environ.get('CORS_ORIGINS', '*').split(',') diff --git a/src/flask_prompt_master/forms/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/forms/__pycache__/__init__.cpython-312.pyc index 1062be33e04e41f410846c607e2dbcc8882919ec..fa0bfa6c592caeced14e91c5c9041ffcdb0ce995 100644 GIT binary patch delta 69 zcmdnWw1$cIG%qg~0}!N3oXc#O$h%#~%*84uF)=YFF|(vNIi|QMIVLS9u{b-vpeR4L Xpd>ywvA86)C?+kxD7QFf;!hg@5#S ax1c0GH?g=RwJ0VnzbLmjX0shr0uul~+ZfXT delta 81 zcmbQrIggX~G%qg~0}wo{Ta_WPk@pXysf~U{er~FMQEFaRW@27azJ6k6NpZ4%aZ$2< jT25kdc6>omer`cYd~RZKNotXPT7FS(vHoULrUWJcS9Tn2 diff --git a/src/flask_prompt_master/models/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/models/__pycache__/__init__.cpython-312.pyc index 215fdcce7ea485276714321fdc9136644ecdc758..296c52e95294209221690d727ccc1383feb61c6d 100644 GIT binary patch delta 71 zcmaFK^ni)?G%qg~0}!N3oXgxWk@vZ-xrS bx1c0GH?g=RwJ0VxKP5G%IA-%!jy=o(pVAuw delta 68 zcmaDM@lk^JG%qg~0}!N6-J7v)BX1Fhw4;7Ter~FMQEFaRW@27azJ6k6NpZ4%aZ$4V X|q7~5NH=( diff --git a/src/flask_prompt_master/models/__pycache__/history_models.cpython-312.pyc b/src/flask_prompt_master/models/__pycache__/history_models.cpython-312.pyc index 9aed82e070fb2ba22bfa064d39edc0efe3085693..3c86416388c9377e27eec34671827c001190f878 100644 GIT binary patch delta 74 zcmexR{Jfa&G%qg~0}!N3oXh;DxsmTNyRNN^RZL=HVoYLYNpW&aaZz$iT25kdc6>om cer`cYd~RZKNor9{ZhlH?PI1g;b&ivU009^rEdT%j delta 83 zcmaD}{GpidG%qg~0}vcjf0^-FVVb~88qjQreG{i4*otjxr`qqWs)~lK9-j;*!)N{oMSN)SP1d&2k(k4FM$oACmw8 diff --git a/src/flask_prompt_master/models/__pycache__/models.cpython-312.pyc b/src/flask_prompt_master/models/__pycache__/models.cpython-312.pyc index ff1ca86880cc8e3f2f1e17e8f02a6b7b5d7bca82..91673b68b345e85bb0b59522521c79ae09496bc0 100644 GIT binary patch delta 74 zcmaD~{H&PoG%qg~0}!N3oXc!f*vR*XP1n@LDkd>8F(xsyq&PXIxF|U$Ehn)!JHDVO cKewPHJ~y$rB(*3eH$Npcr#NP_1N(X-0Omm(v;Y7A delta 83 zcmaD>{Jxm)G%qg~0}$kz&B?qazme|`o0*+{Mt*Lpeo<;(R%T*eQoep-W=V0fesNK< lep*gqadvz`QGRYgNqlZ%aY<^Cer|qBYEH5KW^?xSMgaFb9_Ro7 diff --git a/src/flask_prompt_master/models/__pycache__/poetry_favorites.cpython-312.pyc b/src/flask_prompt_master/models/__pycache__/poetry_favorites.cpython-312.pyc index 9160c12090465d04f1ff1ed2d2d29f5107fd9848..24f7cde5584b6f0830c46aedaa8ffd54092f1a0a 100644 GIT binary patch delta 73 zcmZ3jzDS+-G%qg~0}!N3oXf1)$h(4D*WSe{CNVKFCNZ<5I60=cC^;rAC$Ts?zMv>S bx1c0GH?g=RwJ0VxKP5G%IA-%}?gQ)qdzl)& delta 82 zcmZ3azFM94G%qg~0}w>(oXIfV$h(5u%tJpTKQ~psC^auDGchkIUq3Okq&Qi>xF}ga kEhn)!JHDVOKewPHJ~y$rB(+FCH$Npcr&xdUBklw209wi&WdHyG diff --git a/src/flask_prompt_master/routes/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/__init__.cpython-312.pyc index b9286c9a9c4e4aa7a9095a4d83f7e02d40348531..d61960b28da8585f5678e41847c1612d1bda71df 100644 GIT binary patch delta 70 zcmZ3>w1kQGG%qg~0}!N3oXaeq$h%J0+{G#;F)=YFF|(vNIi|QMIVLS9u{b-vpeR4L Ypd>ywvA86)D5faCv?R4SX5vR103b%7 delta 79 zcmZ3&w3dnYG%qg~0}wo{Ta}SNk$0V$gMLPSZmND!YF<`mVqQ|deqv@xak74KQL=to hPGWI(d_hruZb3mXlbV9bZtC cpIcB8pPN`*l3El~lwVqsS{$?am8iNh0Gw(X%m4rY delta 83 zcmeAunpnhlnwOW00SFk+&dm(h-N?60)XY^sBR@A)zbG{?D>E@KDPKP^v!pm#zqlw_ lKP@M*I6JxFoemzbL=7B(+$7^FvW}WdNGp9pC@} diff --git a/src/flask_prompt_master/routes/__pycache__/auth.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/auth.cpython-312.pyc index cf475acd0fa06772a3ffbc8c6372c07c848f333a..22ce4c7e306dca64f877edeb8fdbe2905c21a5b7 100644 GIT binary patch delta 74 zcmbQ~Gr@=NG%qg~0}!N3oXc#J-pDtRMc3HHDkd>8F(xsyq&PXIxF|U$Ehn)!JHDVO cKewPHJ~y$rB(*4}D8IBMwK!(;RTdXT0E+M$e*gdg delta 69 zcmbQ>Gt-CfG%qg~0}!N6-J7vZY9rr77HJ#(jQreG{i4*otjxr`q(G%qg~0}!N3oXcFTvXO6=fUbj!RZL=HVoYLYNpW&aaZz$iT25kdc6>om cer`cYd~RZKNor9{QGRJjYH`fwdjf7!0H`M$2><{9 delta 83 zcmbOowj_-2G%qg~0}vGaT$H&{c_ZH}0W(kijQreG{i4*otjxr`qqWs)~lK9-j;*!)N{i6KRlGI}T%~u87qyW-R9<~4g diff --git a/src/flask_prompt_master/routes/__pycache__/expert_generate_3.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/expert_generate_3.cpython-312.pyc index 877eeecde1d3286ea08ad014508ca1d7aa5ef5d4..b70949d1fb4899d991516e03bbc914b7c30e8588 100644 GIT binary patch delta 74 zcmcbTa5{nSG%qg~0}!N3oXeC~-^gbysO#Wj6_c2l7?YS;Qk)!9T$CJ>mXlbV9bZtC cpIcB8pPN`*l3El~lwVqsS{$>vT=1?O0F@mY!vFvP delta 83 zcmX?|a3z87G%qg~0}wQYFUjOn+sJ1uXy&P(k)NBYUzD1cm6@2Al&_zdSyG&=UtE-| lpO%wYoE=|Kl%HEr5}%t`T#{O(UzA^3l3J|4IZyDe8~~2Z9m@a! diff --git a/src/flask_prompt_master/routes/__pycache__/favorites.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/favorites.cpython-312.pyc index 363fe3ae51bc79229559d127b2215ff2bf61ab79..49abde3e8e56b9c3a05dafa0003436ff11295b8e 100644 GIT binary patch delta 73 zcmeCyXwu+4&CAQh00ik0=Q5i&@}6PRwQ#YDNlZ+PNz5!MPL3%qN{&g(Ni5EeFDS~- bEhvf4O)M@+Es811FD*$ej@iu5{6_!)ZXX&M delta 82 zcmZqD=+@vp&CAQh00gO1_hu+=tYp?n3x!om|0Ss98+AB95b1bRhT2D QD8IBMwK!(84C_lr0AzX;T>t<8 delta 85 zcmey<%h=k-$ak8Tmx}=iYL#AQ)Y)$2yTM}Srk|0Yo2p-wnwOQCn3t5VpO{%voUC75 nl&qhYlUSS`Ur>~vTTl|8n^;_uTBKi;Us{q{tiM^9^`#>K?>!#) diff --git a/src/flask_prompt_master/routes/__pycache__/meal_planning.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/meal_planning.cpython-312.pyc index 36332ed4acc02b9381427c0e8ea4d7a5f32bed39..2309f193b633d07622cc531f8d5f2bea59907c4a 100644 GIT binary patch delta 60 zcmaD&&fE@KDPKP^v!pm#zqlw_ XfAU3BVGjMG{L+%tV*Sm=Y-&aTD;5_) diff --git a/src/flask_prompt_master/routes/__pycache__/meeting_minutes.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/meeting_minutes.cpython-312.pyc index 5d27117b149df8f17c7cde9edcf87c965295bc01..eeaad7be113be832dccd517c493e13d8c7d5608c 100644 GIT binary patch delta 74 zcmZn)`5DZ2nwOW00SMA1&SgeRZsgm^p=;-26_c2l7?YS;Qk)!9T$CJ>mXlbV9bZtC cpIcB8pPN`*l3El~lwVqsS{$?aF9)k40H<^s*8l(j delta 83 zcmewv+!VrhnwOW00SH9R=VV@x*vPk&!^~YjBR@A)zbG{?D>E@KDPKP^v!pm#zqlw_ lKP@M*I6JxFoemzbL=7B(+$7^A`?QMF5}d9nb&( diff --git a/src/flask_prompt_master/routes/__pycache__/placeholder_apps.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/placeholder_apps.cpython-312.pyc index 171b81d24813b21201e6f86d4837583fbdfefb8a..52c1c811ff6aee39453d822cfc737aebb16f80cf 100644 GIT binary patch delta 62 zcmbO+m$82?Bj0IWUM>b8NS8R5>F&Id&qGhh-o+{=F)=YFF|(vNIi|QMIc9R9o-jvD QQGRJjYH`fw9z7lf08I`P)Bpeg delta 85 zcmeC5%Q#~$Bj0IWUM>b85Ij9MQ`%`GpNF2AhkizWZmND!YF<`mVqQ|deqv@xak74K nQL=toPGWI(d_hruZb3}Jst%Brtlqz diff --git a/src/flask_prompt_master/routes/__pycache__/poetry.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/poetry.cpython-312.pyc index 1d25b90338319275a1bf023fef55e43fabb11f69..9b0f30941c33d167000af41f6ed2fdf68c3d9f2f 100644 GIT binary patch delta 76 zcmaFV!g#ZVk?%AwFBbz4q)VL36tLOIw?;(Q)Ws?$F)=YFF|(vNIi|QMIVLS9u{b-v epeR4Lpd>ywvA86)D5faCv?R4SX7dM;B3%H_{~N#n delta 85 zcmccF!uY6#k?%AwFBbz4r0JZ=D74zhw?@RwPCp|*H&wqVH7_eOF)t}!KQXhUI9b2A nC|N%(C$Ts?zMv>Sx1c0GH?g=RwMf4xzqBN^Sby_#ks@6H<*XkW diff --git a/src/flask_prompt_master/routes/__pycache__/prompt_optimization.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/prompt_optimization.cpython-312.pyc index 09cddd35a32dd4bd8ba5ea59d1d44d63a1fdd456..21d38ce0ddd7c0dc37404ee73b9bb9f52d8e1280 100644 GIT binary patch delta 74 zcmZ3YH(QVIG%qg~0}!N3oXgY{*vQAkuIuDt6_c2l7?YS;Qk)!9T$CJ>mXlbV9bZtC cpIcB8pPN`*l3El~lwVqsS{$?4jr|@!08SSfZ~y=R delta 83 zcmbQOw?vQcG%qg~0}woOn3H*geS bx1c0GH?g=RwJ4@2zqBN^IA-&4uBS=>nNAy9 delta 82 zcmZ1+y(XIXG%qg~0}$Lbo0G}7k++4*%v(PrKQ~psC^auDGchkIUq3Okq&Qi>xF}ga kEhn)!JHDVOKewPHJ~y$rB(+GtD8IBMwOD`iKCY)q0D#{f4*&oF diff --git a/src/flask_prompt_master/routes/__pycache__/routes.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/routes.cpython-312.pyc index cfb41e5182490013b737458fdb9215d9760348fc..bdee28b3f7d5e4324e58393d443f2995fd68b966 100644 GIT binary patch delta 62 zcmcaQjrq(pX1>$Byj%=GkS=j9bIIY2d>mXtrY=@7iHV6ZiJ2wE$uY%6$uW}+xr8}l Ritzjrr;{X1>$Byj%=Gu>bX<%<_F3`8c@D?DRA8b5r$;QuDGh6Z4Yt^%FBoij(z= oi<0%zauSQP;|q%Na|=r1a}$e8Qj7G9@=Hrni}g1mXlbV9bZtC gpIcB8pPN`*l3El~lwVqsS{yTZpNiz>JU)I202!lJf`1m9Mm+Ke^ diff --git a/src/flask_prompt_master/routes/__pycache__/travel_planning.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/travel_planning.cpython-312.pyc index 1c662488186eff76018099cc2c6b27861d70f04d..23bffcd8fe79e6ddcc2cf634a3085e1206622893 100644 GIT binary patch delta 74 zcmeyF`yrR_G%qg~0}!N3oXg};-pFUprEBM66_c2l7?YS;Qk)!9T$CJ>mXlbV9bZtC cpIcB8pPN`*l3El~lwVqsS{$>vnyXF+0IAm+vj6}9 delta 83 zcmey6`!kpCG%qg~0}xEsoRjIPw2{x8%gkLrBR@A)zbG{?D>E@KDPKP^v!pm#zqlw_ lKP@M*I6JxFoemzbL=7B(+$7a}iga4gj$)9q0f6 diff --git a/src/flask_prompt_master/routes/__pycache__/weekly_report.cpython-312.pyc b/src/flask_prompt_master/routes/__pycache__/weekly_report.cpython-312.pyc index 70898c5040a26675828ce6a0840d1262e382af86..f1cb04b6b5baaa4c5b1eb711dfbe8cfec3b176c2 100644 GIT binary patch delta 74 zcmZn;{uRV`nwOW00SMA1&ShpxZseQIp=;w}6_c2l7?YS;Qk)!9T$CJ>mXlbV9bZtC cpIcB8pPN`*l3El~lwVqsS{$?aKF1OT0HrY-M*si- delta 83 zcmewr)EvxrnwOW00SL}1&&j+av5{{!hncH>Mt*Lpeo<;(R%T*eQoep-W=V0fesNK< lep*gqadvz`QGRYgNqlZ%aY<^Ceo=mDNoukF=4%{F6adLX9^n80 diff --git a/src/flask_prompt_master/services/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/services/__pycache__/__init__.cpython-312.pyc index c403d90a4eae454713d00edb1bd89360ac776633..2d20371189a31c54c651b666e05ce381ee3d5fc3 100644 GIT binary patch delta 72 zcmey(_=%DCG%qg~0}!N3oXb2hk+)Xg(#0w!F)=YFF|(vNIi|QMIVLS9u{b-vpeR4L apd>ywvA86)D5f~Is4O!%wK!(tAxi*>&>H^$ delta 81 zcmeyw_?waUG%qg~0}wo{Ta~eIB5$pQlYT~iZmND!YF<`mVqQ|deqv@xak74KQL=to jPGWI(d_hruZb3u#GRG^tFIoK diff --git a/src/flask_prompt_master/services/__pycache__/auth_service.cpython-312.pyc b/src/flask_prompt_master/services/__pycache__/auth_service.cpython-312.pyc index 38f6ac7eb1c4dfe1e87e3d785f85670458885360..f26f4a99d9fd89d32b276c5369dbe4c731417692 100644 GIT binary patch delta 3414 zcmb7GeNa@_6~Fg=?OXN>++F#Q<$h1shjqgt#y>Ro*{>hg{Z;kfeICo+4+oO{|KR@--$r~4s-F)@+TcdqbubsJh zWO%Cg?2TVuq(XCx*4ZAuHTp_aii z?WG=tVTr7?nn?~n&-K_*$%D+i?t0|mJId)dliwYhJpD5L-5ff6YxIr(6VJY>!IRT* zzIbe^?{HmBi3Vi5FLs1?6_t79sN~<*(x&>EHY)A$>3iDuM-99E`*dG09F-*a@H7c-gtciA0b7$DE$2;|_I&dYM7R^FF z<%_zVw5bOuu>CP7_m}<2H189a`*_pqO~czJTqV8UkDT)ccMR+ps(feJ*~+&oCze!C zIBR;>T(_qWRt!`OrB2vASInM!5^~HNTrsd>NFH8#!gft59al=v877of6ZWcW_VwfT z^%M5GE9Sa51Eyn4HVH?}X)p&+z@%;qB{+xVi%K_R%FM=6^9)nW)R{7cn`TP65j~MB zd;~v%O~OMYf*_G~vMnRRM}!2IC{t#b)S5(@;&gKdspI4OJ%vf-oDA~oImT|r>w1)n z!V>+Al{}>J7;Q(L{C;$R-;VZUkI<1rO`rd?@3Yf~XNh&>H04b^DJOr>mmrV^>9xjV z&{Aj}Cy$|JkH2LvWskA;K#RXU9BA98!6s{S;k?jNDR@K;LLRjNo&0K3f+<=$cw~Ud zJZ)m!(IN1_8M;4Uw6Y;)K0BCE)e+uPA5Z&*U$oIgM*6oXPp;V?yVT&gF>#J8}8)JVm+ zl!T>xY$ivg(M*`Whl@&~w&p<4uRR5;fwPOHPuQ>+KSSO!EWqZG4-7657m|ONUAUMS zE%~^NEVj6%Lh7p(lSa#P#Y;gfp%686&?B-bplZ+1R)>|s)X4DU%YBnSdi%3?e!M)} z>zS)5(eS+ggBU0pKdrWPk+#Y)O?M!OXPh0BQh$o!UBp4FFFbngvetg7ZcS9w9!{bT+~k zP;aI1@Jacm(`6-~n@3L`I4S3o-#Is?JCtkoqH%lCaNwNdV%GVr_Z*j%_m!*m?PS^9 zUldB{ti47;mrTWgD^@4bYD_ZL%KVsZVJ**(RbVRrmKST~k<`=&coW3$`GYC$?M3cT zkz37nKfByrx7=Ot^%%d*s#v_LX&)Xg9@;HLP5&B;YLwsY4}YaTqB3REu5cjak4K9I ziq~ps_u6cTU?*me1v*9(<92f=rT6r)Kr9(fd|@OvqhBz61HNV~DJQ?m%E!yeRMw98 zwl{)_ah2^jBmFED*q#=H3rhsXsa4Q?JQZ@mWp!xh-w8>6y z6q!88wb`8I;uE7*EmWOOZ{#W*8gG>A<0_iL5fKjU@Tiw~FhoVis=gx4je1prCk||#3OJLN! z*ecR|)8SzVNta3fUC086Wu z(CXbnV@(nN?$U)d1^n22Oy#ixk)nt9dNnxCJ%X1O`l_zWU)epov}{-(J9`)%8TGb- zZacsW06PJ80l*`YJ#E+>89%omd=~oG?@;JL9}3DRV#;lf6VvYUNSYG^DJE0tHfI#Q zm?`BLlVfv delta 2616 zcmb7Ge@t7)9lv|O>}MMunDWB}Y=SZ70l^URlaSJk010iKAEd3q)-d2Xu@f72_smGB zNz*Bck}Xn_UaBT*)}&jyrOTSNBWk*+T^lu3Cry(=(M0#QZvCS`qiGvmCr#QqY4^Ps zXojY3Jz1ao-uLdl?{nWDcYeC}SWoURa&laVwb;{d#D5q*m0NHSpXXd^}0?S--WN9`h)RMj^R9vFWYLS zk4c7l7%hz5Z0x#g>|x_v!+qC|9H#NywIcU`L)Yk4yn^nNRb>-1{0yQAmtQjQWlV3C zmeQ?7&PRHXE)09wZe1)6{FjKtHaScJre_9ps=2GWuKM8+J9m}D?QzgA!1ikLC-^~7MzjL;*(+G>sM zF_$nng#N0aJnxCoW20v(zjbg*TRNdFoz#N2oI#?|3Bji%*(%O9KwlD_bkbko0oF{* z8e{)YH)p?_voB$~kKTB5_Vgv2_w+X}O#k=@`^{c>a#SA9>|VA;mn=uT-;5^{1D2RF zR$5AIXfSQWER`L{NbHH38C|fPkM*18NSYXyWcDXBCd8UV{?_Vuy=Tg@0Lsq{c186!ckut3M}Zo)NmtGgO& z<0I~JIZ(-_c@S@Z7dker>8$J_TvURTU@EsGIOMvY9*1zjUe(9EG7>VYZ&Mv zS#T(c(xH;T6YF8_UVt`$wE#{4AHYfg?hg^9`vBGf$N(Dv+5!Ier%4B_>jdaxpvyMX zZf-mZ>IVU~FfhS*1vCQwvgBlXPhw~^f5UJl-eVVQ16O5XaggQgAvC81=~myCrGeTh z|LO_<>etk_R=nGGqixdPb9Br5n*T!84;r3tcu#AjulZiBbD?Vm8(rvzyBVsCK|7N)J~3vV2W1)&kJ5ypC=5D zd^IfL#l|y_Wi%rHJz*AQgWIORC~sGAL;Ose!DKhU{QwUD@N>GE#LhY2*xj{17{NdL z-ld=*#Gww`=^sNKpVy(3m9pYq58Jh<@j9g2s@D|AV@g&wWdmmwLp&$+po~J>a?0Q( z62=_#vrwQ$$SypNW6rEIEA}b#=CTepf((X6n~G|%NPCOA=z*|D^V?d4s#v9ssjS=s zv{dtJ*l=Wm^K)61ei$xpR1d1G+?`{rAHgGNzqk{PU|k&s>L0y%W#;rx?Z=~&*s-JG zn(jU?0Um@GHILhWDrJ5@@>}r>#mGfk>91-kiXk4BE1fj@?2C}tv3W`_E#wh#vHAIM z@Q0~EZ_52MQ<~m8rCLr?dU$DRXv(*I!nge8*0=6?H*g~`>DzX+`+d!KX2;Obfe4jDz>S8oX1okCein7N3 zSX`@ZeZs!~nU*Yi7`B3LJHR6VI|055kPDyz!2M%ihu}zXz4==PhtaR4z=v}FCxReX zeJUcwI|tI7lS!cK#tX{sVthv}$+dU1Oq%o1i*=p(A^Cy%r6A5l=|Ae4>jUz3Tl1I9sU42Q}?@`SMsQLr6 R>TgoJgtz0rAl~s0{0qYKRW1Mk diff --git a/src/flask_prompt_master/services/__pycache__/favorite_service.cpython-312.pyc b/src/flask_prompt_master/services/__pycache__/favorite_service.cpython-312.pyc index b7c725ec9d03d329872fdb7f4be67d22b7248ee5..a7b3d846886733c855df841c10c004f6d48a6c29 100644 GIT binary patch delta 74 zcmaFpa>Ir9G%qg~0}!N3oXfnvkynOE-_gY?CNVKFCNZ<5I60=cC^;rAC$Ts?zMv>S cx1c0GH?g=RwJ4@IwWusJIkh-uaUzof0J!QJ!vFvP delta 69 zcmccN^3a9%G%qg~0}!N6-J8L@kynOE+DktpKQ~psC^auDGchkIUq3Okq&Qi>xF}hF X@fb}WqVG%qg~0}!N3oXb3+x{=R{Nyx*+Dkd>8F(xsyq&PXIxF|Vh@Wc0P>nG%qg~0}w>(oXI$+vXRe<$s$lcBR@A)zbG{?D>E@KDPKP^v!pm#zqlw_ nKP@M*I6JxFoemzc{t1EHgQ^SbuXl(|HX5=i(mv diff --git a/src/flask_prompt_master/services/auth_service.py b/src/flask_prompt_master/services/auth_service.py index 20a14b8..ff95979 100644 --- a/src/flask_prompt_master/services/auth_service.py +++ b/src/flask_prompt_master/services/auth_service.py @@ -5,6 +5,7 @@ import hashlib import os import re +import bcrypt from datetime import datetime, timedelta from src.flask_prompt_master import db from src.flask_prompt_master.models.models import User @@ -14,13 +15,20 @@ class AuthService: @staticmethod def generate_salt(): - """生成随机盐值""" - return os.urandom(16).hex() - + """生成随机盐值(为兼容性保留,新用户使用bcrypt)""" + return 'bcrypt' # 新用户使用bcrypt,标识为'bcrypt' + @staticmethod def hash_password(password, salt): - """使用盐值加密密码""" - return hashlib.md5((password + salt).encode('utf-8')).hexdigest() + """加密密码:新用户使用bcrypt,旧用户保持MD5""" + if salt == 'bcrypt': + # 使用bcrypt哈希密码 + password_bytes = password.encode('utf-8') + hashed = bcrypt.hashpw(password_bytes, bcrypt.gensalt()) + return hashed.decode('utf-8') + else: + # 旧MD5哈希方式(向后兼容) + return hashlib.md5((password + salt).encode('utf-8')).hexdigest() @staticmethod def validate_password(password): @@ -28,6 +36,21 @@ class AuthService: if len(password) < 6: return False, "密码长度至少6位" return True, "密码格式正确" + + @staticmethod + def check_password(password, hashed_password, salt): + """验证密码:支持bcrypt和MD5""" + if salt == 'bcrypt': + # 使用bcrypt验证 + try: + password_bytes = password.encode('utf-8') + hashed_bytes = hashed_password.encode('utf-8') + return bcrypt.checkpw(password_bytes, hashed_bytes) + except Exception: + return False + else: + # 使用MD5验证 + return hashlib.md5((password + salt).encode('utf-8')).hexdigest() == hashed_password @staticmethod def validate_email(email): @@ -135,8 +158,7 @@ class AuthService: return {'success': False, 'message': '账户已被禁用'} # 验证密码 - hashed_password = AuthService.hash_password(login_pwd, user.login_salt) - if hashed_password != user.login_pwd: + if not AuthService.check_password(login_pwd, user.login_pwd, user.login_salt): return {'success': False, 'message': '用户名或密码错误'} # 更新最后登录时间 @@ -245,8 +267,7 @@ class AuthService: return {'success': False, 'message': '用户不存在'} # 验证旧密码 - old_hashed = AuthService.hash_password(old_password, user.login_salt) - if old_hashed != user.login_pwd: + if not AuthService.check_password(old_password, user.login_pwd, user.login_salt): return {'success': False, 'message': '原密码错误'} # 验证新密码 diff --git a/src/flask_prompt_master/utils/__pycache__/__init__.cpython-312.pyc b/src/flask_prompt_master/utils/__pycache__/__init__.cpython-312.pyc index 4b512d74d2f84102210f9909e178cb87216aad45..48ef0af8a8b35ce4479b39a9bf4ee28090425e72 100644 GIT binary patch delta 69 zcmeyt_@0sXG%qg~0}!N3oXb2hk+)XI%*84uF)=YFF|(vNIi|QMIVLS9u{b-vpeR4L Xpd>ywvA86)D5kU|Gp9Ia;(kj2IB*%g delta 78 zcmaFQ_=A!6G%qg~0}wo{Ta~eIB5$p!y?#c1ZmND!YF<`mVqQ|deqv@xak74KQL=to gPGWI(d_hruZb3~v aTTl|8n^;_uS`<@Sl9^K+vw0cQTLA!3su~jj delta 81 zcmeBDpRCS%nwOW00SFdn?$1cv$eY4s>ZPBNpPQ;*l$w{7nV6T9ub-G%Qk<+`T$HSz jmXlbV9bZtCpIcB8pPN`*l3Ju+T9TPltiO3K(^~-mM?)PV diff --git a/test_config.py b/test_config.py new file mode 100644 index 0000000..7c95d95 --- /dev/null +++ b/test_config.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +测试新的配置系统 +""" + +import os +import sys +from dotenv import load_dotenv + +# 加载测试环境变量 +env_file = '.env.test' +if os.path.exists(env_file): + load_dotenv(env_file) + print(f"[OK] 已加载环境变量文件: {env_file}") +else: + print(f"[WARN] 环境变量文件不存在: {env_file}") + print("正在检查默认环境变量...") + load_dotenv() + +def test_config_system(): + """测试配置系统""" + print("\n[TEST] 测试配置系统...") + + try: + # 导入新的配置系统 + from config import get_config + + # 获取配置 + config_class = get_config() + print(f"[OK] 获取配置类: {config_class.__name__}") + + # 检查环境变量 + env = os.environ.get('FLASK_ENV', 'development') + print(f"[OK] 当前环境: {env}") + + # 创建配置实例 + config = config_class() + print(f"[OK] 配置实例创建成功") + + # 检查关键配置 + print(f"[OK] SECRET_KEY: {'已设置' if config.SECRET_KEY else '未设置'}") + print(f"[OK] DATABASE_URL: {'已设置' if config.SQLALCHEMY_DATABASE_URI else '未设置'}") + print(f"[OK] LLM_API_KEY: {'已设置' if config.LLM_API_KEY else '未设置'}") + + return True + + except Exception as e: + print(f"[ERROR] 配置系统测试失败: {str(e)}") + import traceback + traceback.print_exc() + return False + +def test_old_config_compatibility(): + """测试旧配置文件的兼容性""" + print("\n[TEST] 测试旧配置文件兼容性...") + + try: + # 测试旧的config.py + import warnings + + # 捕获警告 + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + + # 导入旧的config.py(会触发警告) + from config import Config as OldConfig + + if w: + print(f"[OK] 检测到弃用警告: {w[0].message}") + else: + print("[WARN] 未检测到弃用警告(可能有问题)") + + # 尝试创建实例 + try: + old_config = OldConfig() + print(f"[OK] 旧配置类可实例化") + return True + except ValueError as e: + print(f"[OK] 旧配置类按要求抛出错误(正常): {e}") + return True + + except Exception as e: + print(f"[ERROR] 旧配置兼容性测试失败: {str(e)}") + return False + +def test_app_factory(): + """测试应用工厂""" + print("\n[TEST] 测试应用工厂...") + + try: + from src.flask_prompt_master import create_app + + # 创建应用(应该使用新的配置系统) + app = create_app() + print(f"[OK] 应用创建成功") + + # 检查应用配置 + print(f"[OK] 应用调试模式: {app.config.get('DEBUG', '未设置')}") + print(f"[OK] 数据库URI: {app.config.get('SQLALCHEMY_DATABASE_URI', '未设置')[:50]}...") + + return True + + except Exception as e: + print(f"[ERROR] 应用工厂测试失败: {str(e)}") + import traceback + traceback.print_exc() + return False + +def main(): + """主测试函数""" + print("=" * 60) + print("aitsc 项目配置系统测试") + print("=" * 60) + + # 显示当前工作目录 + print(f"工作目录: {os.getcwd()}") + + # 检查环境变量文件 + env_files = ['.env', '.env.test', 'env.example'] + for env_file in env_files: + if os.path.exists(env_file): + print(f"[OK] 找到环境变量文件: {env_file}") + else: + print(f"[WARN] 未找到环境变量文件: {env_file}") + + # 运行测试 + tests = [ + ("配置系统", test_config_system), + ("旧配置兼容性", test_old_config_compatibility), + ("应用工厂", test_app_factory), + ] + + results = [] + for test_name, test_func in tests: + success = test_func() + results.append((test_name, success)) + + # 汇总结果 + print("\n" + "=" * 60) + print("测试结果汇总") + print("=" * 60) + + all_passed = True + for test_name, success in results: + status = "[OK] 通过" if success else "[ERROR] 失败" + print(f"{test_name}: {status}") + if not success: + all_passed = False + + print("\n" + "=" * 60) + if all_passed: + print("[SUCCESS] 所有测试通过!项目可以正常运行。") + print("\n下一步操作:") + print("1. 复制 .env.example 为 .env") + print("2. 在 .env 中填写实际的环境变量值") + print("3. 删除或备份旧的 .env 文件(包含硬编码密码)") + print("4. 运行 python run_dev.py 启动应用") + else: + print("[WARN] 部分测试失败,需要进一步检查。") + + return all_passed + +if __name__ == '__main__': + success = main() + sys.exit(0 if success else 1) \ No newline at end of file