From 2cb7ce5c6680839f4c46be7d97488bf648b0d4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B3=A2=E6=BE=9C=E5=A3=AE=E9=98=94?= <263303411@qq.com> Date: Sun, 17 Aug 2025 18:52:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=87=8D=E6=9E=84=EF=BC=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cursor/rules/5sguize.mdc | 2 +- .../typing_extensions.cpython-312.pyc | Bin 139361 -> 139361 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 461 -> 461 bytes .../__pycache__/_utilities.cpython-312.pyc | Bin 2688 -> 2688 bytes .../blinker/__pycache__/base.cpython-312.pyc | Bin 21931 -> 21931 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 2700 -> 2700 bytes .../click/__pycache__/_compat.cpython-312.pyc | Bin 27411 -> 27411 bytes .../__pycache__/_winconsole.cpython-312.pyc | Bin 11946 -> 11946 bytes .../click/__pycache__/core.cpython-312.pyc | Bin 135661 -> 135661 bytes .../__pycache__/decorators.cpython-312.pyc | Bin 24697 -> 24697 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 14847 -> 14847 bytes .../__pycache__/formatting.cpython-312.pyc | Bin 14021 -> 14021 bytes .../click/__pycache__/globals.cpython-312.pyc | Bin 3079 -> 3079 bytes .../click/__pycache__/parser.cpython-312.pyc | Bin 21451 -> 21451 bytes .../click/__pycache__/termui.cpython-312.pyc | Bin 32756 -> 32756 bytes .../click/__pycache__/types.cpython-312.pyc | Bin 49452 -> 49452 bytes .../click/__pycache__/utils.cpython-312.pyc | Bin 26327 -> 26327 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 450 -> 450 bytes .../colorama/__pycache__/ansi.cpython-312.pyc | Bin 3903 -> 3903 bytes .../__pycache__/ansitowin32.cpython-312.pyc | Bin 16370 -> 16370 bytes .../__pycache__/initialise.cpython-312.pyc | Bin 3508 -> 3508 bytes .../__pycache__/win32.cpython-312.pyc | Bin 8093 -> 8093 bytes .../__pycache__/winterm.cpython-312.pyc | Bin 9046 -> 9046 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 2440 -> 2440 bytes .../flask/__pycache__/app.cpython-312.pyc | Bin 62378 -> 62378 bytes .../__pycache__/blueprints.cpython-312.pyc | Bin 4960 -> 4960 bytes .../flask/__pycache__/cli.cpython-312.pyc | Bin 43339 -> 43339 bytes .../flask/__pycache__/config.cpython-312.pyc | Bin 16169 -> 16169 bytes .../flask/__pycache__/ctx.cpython-312.pyc | Bin 19787 -> 19787 bytes .../flask/__pycache__/globals.cpython-312.pyc | Bin 1825 -> 1825 bytes .../flask/__pycache__/helpers.cpython-312.pyc | Bin 25396 -> 25396 bytes .../flask/__pycache__/logging.cpython-312.pyc | Bin 3230 -> 3230 bytes .../__pycache__/sessions.cpython-312.pyc | Bin 17093 -> 17093 bytes .../flask/__pycache__/signals.cpython-312.pyc | Bin 1182 -> 1182 bytes .../__pycache__/templating.cpython-312.pyc | Bin 9867 -> 9867 bytes .../flask/__pycache__/typing.cpython-312.pyc | Bin 3948 -> 3948 bytes .../__pycache__/wrappers.cpython-312.pyc | Bin 10013 -> 10013 bytes .../json/__pycache__/__init__.cpython-312.pyc | Bin 6653 -> 6653 bytes .../json/__pycache__/provider.cpython-312.pyc | Bin 9220 -> 9220 bytes .../json/__pycache__/tag.cpython-312.pyc | Bin 13915 -> 13915 bytes .../sansio/__pycache__/app.cpython-312.pyc | Bin 33647 -> 33647 bytes .../__pycache__/blueprints.cpython-312.pyc | Bin 31144 -> 31144 bytes .../__pycache__/scaffold.cpython-312.pyc | Bin 30184 -> 30184 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 1592 -> 1592 bytes .../__pycache__/_json.cpython-312.pyc | Bin 1146 -> 1146 bytes .../__pycache__/encoding.cpython-312.pyc | Bin 2646 -> 2646 bytes .../__pycache__/exc.cpython-312.pyc | Bin 3906 -> 3906 bytes .../__pycache__/serializer.cpython-312.pyc | Bin 15374 -> 15374 bytes .../__pycache__/signer.cpython-312.pyc | Bin 11251 -> 11251 bytes .../__pycache__/timed.cpython-312.pyc | Bin 8695 -> 8695 bytes .../__pycache__/url_safe.cpython-312.pyc | Bin 3496 -> 3496 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 1617 -> 1617 bytes .../__pycache__/_identifier.cpython-312.pyc | Bin 2098 -> 2098 bytes .../__pycache__/async_utils.cpython-312.pyc | Bin 4938 -> 4938 bytes .../__pycache__/bccache.cpython-312.pyc | Bin 19289 -> 19289 bytes .../__pycache__/compiler.cpython-312.pyc | Bin 103856 -> 103856 bytes .../__pycache__/defaults.cpython-312.pyc | Bin 1570 -> 1570 bytes .../__pycache__/environment.cpython-312.pyc | Bin 76599 -> 76599 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 7679 -> 7679 bytes .../__pycache__/filters.cpython-312.pyc | Bin 72461 -> 72461 bytes .../__pycache__/idtracking.cpython-312.pyc | Bin 19084 -> 19084 bytes .../jinja2/__pycache__/lexer.cpython-312.pyc | Bin 32029 -> 32029 bytes .../__pycache__/loaders.cpython-312.pyc | Bin 32239 -> 32239 bytes .../jinja2/__pycache__/nodes.cpython-312.pyc | Bin 58183 -> 58183 bytes .../__pycache__/optimizer.cpython-312.pyc | Bin 2653 -> 2653 bytes .../jinja2/__pycache__/parser.cpython-312.pyc | Bin 61144 -> 61144 bytes .../__pycache__/runtime.cpython-312.pyc | Bin 48848 -> 48848 bytes .../jinja2/__pycache__/tests.cpython-312.pyc | Bin 9014 -> 9014 bytes .../jinja2/__pycache__/utils.cpython-312.pyc | Bin 34762 -> 34762 bytes .../__pycache__/visitor.cpython-312.pyc | Bin 5317 -> 5317 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 20917 -> 20917 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 304 -> 304 bytes .../__pycache__/_internal.cpython-312.pyc | Bin 9727 -> 9727 bytes .../__pycache__/_reloader.cpython-312.pyc | Bin 20517 -> 20517 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 33288 -> 33288 bytes .../__pycache__/formparser.cpython-312.pyc | Bin 16985 -> 16985 bytes .../werkzeug/__pycache__/http.cpython-312.pyc | Bin 50176 -> 50176 bytes .../__pycache__/local.cpython-312.pyc | Bin 28428 -> 28428 bytes .../__pycache__/security.cpython-312.pyc | Bin 7095 -> 7095 bytes .../__pycache__/serving.cpython-312.pyc | Bin 46053 -> 46053 bytes .../werkzeug/__pycache__/test.cpython-312.pyc | Bin 59776 -> 59776 bytes .../werkzeug/__pycache__/urls.cpython-312.pyc | Bin 8228 -> 8228 bytes .../__pycache__/user_agent.cpython-312.pyc | Bin 2117 -> 2117 bytes .../__pycache__/utils.cpython-312.pyc | Bin 28096 -> 28096 bytes .../werkzeug/__pycache__/wsgi.cpython-312.pyc | Bin 25173 -> 25173 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 2381 -> 2381 bytes .../__pycache__/accept.cpython-312.pyc | Bin 15881 -> 15881 bytes .../__pycache__/auth.cpython-312.pyc | Bin 14414 -> 14414 bytes .../__pycache__/cache_control.cpython-312.pyc | Bin 12187 -> 12187 bytes .../__pycache__/csp.cpython-312.pyc | Bin 6150 -> 6150 bytes .../__pycache__/etag.cpython-312.pyc | Bin 5374 -> 5374 bytes .../__pycache__/file_storage.cpython-312.pyc | Bin 8788 -> 8788 bytes .../__pycache__/headers.cpython-312.pyc | Bin 30431 -> 30431 bytes .../__pycache__/mixins.cpython-312.pyc | Bin 16364 -> 16364 bytes .../__pycache__/range.cpython-312.pyc | Bin 10007 -> 10007 bytes .../__pycache__/structures.cpython-312.pyc | Bin 58902 -> 58902 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 23371 -> 23371 bytes .../debug/__pycache__/console.cpython-312.pyc | Bin 11596 -> 11596 bytes .../debug/__pycache__/repr.cpython-312.pyc | Bin 13738 -> 13738 bytes .../debug/__pycache__/tbtools.cpython-312.pyc | Bin 16939 -> 16939 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 4634 -> 4634 bytes .../__pycache__/converters.cpython-312.pyc | Bin 10881 -> 10881 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 7877 -> 7877 bytes .../routing/__pycache__/map.cpython-312.pyc | Bin 39762 -> 39762 bytes .../__pycache__/matcher.cpython-312.pyc | Bin 8200 -> 8200 bytes .../routing/__pycache__/rules.cpython-312.pyc | Bin 39046 -> 39046 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 157 -> 157 bytes .../sansio/__pycache__/http.cpython-312.pyc | Bin 5603 -> 5603 bytes .../__pycache__/multipart.cpython-312.pyc | Bin 14006 -> 14006 bytes .../__pycache__/request.cpython-312.pyc | Bin 21850 -> 21850 bytes .../__pycache__/response.cpython-312.pyc | Bin 31694 -> 31694 bytes .../sansio/__pycache__/utils.cpython-312.pyc | Bin 6142 -> 6142 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 281 -> 281 bytes .../__pycache__/request.cpython-312.pyc | Bin 26090 -> 26090 bytes .../__pycache__/response.cpython-312.pyc | Bin 34522 -> 34522 bytes __pycache__/config.cpython-312.pyc | Bin 1209 -> 1209 bytes app.db | Bin 45056 -> 0 bytes app.py | 4 - .../docs => docs}/api_documentation.txt | 0 flask_prompt_master/__init__.py | 30 - .../__pycache__/__init__.cpython-312.pyc | Bin 1091 -> 0 bytes .../__pycache__/chat_routes.cpython-312.pyc | Bin 1141 -> 0 bytes .../__pycache__/forms.cpython-312.pyc | Bin 1159 -> 0 bytes .../__pycache__/init_db.cpython-312.pyc | Bin 103819 -> 0 bytes .../__pycache__/models.cpython-312.pyc | Bin 8290 -> 0 bytes .../__pycache__/routes.cpython-312.pyc | Bin 46235 -> 0 bytes flask_prompt_master/app.db | Bin 94208 -> 0 bytes flask_prompt_master/app.py | 239 ---- flask_prompt_master/forms.py | 12 - flask_prompt_master/models.py | 89 -- flask_prompt_master/routes.py | 1177 ----------------- flask_prompt_master/static/css/style.css | 18 - .../__pycache__/__init__.cpython-312.pyc | Bin 191 -> 0 bytes .../__pycache__/prompts.cpython-312.pyc | Bin 51694 -> 0 bytes forms.py | 24 - init_db.py | 102 +- init_tedb.py | 298 ----- instance/app.db | Bin 110592 -> 0 bytes instance/prompt_master.db | Bin 28672 -> 0 bytes manage.py | 11 - migrations/migrate_to_mysql.py | 28 - migrations/versions/add_wx_fields.py | 66 - migrations/versions/create_wx_tables.py | 71 - run_dev.py | 2 +- scripts/backup_db.py | 32 - src/flask_prompt_master/__init__.py | 4 +- .../flask_prompt_master/config.py | 0 src/flask_prompt_master/forms/__init__.py | 8 + src/flask_prompt_master/models/__init__.py | 8 + src/flask_prompt_master/models/models.py | 2 +- .../flask_prompt_master/promptsTemplates.py | 4 +- src/flask_prompt_master/routes/__init__.py | 8 + .../flask_prompt_master}/routes/prompts.py | 0 src/flask_prompt_master/routes/routes.py | 8 +- src/flask_prompt_master/services/__init__.py | 10 + .../flask_prompt_master/static}/css/chat.css | 0 .../flask_prompt_master/static}/css/style.css | 0 .../flask_prompt_master/static}/js/main.js | 0 .../templates/__init__.py | 0 .../flask_prompt_master}/templates/base.html | 0 .../templates/expert_generate.html | 0 .../templates/generate.html | 0 .../flask_prompt_master}/templates/index.html | 0 .../templates/prompt.html | 0 .../templates/prompt_list.html | 0 .../flask_prompt_master}/templates/prompts.py | 0 src/flask_prompt_master/utils/__init__.py | 10 + sync_templates.py | 98 -- templates/base.html | 36 - templates/feedback.html | 37 - templates/generate.html | 22 - templates/prompt.html | 30 - test_db.py | 6 +- 173 files changed, 151 insertions(+), 2345 deletions(-) delete mode 100644 app.db delete mode 100644 app.py rename {flask_prompt_master/docs => docs}/api_documentation.txt (100%) delete mode 100644 flask_prompt_master/__init__.py delete mode 100644 flask_prompt_master/__pycache__/__init__.cpython-312.pyc delete mode 100644 flask_prompt_master/__pycache__/chat_routes.cpython-312.pyc delete mode 100644 flask_prompt_master/__pycache__/forms.cpython-312.pyc delete mode 100644 flask_prompt_master/__pycache__/init_db.cpython-312.pyc delete mode 100644 flask_prompt_master/__pycache__/models.cpython-312.pyc delete mode 100644 flask_prompt_master/__pycache__/routes.cpython-312.pyc delete mode 100644 flask_prompt_master/app.db delete mode 100644 flask_prompt_master/app.py delete mode 100644 flask_prompt_master/forms.py delete mode 100644 flask_prompt_master/models.py delete mode 100644 flask_prompt_master/routes.py delete mode 100644 flask_prompt_master/static/css/style.css delete mode 100644 flask_prompt_master/templates/__pycache__/__init__.cpython-312.pyc delete mode 100644 flask_prompt_master/templates/__pycache__/prompts.cpython-312.pyc delete mode 100644 forms.py delete mode 100644 init_tedb.py delete mode 100644 instance/app.db delete mode 100644 instance/prompt_master.db delete mode 100644 manage.py delete mode 100644 migrations/migrate_to_mysql.py delete mode 100644 migrations/versions/add_wx_fields.py delete mode 100644 migrations/versions/create_wx_tables.py delete mode 100644 scripts/backup_db.py rename config.py => src/flask_prompt_master/config.py (100%) create mode 100644 src/flask_prompt_master/forms/__init__.py create mode 100644 src/flask_prompt_master/models/__init__.py rename flask_prompt_master/init_db.py => src/flask_prompt_master/promptsTemplates.py (99%) create mode 100644 src/flask_prompt_master/routes/__init__.py rename {flask_prompt_master => src/flask_prompt_master}/routes/prompts.py (100%) create mode 100644 src/flask_prompt_master/services/__init__.py rename {static => src/flask_prompt_master/static}/css/chat.css (100%) rename {static => src/flask_prompt_master/static}/css/style.css (100%) rename {static => src/flask_prompt_master/static}/js/main.js (100%) rename {flask_prompt_master => src/flask_prompt_master}/templates/__init__.py (100%) rename {flask_prompt_master => src/flask_prompt_master}/templates/base.html (100%) rename {flask_prompt_master => src/flask_prompt_master}/templates/expert_generate.html (100%) rename {flask_prompt_master => src/flask_prompt_master}/templates/generate.html (100%) rename {flask_prompt_master => src/flask_prompt_master}/templates/index.html (100%) rename {flask_prompt_master => src/flask_prompt_master}/templates/prompt.html (100%) rename {flask_prompt_master => src/flask_prompt_master}/templates/prompt_list.html (100%) rename {flask_prompt_master => src/flask_prompt_master}/templates/prompts.py (100%) create mode 100644 src/flask_prompt_master/utils/__init__.py delete mode 100644 sync_templates.py delete mode 100644 templates/base.html delete mode 100644 templates/feedback.html delete mode 100644 templates/generate.html delete mode 100644 templates/prompt.html diff --git a/.cursor/rules/5sguize.mdc b/.cursor/rules/5sguize.mdc index 1e843c6..b3f2026 100644 --- a/.cursor/rules/5sguize.mdc +++ b/.cursor/rules/5sguize.mdc @@ -1,5 +1,5 @@ --- -alwaysApply: false +alwaysApply: true --- ### **软件开发人员5S个人工作规范体系** **版本:** 1.0 diff --git a/.venv/Lib/site-packages/__pycache__/typing_extensions.cpython-312.pyc b/.venv/Lib/site-packages/__pycache__/typing_extensions.cpython-312.pyc index a625060f59894b4b2d7be12f8e9394ea63a1cafd..1be9ebeaed29193dd619193090a6d4bbe65d0fea 100644 GIT binary patch delta 28 icmaEOfaBo-4(`*uyj%=GpgVnGBX=t|<5q5_Fa-dKcnAjo delta 28 icmaEOfaBo-4(`*uyj%=G@Lys delta 28 icmaF6nB(nY4(`*uyj%=G@K0hvBX=t|<5q5_M}h#0)CjWx diff --git a/.venv/Lib/site-packages/click/__pycache__/decorators.cpython-312.pyc b/.venv/Lib/site-packages/click/__pycache__/decorators.cpython-312.pyc index 653cc3e069361e9efd7c3f9790cd3c76175f2120..b6417e20b2caaa341aea306ccb10ea86ceb7e1b9 100644 GIT binary patch delta 22 ccmex)fbr)6M()$Ryj%=GpgVoxM((@>0AJGwUH||9 delta 22 ccmex)fbr)6M()$Ryj%=G@K0jFM((@>0Ah;=uK)l5 diff --git a/.venv/Lib/site-packages/click/__pycache__/exceptions.cpython-312.pyc b/.venv/Lib/site-packages/click/__pycache__/exceptions.cpython-312.pyc index bf5be04f3d6d50d21b48a08475a97dcb04351f9a..7048b3cdbfc83086920e833bf238d74f08088276 100644 GIT binary patch delta 20 acmexg{J)s{G%qg~0}$v=U$~L`izNV2b_Xp0 delta 20 acmexg{J)s{G%qg~0}%X^Sg?`%izNV5E(d-9 diff --git a/.venv/Lib/site-packages/click/__pycache__/formatting.cpython-312.pyc b/.venv/Lib/site-packages/click/__pycache__/formatting.cpython-312.pyc index 127176f57409360187be1a2e382f29356f8413ce..9f9b71be5e6dec9c4c1a4b8a7b1678a4fe0c2117 100644 GIT binary patch delta 20 acmX?_do-8(G%qg~0}$v=U$~Kbml*&@iw1B2 delta 20 acmX?_do-8(G%qg~0}%X^Sg?_Mml*&`Lk7VB diff --git a/.venv/Lib/site-packages/click/__pycache__/globals.cpython-312.pyc b/.venv/Lib/site-packages/click/__pycache__/globals.cpython-312.pyc index c022a49609ece61e45fae3e0b07446a2fedad07d..2580a1a2a3b63293b23b0521af93ec055a2ae60f 100644 GIT binary patch delta 20 acmZpdXqVtV&CAQh00g?z7jESK!wmp3yaizZ delta 20 acmZpdXqVtV&CAQh00jRe7Hs7H!wmp6bOo{i diff --git a/.venv/Lib/site-packages/click/__pycache__/parser.cpython-312.pyc b/.venv/Lib/site-packages/click/__pycache__/parser.cpython-312.pyc index 9a9f4ad84ff6912a990283ecd1ae08087cb69597..7962113dce262856579206fb53eed082fa2cc634 100644 GIT binary patch delta 22 ccmX@TobmK>M()$Ryj%=GpgVoxM(zW_098E)6#xJL delta 22 ccmX@TobmK>M()$Ryj%=G@K0jFM(zW_09W+~W&i*H diff --git a/.venv/Lib/site-packages/click/__pycache__/termui.cpython-312.pyc b/.venv/Lib/site-packages/click/__pycache__/termui.cpython-312.pyc index e228844234353d7fcc64952f961838e58f80982e..0984aedb605501a7b9d16774a681dfa247266074 100644 GIT binary patch delta 22 ccmezJpYh9oM()$Ryj%=GpgVoxM(&sO0BN)cYybcN delta 22 ccmezJpYh9oM()$Ryj%=G@K0jFM(&sO0Bmdsy#N3J diff --git a/.venv/Lib/site-packages/click/__pycache__/types.cpython-312.pyc b/.venv/Lib/site-packages/click/__pycache__/types.cpython-312.pyc index 6c9d2a7cfa1c5dec8d2289e50b0b40a134b12f8e..b1f85d132e3513f5a2384002a0dd30da6d177794 100644 GIT binary patch delta 22 ccmZ3}#Jr}7nfo*^FBbz4=uTg_kz4T~07@MOU;qFB delta 22 ccmZ3}#Jr}7nfo*^FBbz4{F7L)kz4T~08G^eu>b%7 diff --git a/.venv/Lib/site-packages/click/__pycache__/utils.cpython-312.pyc b/.venv/Lib/site-packages/click/__pycache__/utils.cpython-312.pyc index afcaf0b6a1d770d67df719fca05c9c295ed9f177..d37a3766d753d6ce3c1b15e465aa5abd86fbc7cd 100644 GIT binary patch delta 22 ccmcb9mht*oM()$Ryj%=GpgVoxM(#6d09_sjm;e9( delta 22 ccmcb9mht*oM()$Ryj%=G@K0jFM(#6d0AJPz=>Px# diff --git a/.venv/Lib/site-packages/colorama/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/colorama/__pycache__/__init__.cpython-312.pyc index 0598a6c0d9d4026749ec1276cb5086d52e58e64d..983e64854cf105fe287abc64f67573ad19919729 100644 GIT binary patch delta 20 acmX@ae2AI*G%qg~0}$v=U$~KbJ0k!$_61%5 delta 20 acmX@ae2AI*G%qg~0}%X^Sg?_MJ0k!(t_80E diff --git a/.venv/Lib/site-packages/colorama/__pycache__/ansi.cpython-312.pyc b/.venv/Lib/site-packages/colorama/__pycache__/ansi.cpython-312.pyc index 9c308c1a9c2d046bab5f4078078afffbcdac589d..ae833f491429faa009ff675ef51410c32591ebc0 100644 GIT binary patch delta 20 acmdllw_lF?G%qg~0}$v=U$~LmgdYGpSOpmX delta 20 acmdllw_lF?G%qg~0}%X^Sg?`XgdYGs5Cv)g diff --git a/.venv/Lib/site-packages/colorama/__pycache__/ansitowin32.cpython-312.pyc b/.venv/Lib/site-packages/colorama/__pycache__/ansitowin32.cpython-312.pyc index 682c4995945cb1aa71b352101893a5db4aac058e..181f8354059d9a94462843e6b8881000823ffa0e 100644 GIT binary patch delta 20 acmexV|EZq)G%qg~0}$v=U$~L`xjg_;BnKn_ delta 20 acmexV|EZq)G%qg~0}%X^Sg?`%xjg_=+y`|4 diff --git a/.venv/Lib/site-packages/colorama/__pycache__/initialise.cpython-312.pyc b/.venv/Lib/site-packages/colorama/__pycache__/initialise.cpython-312.pyc index c4bbd427e9811b63f74c14d10c8d87be1bb72f10..1e68b8c8771afbddea6e0238c978f52fba6c5921 100644 GIT binary patch delta 20 acmdlYy+xY)G%qg~0}$v=U$~KbB`*LuG6iq| delta 20 acmdlYy+xY)G%qg~0}%X^Sg?_MB`*Lw>IK07 diff --git a/.venv/Lib/site-packages/colorama/__pycache__/win32.cpython-312.pyc b/.venv/Lib/site-packages/colorama/__pycache__/win32.cpython-312.pyc index 4f3c644df2b0f611b38cce52709000847e73d5b7..929305316f49b803d1b6db1c4e583fca3076d16f 100644 GIT binary patch delta 20 acmbPhKi8i7G%qg~0}$v=U$~Kbk~{!9yaj~- delta 20 acmbPhKi8i7G%qg~0}%X^Sg?_Mk~{!CbOqJ` diff --git a/.venv/Lib/site-packages/colorama/__pycache__/winterm.cpython-312.pyc b/.venv/Lib/site-packages/colorama/__pycache__/winterm.cpython-312.pyc index f3f979942c753d75edb8723a748c73886c3c4192..dd2b8bc95b19c34bdadaa30429f1b467a44657bf 100644 GIT binary patch delta 20 acmccScFm3ZG%qg~0}$v=U$~LmTNwaDqy@qN delta 20 acmccScFm3ZG%qg~0}%X^Sg?`XTNwaGTm};W diff --git a/.venv/Lib/site-packages/flask/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/__init__.cpython-312.pyc index 8cbf084c10c3ec4de89d06b79e97b1fa2337da28..529d388aebf404c4757c3c4b691b6cbb2a9d8569 100644 GIT binary patch delta 20 acmeAW?hxia&CAQh00g?z7jERP-w delta 20 acmaE$_CSsMG%qg~0}%X^Sg?^hR2Tq5Tm|6( diff --git a/.venv/Lib/site-packages/flask/__pycache__/cli.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/cli.cpython-312.pyc index 54801cbd240e022d7b0742792b1469d8d138da7f..4c45e117a95c4fd9fec27f27155800603281c60c 100644 GIT binary patch delta 22 ccmX?oiRttuChpU`yj%=GpgVoxMsA0d09!=|LjV8( delta 22 ccmX?oiRttuChpU`yj%=G@K0jFMsA0d0A2kDlmGw# diff --git a/.venv/Lib/site-packages/flask/__pycache__/config.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/config.cpython-312.pyc index 89bb2e831d52086cef2d91b6e297e230ffb4a822..39308790e63e6fa659b233f8e94715bddc8608a3 100644 GIT binary patch delta 20 acmZ2kx3Z4=G%qg~0}$v=U$~K5&K>|nm<7iG delta 20 acmZ2kx3Z4=G%qg~0}%X^Sg?^>&K>|qPzD$P diff --git a/.venv/Lib/site-packages/flask/__pycache__/ctx.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/ctx.cpython-312.pyc index 5ea228d39d3fb072a3c6eaceac0207131b2ff87f..91e5e6e40035b8b32ddbc5e5e2a6c9d12c019a0a 100644 GIT binary patch delta 22 ccmX>-i}Ca-i}Caj2!?r7zF45 diff --git a/.venv/Lib/site-packages/flask/__pycache__/helpers.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/helpers.cpython-312.pyc index c3a098fc02601ef369d444d6280227caca3a327a..3ad0a578ab70e02a3f1fa33a15b692a30519b246 100644 GIT binary patch delta 22 ccmdmTjB(2`M()$Ryj%=GpgVoxMsCey097dlo&W#< delta 22 ccmdmTjB(2`M()$Ryj%=G@K0jFMsCey09WA#?*IS* diff --git a/.venv/Lib/site-packages/flask/__pycache__/logging.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/logging.cpython-312.pyc index 5c48b4390e011aea053fc236c60321367b921e16..9bcd34c38430312894ef4a784de50edf4709123d 100644 GIT binary patch delta 20 acmbOyIZu-NG%qg~0}$v=U$~KbG7kVXc?Br| delta 20 acmbOyIZu-NG%qg~0}%X^Sg?_MG7kVaF$H=6 diff --git a/.venv/Lib/site-packages/flask/__pycache__/sessions.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/sessions.cpython-312.pyc index 00c2c8b07b060c00321c85511e618e86186d17fd..f0d2cc4f9bd0153b0c54d0bf0558d0b4a360a9a7 100644 GIT binary patch delta 22 ccmX@w%6PPuk^3|+FBbz4=uTg_k$aaD08ab{t^fc4 delta 22 ccmX@w%6PPuk^3|+FBbz4{F7L)k$aaD08z9C{{R30 diff --git a/.venv/Lib/site-packages/flask/__pycache__/signals.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/signals.cpython-312.pyc index 70ce6c6cf29db6591c5eaed9c071a729f4cf18eb..181968073a6bbcffa867b35f110f3789895aecec 100644 GIT binary patch delta 20 acmbQoIggY3G%qg~0}$v=U$~KbG7A7RF$Dnt delta 20 acmbQoIggY3G%qg~0}%X^Sg?_MG7A7T=><{% diff --git a/.venv/Lib/site-packages/flask/__pycache__/templating.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/templating.cpython-312.pyc index af054b5baefdeb7411ec827ef45cbe92b292e8f0..23fb00ba960dd7a35bc3025d1ad9558440012da0 100644 GIT binary patch delta 20 acmeD7?e^t9&CAQh00g?z7jEQkPy+xt>jiQE delta 20 acmeD7?e^t9&CAQh00jRe7Hs5hPy+xwqXokN diff --git a/.venv/Lib/site-packages/flask/__pycache__/typing.cpython-312.pyc b/.venv/Lib/site-packages/flask/__pycache__/typing.cpython-312.pyc index bda823778fb1c8b65c687f44a5375ab9881d1341..97db9c414e7ec51c800243daba7166215457fa47 100644 GIT binary patch delta 20 acmaDO_ePHUG%qg~0}$v=U$~Jwkskm-U-~}rH delta 20 acmbR1H`kB*G%qg~0}%X^Sg?^>NF4w^m<4mkj_pX9Xw# diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/_json.cpython-312.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/_json.cpython-312.pyc index f9dd95a66a0c153a2955eed1070f9c3a8847ff0f..f0d25c93f150a1dd0ff666ceea64aef81fa0916f 100644 GIT binary patch delta 20 acmeyx@r#4|G%qg~0}$v=U$~Jwp9KIwZ3UA6 delta 20 acmeyx@r#4|G%qg~0}%X^Sg?^hp9KIzB?aUF diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/encoding.cpython-312.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/encoding.cpython-312.pyc index 7c3dabd9c6f40d0fa6a7fa3b5556db859c408596..3102b688ec5b43bb63b167777e5a1182ff27e75b 100644 GIT binary patch delta 20 acmca6a!rK$G%qg~0}$v=U$~Lmn+pIug9SwZ delta 20 acmca6a!rK$G%qg~0}%X^Sg?`Xn+pIxI|Y^i diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/exc.cpython-312.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/exc.cpython-312.pyc index f5e1271ca89e644e4229d01d0cf49f594a0a5c25..4d0f0aa4b6c6b81c5daca332a6264f1303c1edd0 100644 GIT binary patch delta 20 acmX>kcSw%=G%qg~0}$v=U$~LmoF4!>&;=p@ delta 20 acmX>kcSw%=G%qg~0}%X^Sg?`XoF4!^hy`;1 diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/serializer.cpython-312.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/serializer.cpython-312.pyc index 786d32252c6522fe57eac8f4b364e1e73ab174bd..bafc8f375b5f032f2530e42bcc42f320fa528d9f 100644 GIT binary patch delta 20 acmeCH=&Rs9&CAQh00g?z7jEQcwgCV?g#~8- delta 20 acmeCH=&Rs9&CAQh00jRe7Hs5ZwgCV_Jq5S` diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/signer.cpython-312.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/signer.cpython-312.pyc index 969206ddbfd60a8ba25766faf937e57e1954df98..a19073e5bbe024cb666a4ab3a541e6111d6e369c 100644 GIT binary patch delta 20 acmewy{yCicG%qg~0}$v=U$~L`g*E_7my+WG%G%qg~0}$v=U$~KbE-wH#QUy!^ delta 20 acmZ1>y+WG%G%qg~0}%X^Sg?_ME-wH&3I&}2 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc index dbab2c2a93ebce29a743cba4cc82d372e0c81c9f..554f16f739dbbbb416255796a463d072070f6881 100644 GIT binary patch delta 20 acmcb}bCHMpG%qg~0}$v=U$~LmjST=gmjxmK delta 20 acmcb}bCHMpG%qg~0}%X^Sg?`XjST=jPX%)T diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc index b4f24cf3d9ddd7eb2c387c4aa204c99e772cf9c1..80f9754dce51a80b6cfbc15834399526860e2860 100644 GIT binary patch delta 20 acmdlaut|XXG%qg~0}$v=U$~K5odWodW;<0y diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc index 8dfc3484328385483336d2f84c10e203444a2ec1..08a0d1d0c35f9caa184a2d18d7c504e473eb9f2a 100644 GIT binary patch delta 22 ccmcaPjq&C*M()$Ryj%=GpgVoxMs7cE08{t|l>h($ delta 22 ccmcaPjq&C*M()$Ryj%=G@K0jFMs7cE09LRD<^TWy diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/compiler.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/compiler.cpython-312.pyc index bc71d901ae627d3a60532ee9f5d73d37ef325478..77af10399503c56d87979f89789a785f8b22adf3 100644 GIT binary patch delta 25 fcmdn6nr*{sHty5Byj%=GpgVnGBllKr#-&pMW=#jF delta 25 fcmdn6nr*{sHty5Byj%=G@K0hvBllKr#-&pMY4`{F diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/defaults.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/defaults.cpython-312.pyc index d32d6083cbe72470048ee614d2837f042fc481df..b3ee0de440f1d32feba5e7679d13ef73c0acb891 100644 GIT binary patch delta 20 acmZ3)vxtZLG%qg~0}$v=U$~K5oDBdoKLnKk delta 20 acmZ3)vxtZLG%qg~0}%X^Sg?^>oDBdq_XOqu diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/environment.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/environment.cpython-312.pyc index c30fa2d3e8331801d604f371c89c8e397715abff..c3ba0eb391580f823d9c76515b7ed89d6a7b120d 100644 GIT binary patch delta 25 fcmdmfjb-~a7Vgu$yj%=GpgVnGBllKrMjdScZF2`E delta 25 fcmdmfjb-~a7Vgu$yj%=G@K0hvBllKrMjdScaUKVE diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc index 99dde3d3384778b7da2544341e41a93c5080b2a9..fbecc16484f9e88d5a75b5adae8f92dec3074a90 100644 GIT binary patch delta 20 acmexw{ok7VG%qg~0}$v=U$~L`i!1<1dIq5Y delta 20 acmexw{ok7VG%qg~0}%X^Sg?`%i!1<4G6wPh diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/filters.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/filters.cpython-312.pyc index 0db24619453382b63fd3e4307ba4cd70bb702a3e..8c71c47d7ff763ffb2fdadc5288c126ce452bde2 100644 GIT binary patch delta 25 fcmeC(#?rfuh5IxwFBbz4=uThQ$i0=Dkx3c=U%3WY delta 25 fcmeC(#?rfuh5IxwFBbz4{F7MF$i0=Dkx3c=V`K)Y diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc index 7c2c9cc164d34f6b68e4366d1ff8a0d952799fbf..e95153bd7e3fed5c8a1fc1c427d08364e427a49c 100644 GIT binary patch delta 22 ccmeB~%GfiNk^3|+FBbz4=uTg_k-O0g07u~lD*ylh delta 22 ccmeB~%GfiNk^3|+FBbz4{F7L)k-O0g07{t#d;kCd diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/lexer.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/lexer.cpython-312.pyc index dcafe745c1120cb162519014da77495eda036bb2..e608b4bf5acbe1a0d3d11a8d25323e96d62663cc 100644 GIT binary patch delta 22 ccmbRHi*fERM()$Ryj%=GpgVoxMsA^609jH7+W-In delta 22 ccmbRHi*fERM()$Ryj%=G@K0jFMsA^609*TNwaBTm`cL diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/utils.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/utils.cpython-312.pyc index 0f40445a476a72a7d4004cbbe62d1bd63580f841..9d7b4a81a95a06eb9029258c41e615b6f4378d6f 100644 GIT binary patch delta 22 ccmX@r&vdGviTgA!FBbz4=uTg_k$ZnT08zsS7ytkO delta 22 ccmX@r&vdGviTgA!FBbz4{F7L)k$ZnT091PiX#fBK diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc index c1a664b9ad9b5edb5a37356467eb390f7c3e2b6a..cf9922ae33e01ca7a0bafc86f4a510f45a152d67 100644 GIT binary patch delta 20 acmX@Ac~q18G%qg~0}$v=U$~Kbmk0no*#*V` delta 20 acmX@Ac~q18G%qg~0}%X^Sg?_Mmk0nrkp>q4 diff --git a/.venv/Lib/site-packages/markupsafe/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markupsafe/__pycache__/__init__.cpython-312.pyc index cea30eb429b9b5de57c790f094743c6c8149730d..2993b77844f609d1099b7168f31cf7c54e829c59 100644 GIT binary patch delta 22 ccmdnGm~rc3M()$Ryj%=GaB|whjohmO0aYspWB>pF delta 22 ccmdnGm~rc3M()$Ryj%=G@K0jFM($OC08^z08UO$Q diff --git a/.venv/Lib/site-packages/werkzeug/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/__pycache__/__init__.cpython-312.pyc index cb7b811ce7e8cecc46352965262938629dc8a93b..e551417a11e5fa2f00ab8f888589885e34f6eff4 100644 GIT binary patch delta 20 acmdnMw1J8HG%qg~0}$v=U$~K5l@S0m0tBW2 delta 20 acmdnMw1J8HG%qg~0}%X|Sg?^>l@S0o!36jK diff --git a/.venv/Lib/site-packages/werkzeug/__pycache__/_internal.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/__pycache__/_internal.cpython-312.pyc index 573ca961fc1f27ef7148fd277178ad93ed4deca7..6004cbd78f9ce67056254916f35fc0a51912f1ce 100644 GIT binary patch delta 20 acmezG{okAWG%qg~0}$v=U$~L`iz)z1!Uo9z delta 20 acmezG{okAWG%qg~0}%X|Sg?`%iz)z4fd?A^ diff --git a/.venv/Lib/site-packages/werkzeug/__pycache__/_reloader.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/__pycache__/_reloader.cpython-312.pyc index bb3915f80866b1dbd520cf8feaff69b9c42200ba..7d32a9bba23076d0d04ecb2fc5ae951f7e192ee5 100644 GIT binary patch delta 22 ccmZ3wfN|*pM()$Ryj%=GpgVoxMsBG908GaQ5&!@I delta 22 ccmZ3wfN|*pM()$Ryj%=G@LyuVMsBG908fSnWB>pF diff --git a/.venv/Lib/site-packages/werkzeug/__pycache__/exceptions.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/__pycache__/exceptions.cpython-312.pyc index bd000ad6e8ae947e3bfe53d516380ee1d2d9a462..f07276cabb38334e70fe2b9e39f8a30ab380a689 100644 GIT binary patch delta 22 ccmeBZVd`jM;y%sG%f$c$y3-eKHq)$ delta 22 ccmZqZU~cGO=045K%f$c$|0Nb|QUL%xxCL(j diff --git a/.venv/Lib/site-packages/werkzeug/__pycache__/user_agent.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/__pycache__/user_agent.cpython-312.pyc index 1f2194f3c310734891fa36b1e6c57c72b60b09d1..96d677211d4fee327a635ed98aa15b45460254a0 100644 GIT binary patch delta 20 acmX>qa8!W%G%qg~0}$v=U$~LmiUR;SNd*W1 delta 20 acmX>qa8!W%G%qg~0}%X|Sg?`XiUR;V2nAXI diff --git a/.venv/Lib/site-packages/werkzeug/__pycache__/utils.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/__pycache__/utils.cpython-312.pyc index 42ec19afcb9e9d4fae09744d60fbcb072526a3de..f48eb1e217803e50c0d9081285602e2c58eabd9e 100644 GIT binary patch delta 22 ccmX?boAJPHM()$Ryj%=GpgVoxM((Y-09$GYb^rhX delta 22 ccmX?boAJPHM()$Ryj%=G@LyuVM((Y-0A48v$N&HU diff --git a/.venv/Lib/site-packages/werkzeug/__pycache__/wsgi.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/__pycache__/wsgi.cpython-312.pyc index 4f9bd81e7814466353602758ed635c0b43083ac1..01996d0da963e7cbe07b52fb8b9e10ebd8c7f5a5 100644 GIT binary patch delta 22 ccmcb5gz@STM()$Ryj%=GpgVoxMsBYp09s`R`~Uy| delta 22 ccmcb5gz@STM()$Ryj%=G@LyuVMsBYp09_;pP5=M^ diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-312.pyc index 3c581372dff25a635f6759e8892b97670b2d0faf..7273a3b9061469d40d337ef9073bef872824d86f 100644 GIT binary patch delta 20 acmX>rbXJJ_G%qg~0}$v=U$~Lmi4y=i(gh^| delta 20 acmX>rbXJJ_G%qg~0}%X|Sg?`Xi4y=lkp*`E diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-312.pyc index cea233a1471de4f6884f33c3963e461896b10966..6859cd0ac2e79c077d832412bc3734403e0b9ef6 100644 GIT binary patch delta 20 acmeCI>8#;C&CAQh00g?z7jESKXA1y9P6lBB delta 20 acmeCI>8#;C&CAQh00jRf7Hs7HXA1yC4FXs diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-312.pyc index a1ae389bb47b859b51aa4b63181eef64de104086..df7408c293a3a3a38d163d7ad5eede8f2796d8ec 100644 GIT binary patch delta 20 acmbOoKRcfLG%qg~0}$v=U$~Kbf<6E~`~}Yd delta 20 acmbOoKRcfLG%qg~0}%X|Sg?_Mf<6F2y9OZu diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-312.pyc index bb151fb3af090d290580e03e061b74110bdd3e7d..d3ace261463570657257b1c85ab7c7c9d607793b 100644 GIT binary patch delta 20 acmZoOXfxnG&CAQh00g?z7jESKEe-%S00o)= delta 20 acmZoOXfxnG&CAQh00jRf7Hs7HEe-%UzXj|7 diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-312.pyc index 38daca2063d5ba7f1fb5d628d9b5103bc2ea25fd..27e93685737864a72d17305f08fd9e6ff0953c35 100644 GIT binary patch delta 20 acmeyT`A?JkG%qg~0}$v=U$~L`vj_l2!3J>v delta 20 acmeyT`A?JkG%qg~0}%X|Sg?`%vj_l5fCj?= diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-312.pyc index fc525cc4f66a136bcac3016d14239b10217b1d2a..999c43a893a7ae6915db78e32c3b939a8b0e6af9 100644 GIT binary patch delta 20 acmccOa>a%FG%qg~0}$v=U$~LmQwab=3kA0T delta 20 acmccOa>a%FG%qg~0}%X|Sg?`XQwab?$_5Dl diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-312.pyc index 24c57216555e86c5ba017f42f359751517ca6a29..b99444201301382216bb2f4252a2ea2596096b07 100644 GIT binary patch delta 22 ccmccrmht{uM()$Ryj%=GpgVoxM(!(R0Apqd00000 delta 22 ccmccrmht{uM()$Ryj%=G@LyuVM(!(R0A?i!QUCw| diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-312.pyc index 9c288af07f40a1cad39f208b48bbb608fcb1a006..4cc942d24a6321465b323cc0b149f1614c489e0b 100644 GIT binary patch delta 20 acmaD;|E8Y%G%qg~0}$v=U$~L`p*;XlGzSs@ delta 20 acmaD;|E8Y%G%qg~0}%X|Sg?`%p*;Xn^9N)A diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/range.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/range.cpython-312.pyc index cf6d9b3b0b8744c038299b0ee02aa0aada4426f3..73464fb5e67c2e8c7751388d2f7d54068012873a 100644 GIT binary patch delta 20 acmbR4H{Fl>G%qg~0}$v=U$~K*M;!n<@C6wF delta 20 acmbR4H{Fl>G%qg~0}%X|Sg?_sM;!n?uLWxW diff --git a/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-312.pyc index d635e6dc725f970cd56ff60f30f4337cb6d77d34..0225800755fbdd8d1cdc74e8beeeb5a4ab254328 100644 GIT binary patch delta 22 ccmbPshI!fTbta1YG%qg~0}$v=U$~LmQ5OJ2?giEW delta 20 acmX>Tbta1YG%qg~0}%X|Sg?`XQ5OJ5tp+Fn diff --git a/.venv/Lib/site-packages/werkzeug/debug/__pycache__/repr.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/debug/__pycache__/repr.cpython-312.pyc index d7d1fbf7c3aec2f2690afd02aa6cfd0c13942601..3d08b3436b57b41afc0ad37f1207475ab79c25cd 100644 GIT binary patch delta 20 acmZ3Ly(*jgG%qg~0}$v=U$~Kbz9|4h3I-Yg delta 20 acmZ3Ly(*jgG%qg~0}%X|Sg?_Mz9|4j$p&ly diff --git a/.venv/Lib/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-312.pyc index b250e1b59c285a6984b93cc4cdb9ec65cd24e847..1defd62d5603f1aa4387a932ad454399c0de1b9b 100644 GIT binary patch delta 22 ccmZ48!nnGHk^3|+FBbz4=uTg_kz2tD07-WR-T(jq delta 22 ccmZ48!nnGHk^3|+FBbz4{Fhj;kz2tD08BOpFaQ7m diff --git a/.venv/Lib/site-packages/werkzeug/routing/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/routing/__pycache__/__init__.cpython-312.pyc index b470a2db8a3987a8ee2a3ba9ac4fb30328c510fe..1d39dcf2eb057051b4a16d856d2412c4a351d1d4 100644 GIT binary patch delta 20 acmbQGGE0T~G%qg~0}$v=U$~K*UkCs-YXrFf delta 20 acmbQGGE0T~G%qg~0}%X|Sg?_sUkCs=Dg_Gw diff --git a/.venv/Lib/site-packages/werkzeug/routing/__pycache__/converters.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/routing/__pycache__/converters.cpython-312.pyc index 9cce96a3296286e26dd090ccff0b691172c74017..1007d0505e7cab75faddc08857243c03e5848dab 100644 GIT binary patch delta 20 acmZn+Z4Bi;&CAQh00g?z7jEP((*giFe+6g& delta 20 acmZn+Z4Bi;&CAQh00jRf7Hs4$(*giIJ_Wh} diff --git a/.venv/Lib/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-312.pyc index 501654e797fd92b41f07d04fea52e78b215cc136..ac5065da6c3d2f72fae09561b1c5778df00ef15a 100644 GIT binary patch delta 20 acmX?Vd(@WuG%qg~0}$v=U$~KbmmB~pF diff --git a/.venv/Lib/site-packages/werkzeug/routing/__pycache__/matcher.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/routing/__pycache__/matcher.cpython-312.pyc index f24b36f206cb83fa059ec5df631b52b80c2ca256..cf6398afd9a0043e77e47b402c62b76bbda30f0f 100644 GIT binary patch delta 20 acmeBh=y2dZ&CAQh00g?z7jESKD-QrTm<7lH delta 20 acmeBh=y2dZ&CAQh00jRf7Hs7HD-QrWR|XmY diff --git a/.venv/Lib/site-packages/werkzeug/routing/__pycache__/rules.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/routing/__pycache__/rules.cpython-312.pyc index 26a163086e3f8f35c0128d79ee6ca5221459e1f4..936428c7cc6b2fc7252e85e1b26c989d391a9ba5 100644 GIT binary patch delta 22 ccmZqM$keuxiTgA!FBbz4=uTg_k-K^Z085qzp#T5? delta 22 ccmZqM$keuxiTgA!FBbz4{Fhj;k-K^Z08Ui~^8f$< diff --git a/.venv/Lib/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-312.pyc index 03bfc6473351b2a2451634acc9720b334124e5cd..ce359a7e3c835172fb91e676da5d959ca17a50e7 100644 GIT binary patch delta 19 ZcmbQsIG2(8G%qg~0}z~?ws0c%Bmgiz1!VvL delta 19 ZcmbQsIG2(8G%qg~0}%X|STK=$5&$m<1snhX diff --git a/.venv/Lib/site-packages/werkzeug/sansio/__pycache__/http.cpython-312.pyc b/.venv/Lib/site-packages/werkzeug/sansio/__pycache__/http.cpython-312.pyc index 3f5da89d4a40ceab96b79b8afc6679f577cf6c23..2fbfc2da62c5c3c94c9486ef2b911b7372599440 100644 GIT binary patch delta 20 acmaE?{aBm(G%qg~0}$v=U$~L`hA03+(gq~} delta 20 acmaE?{aBm(G%qg~0}%X|Sg?`%hA03h($ diff --git a/__pycache__/config.cpython-312.pyc b/__pycache__/config.cpython-312.pyc index f16b6ed4aef5d50d63b353bafe529f4917c4730e..a9fe1f4287e45408b74e269bd6cec77ecc0033cd 100644 GIT binary patch delta 20 acmdnVxs#LoG%qg~0}#B6S-6pV9SZn5ZjRnga~o#gTRKJoi` z>_kqQWP5AVb||@4Z&odbEDEm(qA0vgh#&~lY(B?kZ;G)i6W$GWDUMt}?dr6!aN}+~ z@kEfMmXL@iem`G|{}cZuzCBH+C#64G5EBF-009U<00Izzz_<(SNl|%qR_sjLwF*77 z56x?oR(7rOzFBTk%b^w1a=g&FbwkgUbdoPz)ITK8ZcB;<;}+nnNu*fQa_rikw~9x~^=g&Y z9C9URtiPKxQdw11-1uN1s*cw2J|(QDCLPWg)9^*yx&cCFENOotvmZN5iqlvRlB zKEBnO`k!m^BK{X>eh`Vs^GWfhr|CB5i<(uX{4&}f^G+eZwKKAB`x5B%3(jHvlNcX z$)tExbj!`V@Oi>lY91k}Qwz;kbFaanwUluWgWf>A<4sHVj<<%@YJE~~R?O>G>-wOJ zmR@<@(HJbVq;wQ9D$mV{M=^K9tpi%!waexW+HBeNTHt2LH=MvqKC*r{v(~N-Hfb@f z_#RT$i-qlykz&0^xQ!2U2n00Izz00bZa0SG_<0uX=z1RyXb0_Vlhg+*1;@2k00bZa z0SG_<0uX=z1Rwx`@fX1P|M=G!BZL41AOHafKmY;|fB*y_009W_&;N%KX(90~TVR3! z1Rwwb2tWV=5P$##AOHafK%g%`LlL36oQrku-9P#H$L{xcPrmr_;l1NWzkbdl-3Ooj zeSE+Bb*KB_sQcaVqu*{n{NbCEJ3n>5y0hW^KBe~ynfzxe(`q_9uWIw@EK#+!Y-TO9 zvaqcN9oS^pDHg@x9!3k6T!DyAb%%6t+qLY zelVjiV5f4@fNd8!$iY4euz@kdoX-Wk!Kaw_g+MgK6brr-$cCI^(N_!wawT64G(*FP zLoVO$l{Io;iD%Z3D_5~2Z($?9F6zopmZf7VKJu;jB>=7T{K*5~UUh?Yu;iy+jaZ2b zP+ANdRj;-JP*{BSqGaRV1#A;x@vu%f@b04IESB_N2d{FtFMOM2fo$L=t_v9+)OC5# z%5W34d-X6%)PB5)2fQh}EK<++rQ3MsTzoXMt_P1sP=}}?^ zR-Cw`NWwK}jSR7KW5lg_%xhNsH8&z&Bhh&}l-*<6a5|d{PJGh~rid=54wRo%`QQ2PF zT-q0=_k`&W3mswhR6?Tq_VU(a2ITGK&E*}wBa9ykxqV@LPZ-}ReVpkC*MCFw&VeBJ zPTuVZw~lhdt)&yV3hBdCOdHMk9L<`JU-?!x?SxGu&1dc&b%f0|VIxB%7Uja2YFUOI zk~n3ZjI!_;Q|xV@5t(9m0u)sig3wv>-TR~fCL7{-9@H_9G47&?F1p=CH@j%+J5syo d>MsdNqi@PB?wfY$o!*jul;-MBQ9%5iwv(tQ-P2$YPHYJ4! z1?@rFlZ_Uo2M^T>J$v#G@Dj*HhJuRLk6TJ^o}4$Elq&cjzj?E7X5R1p-phy1&L9#t zap_HRPC@7^Y}%%^oaR&EY$6L;IE!o?!?qGrY&E9ZT1>-8K?GY0@$8EGU@SR$9?P4=Z+-1oE&s7Q0V}YIV!={S5B-97bd3kDW{adi(>aGn zD9Krb8V<1wS<@lhN6GynVGj3YSU#6tC~+;3GM#157%Yhv6S=4Y;n(aJu!)=&V_%m5+1V&V`h?YZSLm$ zEgf^8O`KHTVt-WvoMa^rgd-{u=vt=Lr}iG!6;wtU$o`L6qOpCI!V3aoUU@s zG98n`P|+>{3<`@zqckK|-oZq_jaDAoD?R}uHZA~k>|UQ-o2*QK40o@m)>0d#?Q`|; zVCDLLWN^Zm2$)xCqgchMoaABz5XzIw3r^5E4I3UtJj0DT6}y1eO0;Yv6GfgS-B)bOJ4 zscK&}uzjW$8mVa`lFY0g;vP9j6llnKlM+gOxZf~xrcDfk`=okz3)~~8%bhGx#7zc7 zl;}ibrMgKQ!+8TL1t6 diff --git a/flask_prompt_master/__pycache__/forms.cpython-312.pyc b/flask_prompt_master/__pycache__/forms.cpython-312.pyc deleted file mode 100644 index 39d12acc1c671afebba716a762ac685f79ac4149..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1159 zcmb_bOK1~87@pltvYW?Nt)eXj1x4s;so+7dlu|)bUj$!RU8~DBGmVRxq@CSWdyxuN zdl3tY%|XzE3MIuNo~$5v6fcqH(gEo~Thp7+dhw$F>?S_IqjUK7f6e6ozwgg`T~8o5 zKUyAN+94zKNjQxYtsAQtj46Z>mhy;7rX&el&dXFW6&f)kG-^hJn39iC)l{iwYBX-f zB_yLhgd^h!M~PHc!uQNX5RE}p{Ue$j)r|OxC@~}+Pv>p-a=OT

X{)x#k^U#7;XT zk9qQxKS&)fbW(>49?20Fcu<=-Y03OVl*PiA~NNZ3ickR#c!ix9QC zvzh^83K3*V7@4w+h=L`+NV#4Bb`;B4nTeEvCUJ7|OtfK}G03YpR+hq?sg0_J#uLX` zkq&!e3_k^#+M9bzH=iy)xV`*vW<``bHQ;1g<_dKR0QR+Mi6^euc?a8Gk-7dlsQGgL z(elLP^4-ZVPv&Z~cQQttYnD~8DX}b`uq;}{eqPuq%Np_Re3)SoxXM%kVn&{D3d6o< zdB7wSy7HJCusDrY!9(A79_$*h9nZ}U3<>6~;h=Mi+O9{~zz|H}b`FoSB-92V-f#_o zakQ{uYw7x{?$$`8HSxe*YzZJL$>Hnz! zC=$o&FGUh!y?8232p+Vv!D{(2_{rMr_|n8JCgfQWLor>zdVof{_Ixf-4Md3yPn*@l*Lc-%<@ffo`r;rPD;A*x=DJg{1v(2J%i-3TVR$;X@KwNhB z0sygkYpMN3>Sfd0WaapYO8?nv@43nzv#OsTOD{CFl@84}?Hua^ic4GP_4WqC;-!p{ z;_*<(tKJY3e>|>&C1eaYBN$b*%$w`+&fk0YdvBO%CsaM?@b9j<)*WtN58DoPVx!#- sfUk-qNgvU+Mb!NPbuXgc52$x7B1;{Ut!oHAYnmb%ll#9R_yipM1l(gJ7ytkO diff --git a/flask_prompt_master/__pycache__/init_db.cpython-312.pyc b/flask_prompt_master/__pycache__/init_db.cpython-312.pyc deleted file mode 100644 index e0e7a52d9012db7e6873ce0e7e887b61a17eec7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103819 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 UtAc>C5GUPy9OEM5BkSt_2U~S_ZvX%Q diff --git a/flask_prompt_master/app.db b/flask_prompt_master/app.db deleted file mode 100644 index c540eb25118d2e18f928376bd0aeacc63e8cf988..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94208 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 AEC2ui diff --git a/flask_prompt_master/app.py b/flask_prompt_master/app.py deleted file mode 100644 index b05fed0..0000000 --- a/flask_prompt_master/app.py +++ /dev/null @@ -1,239 +0,0 @@ -from flask import Flask, jsonify, request -from flask_cors import CORS -from datetime import datetime - -app = Flask(__name__) -CORS(app) # 允许跨域请求 - -# 模拟数据库中的模板数据 -MOCK_TEMPLATES = [ - { - "id": "1", - "name": "后端开发工程师", - "description": "专业的后端开发工程师模板", - "category": "软件开发", - "industry": "互联网", - "profession": "开发工程师", - "sub_category": "后端开发", - "system_prompt": "你是一位专业的后端开发工程师..." - }, - { - "id": "2", - "name": "前端开发工程师", - "description": "专业的前端开发工程师模板", - "category": "软件开发", - "industry": "互联网", - "profession": "开发工程师", - "sub_category": "前端开发", - "system_prompt": "你是一位专业的前端开发工程师..." - } -] - -# 身份验证装饰器 -def require_auth(f): - from functools import wraps - @wraps(f) - def decorated(*args, **kwargs): - auth_header = request.headers.get('Authorization') - if not auth_header or not auth_header.startswith('Bearer '): - return jsonify({'error': 'No authorization token provided'}), 401 - # 这里简单验证token,实际应该更严格 - token = auth_header.split(' ')[1] - if token != 'test_token_123': - return jsonify({'error': 'Invalid token'}), 401 - return f(*args, **kwargs) - return decorated - -# 获取模板列表接口 -@app.route('/api/v1/templates', methods=['GET']) -@require_auth -def get_templates(): - # 获取查询参数 - page = int(request.args.get('page', 1)) - size = int(request.args.get('size', 10)) - category = request.args.get('category') - industry = request.args.get('industry') - profession = request.args.get('profession') - - # 过滤模板 - filtered_templates = MOCK_TEMPLATES - if category: - filtered_templates = [t for t in filtered_templates if t['category'] == category] - if industry: - filtered_templates = [t for t in filtered_templates if t['industry'] == industry] - if profession: - filtered_templates = [t for t in filtered_templates if t['profession'] == profession] - - # 计算分页 - start = (page - 1) * size - end = start + size - paginated_templates = filtered_templates[start:end] - - return jsonify({ - 'code': 200, - 'data': { - 'total': len(filtered_templates), - 'pages': (len(filtered_templates) + size - 1) // size, - 'current_page': page, - 'templates': paginated_templates - } - }) - -# 获取单个模板接口 -@app.route('/api/v1/templates/', methods=['GET']) -@require_auth -def get_template(template_id): - template = next((t for t in MOCK_TEMPLATES if t['id'] == template_id), None) - if not template: - return jsonify({'error': 'Template not found'}), 404 - - return jsonify({ - 'code': 200, - 'data': template - }) - -# 创建模板接口 -@app.route('/api/v1/templates', methods=['POST']) -@require_auth -def create_template(): - data = request.get_json() - - # 验证必要字段 - required_fields = ['name', 'description', 'category', 'industry', 'profession'] - for field in required_fields: - if field not in data: - return jsonify({'error': f'Missing required field: {field}'}), 400 - - # 创建新模板 - new_template = { - 'id': str(len(MOCK_TEMPLATES) + 1), - **data, - 'created_at': datetime.now().isoformat() - } - MOCK_TEMPLATES.append(new_template) - - return jsonify({ - 'code': 200, - 'data': { - 'id': new_template['id'], - 'message': 'Template created successfully' - } - }) - -# 更新模板接口 -@app.route('/api/v1/templates/', methods=['PUT']) -@require_auth -def update_template(template_id): - template = next((t for t in MOCK_TEMPLATES if t['id'] == template_id), None) - if not template: - return jsonify({'error': 'Template not found'}), 404 - - data = request.get_json() - template.update(data) - - return jsonify({ - 'code': 200, - 'data': { - 'message': 'Template updated successfully' - } - }) - -# 删除模板接口 -@app.route('/api/v1/templates/', methods=['DELETE']) -@require_auth -def delete_template(template_id): - template_index = next((i for i, t in enumerate(MOCK_TEMPLATES) if t['id'] == template_id), None) - if template_index is None: - return jsonify({'error': 'Template not found'}), 404 - - MOCK_TEMPLATES.pop(template_index) - - return jsonify({ - 'code': 200, - 'data': { - 'message': 'Template deleted successfully' - } - }) - -# 模糊搜索提示词模板接口 -@app.route('/api/v1/templates/search', methods=['GET']) -@require_auth -def search_templates(): - """模糊搜索提示词模板""" - # 获取搜索参数 - keyword = request.args.get('keyword', '').strip() - page = int(request.args.get('page', 1)) - size = int(request.args.get('size', 10)) - - # 如果没有关键词,返回空结果 - if not keyword: - return jsonify({ - 'code': 200, - 'data': { - 'total': 0, - 'pages': 0, - 'current_page': page, - 'templates': [] - } - }) - - # 执行模糊搜索 - # 搜索范围:名称、描述、分类、行业、职业、子分类、系统提示词 - search_results = [] - for template in MOCK_TEMPLATES: - # 在各个字段中搜索关键词 - if any(keyword.lower() in str(value).lower() for value in [ - template.get('name', ''), - template.get('description', ''), - template.get('category', ''), - template.get('industry', ''), - template.get('profession', ''), - template.get('sub_category', ''), - template.get('system_prompt', '') - ]): - # 添加匹配度信息 - match_score = sum( - str(value).lower().count(keyword.lower()) - for value in [ - template.get('name', ''), - template.get('description', ''), - template.get('category', ''), - template.get('industry', ''), - template.get('profession', ''), - template.get('sub_category', ''), - template.get('system_prompt', '') - ] - ) - search_results.append({ - **template, - '_match_score': match_score - }) - - # 按匹配度排序 - search_results.sort(key=lambda x: x['_match_score'], reverse=True) - - # 移除匹配度信息 - search_results = [{k: v for k, v in t.items() if k != '_match_score'} - for t in search_results] - - # 计算分页 - total = len(search_results) - total_pages = (total + size - 1) // size - start = (page - 1) * size - end = start + size - paginated_results = search_results[start:end] - - # 返回结果 - return jsonify({ - 'code': 200, - 'data': { - 'total': total, - 'pages': total_pages, - 'current_page': page, - 'keyword': keyword, - 'templates': paginated_results - } - }) - -if __name__ == '__main__': - app.run(debug=True, port=5000) \ No newline at end of file diff --git a/flask_prompt_master/forms.py b/flask_prompt_master/forms.py deleted file mode 100644 index f6b5f68..0000000 --- a/flask_prompt_master/forms.py +++ /dev/null @@ -1,12 +0,0 @@ -from flask_wtf import FlaskForm -from wtforms import TextAreaField, SubmitField, IntegerField -from wtforms.validators import DataRequired, Length, NumberRange - -class PromptForm(FlaskForm): - input_text = TextAreaField('输入文本', validators=[DataRequired(), Length(min=1, max=1000)]) - submit = SubmitField('生成提示词') - -class FeedbackForm(FlaskForm): - rating = IntegerField('评分', validators=[DataRequired(), NumberRange(min=1, max=5)]) - comment = TextAreaField('评论') - submit = SubmitField('提交反馈') \ No newline at end of file diff --git a/flask_prompt_master/models.py b/flask_prompt_master/models.py deleted file mode 100644 index a5195d8..0000000 --- a/flask_prompt_master/models.py +++ /dev/null @@ -1,89 +0,0 @@ -from flask_prompt_master import db -from datetime import datetime - -class User(db.Model): - __tablename__ = 'user' - - uid = db.Column(db.Integer, primary_key=True) - nickname = db.Column(db.String(100), nullable=False) - mobile = db.Column(db.String(20), nullable=True) - email = db.Column(db.String(100), nullable=True) - sex = db.Column(db.Integer, nullable=False, default=0) - avatar = db.Column(db.String(64), nullable=True) - login_name = db.Column(db.String(20), nullable=False, unique=True) - login_pwd = db.Column(db.String(32), nullable=False) - login_salt = db.Column(db.String(32), nullable=False) - status = db.Column(db.Integer, nullable=False, default=1) - openid = db.Column(db.String(64), unique=True) - session_key = db.Column(db.String(64)) - unionid = db.Column(db.String(64), unique=True) - wx_nickname = db.Column(db.String(100)) - wx_avatar = db.Column(db.String(255)) - updated_time = db.Column(db.DateTime, default=datetime.utcnow) - created_time = db.Column(db.DateTime, default=datetime.utcnow) - - prompts = db.relationship('Prompt', backref='author', lazy='dynamic') - feedbacks = db.relationship('Feedback', backref='author', lazy='dynamic') - -class WxUser(db.Model): - """微信小程序用户表""" - __tablename__ = 'wx_user' - - id = db.Column(db.Integer, primary_key=True) - openid = db.Column(db.String(64), unique=True, nullable=False) - session_key = db.Column(db.String(64)) - unionid = db.Column(db.String(64), unique=True) - nickname = db.Column(db.String(100)) - avatar_url = db.Column(db.String(255)) - gender = db.Column(db.Integer, default=0) # 0:未知, 1:男, 2:女 - country = db.Column(db.String(50)) - province = db.Column(db.String(50)) - city = db.Column(db.String(50)) - language = db.Column(db.String(20)) - phone = db.Column(db.String(20)) - is_active = db.Column(db.Boolean, default=True) - last_login = db.Column(db.DateTime, default=datetime.utcnow) - created_at = db.Column(db.DateTime, default=datetime.utcnow) - updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) - - # 关联到提示词和反馈 - prompts = db.relationship('Prompt', backref='wx_user', lazy='dynamic', - foreign_keys='Prompt.wx_user_id') - feedbacks = db.relationship('Feedback', backref='wx_user', lazy='dynamic', - foreign_keys='Feedback.wx_user_id') - -class Prompt(db.Model): - __tablename__ = 'prompt' - - id = db.Column(db.Integer, primary_key=True) - input_text = db.Column(db.Text, nullable=False) - generated_text = db.Column(db.Text, nullable=False) - created_at = db.Column(db.DateTime, default=datetime.utcnow) - user_id = db.Column(db.Integer, db.ForeignKey('user.uid')) # 修改为可空 - wx_user_id = db.Column(db.Integer, db.ForeignKey('wx_user.id')) # 添加微信用户ID - feedbacks = db.relationship('Feedback', backref='prompt', lazy='dynamic') - -class Feedback(db.Model): - __tablename__ = 'feedback' - - id = db.Column(db.Integer, primary_key=True) - rating = db.Column(db.Integer, nullable=False) - comment = db.Column(db.Text) - created_at = db.Column(db.DateTime, default=datetime.utcnow) - user_id = db.Column(db.Integer, db.ForeignKey('user.uid')) # 修改为可空 - wx_user_id = db.Column(db.Integer, db.ForeignKey('wx_user.id')) # 添加微信用户ID - prompt_id = db.Column(db.Integer, db.ForeignKey('prompt.id'), nullable=False) - -class PromptTemplate(db.Model): - __tablename__ = 'prompt_template' - - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String(100), nullable=False) - description = db.Column(db.Text) - category = db.Column(db.String(50)) - industry = db.Column(db.String(50)) - profession = db.Column(db.String(50)) - sub_category = db.Column(db.String(50)) - system_prompt = db.Column(db.Text, nullable=False) - is_default = db.Column(db.Boolean, default=False) - created_at = db.Column(db.DateTime, default=datetime.utcnow) \ No newline at end of file diff --git a/flask_prompt_master/routes.py b/flask_prompt_master/routes.py deleted file mode 100644 index 1d205fd..0000000 --- a/flask_prompt_master/routes.py +++ /dev/null @@ -1,1177 +0,0 @@ -from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, current_app -from openai import OpenAI -from flask_prompt_master import db -from flask_prompt_master.models import User, Prompt, Feedback, PromptTemplate, WxUser -from flask_prompt_master.forms import PromptForm, FeedbackForm -from config import Config -import pymysql -from datetime import datetime -import requests -import hashlib -import time -import json - -main_bp = Blueprint('main', __name__) - -client = OpenAI(api_key=Config.LLM_API_KEY, base_url=Config.LLM_API_URL) - -# 从配置中获取微信小程序配置 -WX_APPID = Config.WX_APPID -WX_SECRET = Config.WX_SECRET - -def get_system_prompt(template_id=None): - """获取系统提示词模板""" - if template_id: - template = PromptTemplate.query.get(template_id) - if template: - return template.system_prompt - - # 如果没有指定模板ID或模板不存在,返回默认模板 - default_template = PromptTemplate.query.filter_by(is_default=True).first() - if default_template: - return default_template.system_prompt - - # 如果数据库中没有模板,返回硬编码的默认模板 - return """你是一个专业的提示词工程师,擅长将普通的描述转换为结构化、专业的 Prompt。 - -你需要: -1. 分析用户的需求和意图 -2. 将其转换为清晰、详细的提示词 -3. 添加必要的上下文和约束条件 -4. 使用专业的术语和格式 -5. 确保生成的提示词能够获得最佳的 AI 响应 - -请直接返回优化后的提示词,不要添加任何解释或其他内容。""" - -def generate_with_llm(input_text, template_id=None): - """调用大模型API生成提示词""" - try: - system_prompt = get_system_prompt(template_id) - - # 打印参数 - print("\n=== API 调用参数 ===") - print(f"模板ID: {template_id}") - print(f"输入文本: {input_text}") - print(f"系统提示: {system_prompt}") - print("==================\n") - - response = client.chat.completions.create( - model="deepseek-chat", - messages=[ - {"role": "system", "content": system_prompt}, - {"role": "user", "content": input_text} - ], - temperature=0.7, - max_tokens=500 - ) - - # 打印响应 - generated_text = response.choices[0].message.content.strip() - print("\n=== API 响应结果 ===") - print(f"生成的提示词: {generated_text}") - print("==================\n") - - return generated_text - except Exception as e: - current_app.logger.error(f'LLM API调用失败: {str(e)}') - return "提示词生成失败,请稍后重试" - -def get_template_icon(category): - """根据分类返回对应的Font Awesome图标类名""" - icons = { - '通用工具': 'fa-magic', - '内容创作': 'fa-pen-fancy', - '设计创意': 'fa-palette', - '技术研发': 'fa-code', - '商业营销': 'fa-chart-line', - '专业服务': 'fa-briefcase', - '教育培训': 'fa-graduation-cap', - '智慧城市': 'fa-city', - '工业制造': 'fa-industry', - '生活服务': 'fa-concierge-bell' - } - return icons.get(category, 'fa-star') # 默认返回星星图标 - -@main_bp.route('/', methods=['GET', 'POST']) -def index(): - form = PromptForm() - templates = PromptTemplate.query.all() - - # 获取所有可用的分类选项 - industries = sorted(set(t.industry for t in templates if t.industry)) - professions = sorted(set(t.profession for t in templates if t.profession)) - categories = sorted(set(t.category for t in templates if t.category)) - sub_categories = sorted(set(t.sub_category for t in templates if t.sub_category)) - - if form.validate_on_submit(): - template_id = request.form.get('template_id') - generated_text = generate_with_llm(form.input_text.data, template_id) - - # 获取默认用户的 uid - try: - conn = pymysql.connect( - host='localhost', - user='root', - password='123456', - database='food_db', - charset='utf8mb4' - ) - cursor = conn.cursor() - cursor.execute("SELECT uid FROM user WHERE login_name = 'admin' LIMIT 1") - result = cursor.fetchone() - if result: - user_id = result[0] - else: - user_id = 1 # 如果没有找到用户,使用默认值 - cursor.close() - conn.close() - except Exception as e: - print(f"获取用户ID失败: {str(e)}") - user_id = 1 # 如果查询失败,使用默认值 - - prompt = Prompt( - input_text=form.input_text.data, - generated_text=generated_text, - user_id=user_id # 使用查询到的用户ID - ) - db.session.add(prompt) - db.session.commit() - return render_template('generate.html', form=form, prompt=prompt, templates=templates, - get_template_icon=get_template_icon, industries=industries, - professions=professions, categories=categories, - sub_categories=sub_categories) - return render_template('generate.html', form=form, prompt=None, templates=templates, - get_template_icon=get_template_icon, industries=industries, - professions=professions, categories=categories, - sub_categories=sub_categories) - -@main_bp.route('/prompt/') -def show_prompt(prompt_id): - prompt = Prompt.query.get_or_404(prompt_id) - return render_template('prompt.html', prompt=prompt) - -@main_bp.route('/feedback/', methods=['GET', 'POST']) -def submit_feedback(prompt_id): - prompt = Prompt.query.get_or_404(prompt_id) - form = FeedbackForm() - if form.validate_on_submit(): - feedback = Feedback( - rating=form.rating.data, - comment=form.comment.data, - user_id=1, # 临时用户ID - prompt_id=prompt.id - ) - db.session.add(feedback) - db.session.commit() - flash('感谢您的反馈!') - return redirect(url_for('main.show_prompt', prompt_id=prompt.id)) - return render_template('feedback.html', form=form, prompt=prompt) - -# 添加一个API端点来获取模板详情 -@main_bp.route('/api/template/') -def get_template_details(template_id): - template = PromptTemplate.query.get_or_404(template_id) - return jsonify({ - 'id': template.id, - 'name': template.name, - 'description': template.description, - 'system_prompt': template.system_prompt - }) - -# 添加删除模板的API路由 -@main_bp.route('/api/templates/', methods=['DELETE']) -def delete_template(template_id): - try: - # 查找模板 - template = PromptTemplate.query.get_or_404(template_id) - - # 检查是否是默认模板 - if template.is_default: - return jsonify({ - 'success': False, - 'message': '默认模板不能删除' - }), 403 - - # 检查权限(可选:如果需要检查用户是否有权限删除) - # if template.user_id != current_user.id: - # return jsonify({ - # 'success': False, - # 'message': '没有权限删除此模板' - # }), 403 - - # 删除模板 - db.session.delete(template) - db.session.commit() - - return jsonify({ - 'success': True, - 'message': '模板删除成功' - }) - - except Exception as e: - # 回滚事务 - db.session.rollback() - # 记录错误 - current_app.logger.error(f'删除模板失败: {str(e)}') - return jsonify({ - 'success': False, - 'message': '删除模板失败,请稍后重试' - }), 500 - -# 添加微信小程序API路由 -@main_bp.route('/api/wx/generate', methods=['POST']) -def wx_generate_prompt(): - """微信小程序生成提示词接口""" - try: - data = request.get_json() - if not data or 'input_text' not in data or 'uid' not in data: - return jsonify({ - 'code': 400, - 'message': '缺少必要参数', - 'data': None - }) - - input_text = data.get('input_text') - template_id = data.get('template_id') - wx_user_id = data.get('uid') # 使用uid - - # 调用大模型生成提示词 - generated_text = generate_with_llm(input_text, template_id) - - # 保存到数据库 - prompt = Prompt( - input_text=input_text, - generated_text=generated_text, - wx_user_id=wx_user_id, # 使用wx_user_id - created_at=datetime.utcnow() - ) - db.session.add(prompt) - db.session.commit() - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'prompt_id': prompt.id, - 'input_text': prompt.input_text, - 'generated_text': prompt.generated_text, - 'created_at': prompt.created_at.strftime('%Y-%m-%d %H:%M:%S') - } - }) - - except Exception as e: - current_app.logger.error(f"生成提示词失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/templates', methods=['GET']) -def wx_get_templates(): - """获取提示词模板列表""" - try: - # 获取筛选参数 - industry = request.args.get('industry') - profession = request.args.get('profession') - category = request.args.get('category') - sub_category = request.args.get('sub_category') - - # 构建查询 - query = PromptTemplate.query - - if industry: - query = query.filter_by(industry=industry) - if profession: - query = query.filter_by(profession=profession) - if category: - query = query.filter_by(category=category) - if sub_category: - query = query.filter_by(sub_category=sub_category) - - templates = query.all() - - # 返回模板列表 - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': [{ - 'id': t.id, - 'name': t.name, - 'description': t.description, - 'category': t.category, - 'industry': t.industry, - 'profession': t.profession, - 'sub_category': t.sub_category, - 'is_default': t.is_default - } for t in templates] - }) - - except Exception as e: - current_app.logger.error(f"获取模板列表失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/template/', methods=['GET']) -def wx_get_template_detail(template_id): - """获取模板详情""" - try: - template = PromptTemplate.query.get_or_404(template_id) - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'id': template.id, - 'name': template.name, - 'description': template.description, - 'category': template.category, - 'industry': template.industry, - 'profession': template.profession, - 'sub_category': template.sub_category, - 'system_prompt': template.system_prompt, - 'is_default': template.is_default - } - }) - - except Exception as e: - current_app.logger.error(f"获取模板详情失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/login', methods=['POST']) -def wx_login(): - """微信小程序登录接口""" - try: - # 添加调试日志 - print("\n=== 微信登录配置 ===") - print(f"APPID: {WX_APPID}") - print(f"SECRET: {WX_SECRET}") - print("==================\n") - - data = request.get_json() - if not data or 'code' not in data: - return jsonify({ - 'code': 400, - 'message': '缺少code参数', - 'data': None - }) - - code = data.get('code') - print(f"收到的code: {code}") - - # 请求微信接口 - wx_url = 'https://api.weixin.qq.com/sns/jscode2session' - params = { - 'appid': WX_APPID, - 'secret': WX_SECRET, - 'js_code': code, - 'grant_type': 'authorization_code' - } - - response = requests.get(wx_url, params=params) - wx_data = response.json() - print(f"微信返回数据: {wx_data}") - - if 'errcode' in wx_data: - return jsonify({ - 'code': 500, - 'message': f"微信登录失败:{wx_data.get('errmsg')}", - 'data': None - }) - - openid = wx_data.get('openid') - session_key = wx_data.get('session_key') - - # 查找或创建微信用户 - wx_user = WxUser.query.filter_by(openid=openid).first() - if not wx_user: - wx_user = WxUser( - openid=openid, - session_key=session_key - ) - db.session.add(wx_user) - db.session.commit() - else: - wx_user.session_key = session_key - wx_user.last_login = datetime.utcnow() - db.session.commit() - - # 生成登录态token - token = hashlib.md5(f'{openid}{int(time.time())}'.encode()).hexdigest() - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'token': token, - 'openid': openid, - 'uid': wx_user.id, - 'user_info': { - 'id': wx_user.id, - 'nickname': wx_user.nickname, - 'avatar_url': wx_user.avatar_url, - 'gender': wx_user.gender, - 'phone': wx_user.phone - } - } - }) - - except Exception as e: - current_app.logger.error(f"微信登录失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/update_userinfo', methods=['POST']) -def wx_update_userinfo(): - """更新微信用户信息""" - try: - data = request.get_json() - if not data or 'openid' not in data: - return jsonify({ - 'code': 400, - 'message': '缺少必要参数', - 'data': None - }) - - openid = data.get('openid') - wx_user = WxUser.query.filter_by(openid=openid).first() - - if not wx_user: - return jsonify({ - 'code': 404, - 'message': '用户不存在', - 'data': None - }) - - # 更新用户信息 - if 'nickName' in data: - wx_user.nickname = data['nickName'] - if 'avatarUrl' in data: - wx_user.avatar_url = data['avatarUrl'] - if 'gender' in data: - wx_user.gender = data['gender'] - if 'country' in data: - wx_user.country = data['country'] - if 'province' in data: - wx_user.province = data['province'] - if 'city' in data: - wx_user.city = data['city'] - if 'language' in data: - wx_user.language = data['language'] - - wx_user.updated_at = datetime.utcnow() - db.session.commit() - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'id': wx_user.id, - 'nickname': wx_user.nickname, - 'avatar_url': wx_user.avatar_url, - 'gender': wx_user.gender, - 'country': wx_user.country, - 'province': wx_user.province, - 'city': wx_user.city, - 'language': wx_user.language, - 'phone': wx_user.phone - } - }) - - except Exception as e: - current_app.logger.error(f"更新用户信息失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/prompts', methods=['GET']) -def wx_get_prompts(): - """获取用户的提示词历史记录""" - try: - # 获取参数 - uid = request.args.get('uid') - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 10, type=int) - - if not uid: - return jsonify({ - 'code': 400, - 'message': '缺少用户ID', - 'data': None - }) - - # 查询该用户的所有提示词记录 - query = Prompt.query.filter_by(wx_user_id=uid)\ - .order_by(Prompt.created_at.desc()) - - # 分页 - pagination = query.paginate(page=page, per_page=per_page, error_out=False) - prompts = pagination.items - - # 返回数据 - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'prompts': [{ - 'id': p.id, - 'input_text': p.input_text, - 'generated_text': p.generated_text, - 'created_at': p.created_at.strftime('%Y-%m-%d %H:%M:%S') - } for p in prompts], - 'pagination': { - 'total': pagination.total, # 总记录数 - 'pages': pagination.pages, # 总页数 - 'current_page': page, # 当前页 - 'per_page': per_page, # 每页记录数 - 'has_next': pagination.has_next, # 是否有下一页 - 'has_prev': pagination.has_prev # 是否有上一页 - } - } - }) - - except Exception as e: - current_app.logger.error(f"获取提示词历史失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/prompt/', methods=['GET']) -def wx_get_prompt_detail(prompt_id): - """获取提示词详情""" - try: - prompt = Prompt.query.get_or_404(prompt_id) - - # 可以选择性地验证用户身份 - # uid = request.args.get('uid') - # if str(prompt.wx_user_id) != str(uid): - # return jsonify({ - # 'code': 403, - # 'message': '无权访问此记录', - # 'data': None - # }) - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'id': prompt.id, - 'input_text': prompt.input_text, - 'generated_text': prompt.generated_text, - 'created_at': prompt.created_at.strftime('%Y-%m-%d %H:%M:%S'), - 'feedbacks': [{ - 'id': f.id, - 'rating': f.rating, - 'comment': f.comment, - 'created_at': f.created_at.strftime('%Y-%m-%d %H:%M:%S') - } for f in prompt.feedbacks] - } - }) - - except Exception as e: - current_app.logger.error(f"获取提示词详情失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/prompts/count', methods=['GET']) -def wx_get_prompts_count(): - """获取用户的提示词历史记录数量""" - try: - # 获取用户ID - uid = request.args.get('uid') - - if not uid: - return jsonify({ - 'code': 400, - 'message': '缺少用户ID', - 'data': None - }) - - # 查询该用户的提示词记录数量 - count = Prompt.query.filter_by(wx_user_id=uid).count() - - # 获取今日记录数量 - today = datetime.now().date() - today_count = Prompt.query.filter_by(wx_user_id=uid)\ - .filter(db.func.date(Prompt.created_at) == today)\ - .count() - - # 获取本月记录数量 - this_month = today.replace(day=1) - month_count = Prompt.query.filter_by(wx_user_id=uid)\ - .filter(db.func.date(Prompt.created_at) >= this_month)\ - .count() - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'total_count': count, # 总记录数 - 'today_count': today_count, # 今日记录数 - 'month_count': month_count, # 本月记录数 - 'uid': uid - } - }) - - except Exception as e: - current_app.logger.error(f"获取提示词历史数量失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/prompt/', methods=['DELETE']) -def wx_delete_prompt(prompt_id): - """删除提示词记录""" - try: - # 从 URL 参数或请求体中获取用户ID - uid = request.args.get('uid') or request.get_json().get('uid') - if not uid: - return jsonify({ - 'code': 400, - 'message': '缺少用户ID', - 'data': None - }) - - # 查找记录 - prompt = Prompt.query.get_or_404(prompt_id) - - # 验证是否是用户自己的记录 - if str(prompt.wx_user_id) != str(uid): - return jsonify({ - 'code': 403, - 'message': '无权删除此记录', - 'data': None - }) - - # 删除相关的反馈 - Feedback.query.filter_by(prompt_id=prompt_id).delete() - - # 删除提示词记录 - db.session.delete(prompt) - db.session.commit() - - return jsonify({ - 'code': 200, - 'message': '删除成功', - 'data': { - 'id': prompt_id - } - }) - - except Exception as e: - current_app.logger.error(f"删除提示词记录失败: {str(e)}") - db.session.rollback() - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/prompts/search', methods=['GET']) -def wx_search_prompts(): - """搜索提示词接口""" - try: - # 获取参数 - uid = request.args.get('uid') - keyword = request.args.get('keyword', '').strip() - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 10, type=int) - - if not uid: - return jsonify({ - 'code': 400, - 'message': '缺少用户ID', - 'data': None - }) - - # 构建查询 - query = Prompt.query.filter_by(wx_user_id=uid) - - # 如果有关键词,添加搜索条件 - if keyword: - search_condition = ( - Prompt.input_text.ilike(f'%{keyword}%') | # 搜索输入文本 - Prompt.generated_text.ilike(f'%{keyword}%') # 搜索生成的提示词 - ) - query = query.filter(search_condition) - - # 按时间倒序排序并分页 - query = query.order_by(Prompt.created_at.desc()) - pagination = query.paginate(page=page, per_page=per_page, error_out=False) - prompts = pagination.items - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'prompts': [{ - 'id': p.id, - 'input_text': p.input_text, - 'generated_text': p.generated_text, - 'created_at': p.created_at.strftime('%Y-%m-%d %H:%M:%S') - } for p in prompts], - 'pagination': { - 'total': pagination.total, - 'pages': pagination.pages, - 'current_page': page, - 'per_page': per_page, - 'has_next': pagination.has_next, - 'has_prev': pagination.has_prev - } - } - }) - - except Exception as e: - current_app.logger.error(f"搜索提示词失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/templates/search', methods=['GET']) -def wx_search_templates(): - """搜索提示词模板接口""" - try: - # 获取搜索参数 - keyword = request.args.get('keyword', '').strip() - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 10, type=int) - - # 构建基础查询 - query = PromptTemplate.query - - # 添加搜索条件 - if keyword: - search_condition = ( - PromptTemplate.name.ilike(f'%{keyword}%') | # 搜索模板名称 - PromptTemplate.description.ilike(f'%{keyword}%') | # 搜索模板描述 - PromptTemplate.category.ilike(f'%{keyword}%') | # 搜索分类 - PromptTemplate.industry.ilike(f'%{keyword}%') | # 搜索行业 - PromptTemplate.profession.ilike(f'%{keyword}%') | # 搜索职业 - PromptTemplate.system_prompt.ilike(f'%{keyword}%') # 搜索系统提示词 - ) - query = query.filter(search_condition) - - # 获取筛选参数(可选) - industry = request.args.get('industry') - profession = request.args.get('profession') - category = request.args.get('category') - - # 添加筛选条件 - if industry: - query = query.filter_by(industry=industry) - if profession: - query = query.filter_by(profession=profession) - if category: - query = query.filter_by(category=category) - - # 按是否默认模板和创建时间排序 - query = query.order_by(PromptTemplate.is_default.desc(), - PromptTemplate.created_at.desc()) - - # 分页 - pagination = query.paginate(page=page, per_page=per_page, error_out=False) - templates = pagination.items - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'templates': [{ - 'id': t.id, - 'name': t.name, - 'description': t.description, - 'system_prompt': t.system_prompt, # 添加system_prompt字段 - 'category': t.category, - 'industry': t.industry, - 'profession': t.profession, - 'sub_category': t.sub_category, - 'is_default': t.is_default, - 'created_at': t.created_at.strftime('%Y-%m-%d %H:%M:%S') if t.created_at else None - } for t in templates], - 'pagination': { - 'total': pagination.total, - 'pages': pagination.pages, - 'current_page': page, - 'per_page': per_page, - 'has_next': pagination.has_next, - 'has_prev': pagination.has_prev - } - } - }) - - except Exception as e: - current_app.logger.error(f"搜索模板失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/templates/intent', methods=['POST']) -def wx_get_template_by_intent(): - """根据意图获取提示词模板""" - try: - # 获取参数 - data = request.get_json() - user_input = data.get('input_text', '').strip() - - # 意图识别系统提示词 - intent_system_prompt = """你是一位出色的意图识别专家。请分析用户输入的意图,并仅返回以下类别之一: -- 新闻获取 -- 生成图片 -- 网站开发 -- 文案创作 -- 代码开发 -- 数据分析 -- 市场营销 -- 产品设计 -- 其它 - -只返回分类名称,不要其他任何内容。""" - - # 调用意图识别 - response = client.chat.completions.create( - model="deepseek-chat", - messages=[ - {"role": "system", "content": intent_system_prompt}, - {"role": "user", "content": user_input} - ], - temperature=0.1 - ) - - intent = response.choices[0].message.content.strip() - - # 根据意图获取对应的模板提示词 - intent_prompts = { - "新闻获取": "你是一位专业的新闻编辑,擅长整理和总结新闻信息。请帮助用户获取和理解新闻内容,注意:\n1. 确保信息的准确性和时效性\n2. 提供客观中立的视角\n3. 突出重要信息要点\n4. 适当添加背景信息解释", - - "生成图片": "你是一位专业的图像生成提示词专家,擅长将文字需求转化为详细的图像生成提示词。请注意:\n1. 详细描述图像的视觉元素\n2. 指定图像的风格和氛围\n3. 添加技术参数说明\n4. 包含构图和视角建议", - - "网站开发": "你是一位专业的网站开发专家,擅长将需求转化为具体的开发方案。请注意:\n1. 明确网站的目标用户和核心功能\n2. 建议合适的技术栈\n3. 考虑性能和安全性要求\n4. 提供响应式设计建议", - - "文案创作": "你是一位专业的文案创作专家,擅长创作各类营销和品牌文案。请注意:\n1. 确定目标受众和传播渠道\n2. 突出产品/服务的核心价值\n3. 使用适当的语言风格\n4. 注意文案的节奏和结构", - - "代码开发": "你是一位专业的软件开发工程师,擅长编写高质量的代码。请注意:\n1. 遵循编码规范和最佳实践\n2. 考虑代码的可维护性和扩展性\n3. 注重性能优化\n4. 添加适当的注释和文档", - - "数据分析": "你是一位专业的数据分析师,擅长数据处理和分析。请注意:\n1. 明确分析目标和范围\n2. 选择合适的分析方法\n3. 关注数据质量和准确性\n4. 提供可操作的洞察建议", - - "市场营销": "你是一位专业的市场营销专家,擅长制定营销策略。请注意:\n1. 分析目标市场和竞争环境\n2. 制定明确的营销目标\n3. 选择合适的营销渠道\n4. 设计有效的营销活动", - - "产品设计": "你是一位专业的产品设计师,擅长用户体验和界面设计。请注意:\n1. 理解用户需求和痛点\n2. 遵循设计原则和规范\n3. 注重交互体验\n4. 考虑可实现性", - - "其它": "你是一位专业的AI助手,擅长理解和解决各类问题。请注意:\n1. 仔细理解用户需求\n2. 提供清晰的解决方案\n3. 使用专业的语言表达\n4. 确保回答的实用性" - } - - template_prompt = intent_prompts.get(intent, intent_prompts["其它"]) - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'intent': intent, - 'template_prompt': template_prompt - } - }) - - except Exception as e: - current_app.logger.error(f"获取意图模板失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/api/wx/generate/expert', methods=['POST']) -def wx_generate_expert_prompt(): - """两阶段专家提示词生成系统""" - try: - # 检查请求数据 - if not request.is_json: - return jsonify({ - 'code': 400, - 'message': '请求必须是JSON格式', - 'data': None - }) - - data = request.get_json() - if not data: - return jsonify({ - 'code': 400, - 'message': '请求数据为空', - 'data': None - }) - - # 验证必要参数 - user_input = data.get('input_text') - uid = data.get('uid') - - if not user_input or not uid: - return jsonify({ - 'code': 400, - 'message': '缺少必要参数:input_text 或 uid', - 'data': None - }) - - user_input = user_input.strip() - - # 修改第一阶段:意图识别专家的提示词,使其更严格 - intent_analyst_prompt = """你是一位资深的意图分析专家,请分析用户输入的意图和需求。 - -你必须严格按照以下JSON格式返回,不要添加任何其他内容: -{ - "core_intent": "技术", // 必须是以下选项之一:技术、创意、分析、咨询 - "domain": "web开发", // 具体的专业领域 - "key_requirements": [ // 2-4个关键需求 - "需求1", - "需求2" - ], - "expected_output": "期望输出的具体形式", // 简短描述 - "constraints": [ // 1-3个主要约束 - "约束1", - "约束2" - ], - "keywords": [ // 2-4个关键词 - "关键词1", - "关键词2" - ] -} - -注意: -1. 严格遵守JSON格式 -2. core_intent必须是四个选项之一 -3. 数组至少包含1个元素 -4. 所有字段都必须存在 -5. 不要包含注释 -6. 不要添加任何额外的文本""" - - try: - # 获取意图分析结果 - intent_response = client.chat.completions.create( - model="deepseek-chat", - messages=[ - {"role": "system", "content": intent_analyst_prompt}, - {"role": "user", "content": user_input} - ], - temperature=0.1 # 降低温度,使输出更确定 - ) - - intent_analysis_text = intent_response.choices[0].message.content.strip() - - # 添加日志记录 - current_app.logger.info(f"AI返回的意图分析结果: {intent_analysis_text}") - - # 尝试清理和解析JSON - try: - # 移除可能的markdown代码块标记 - intent_analysis_text = intent_analysis_text.replace('```json', '').replace('```', '').strip() - intent_analysis = json.loads(intent_analysis_text) - - # 验证必要字段 - required_fields = ['core_intent', 'domain', 'key_requirements', - 'expected_output', 'constraints', 'keywords'] - for field in required_fields: - if field not in intent_analysis: - raise ValueError(f"缺少必要字段: {field}") - - # 验证core_intent是否为有效值 - valid_intents = ['技术', '创意', '分析', '咨询'] - if intent_analysis['core_intent'] not in valid_intents: - intent_analysis['core_intent'] = '技术' # 默认使用技术 - - # 确保数组字段非空 - array_fields = ['key_requirements', 'constraints', 'keywords'] - for field in array_fields: - if not isinstance(intent_analysis[field], list) or len(intent_analysis[field]) == 0: - intent_analysis[field] = ['未指定'] - - except json.JSONDecodeError as e: - current_app.logger.error(f"JSON解析失败: {str(e)}, 原始文本: {intent_analysis_text}") - return jsonify({ - 'code': 500, - 'message': 'AI返回的格式有误,请重试', - 'data': None - }) - except ValueError as e: - current_app.logger.error(f"数据验证失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - - except Exception as e: - current_app.logger.error(f"意图分析失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': '意图分析过程出错,请重试', - 'data': None - }) - - # 第二阶段:领域专家提示生成 - domain_expert_templates = { - "技术": """你是一位专业的技术领域提示工程师。基于以下意图分析,生成一个专业的技术任务提示词: - -意图分析: -{analysis} - -请生成的提示词包含: -1. 明确的技术背景和上下文 -2. 具体的技术要求和规范 -3. 性能和质量标准 -4. 技术约束条件 -5. 预期交付成果 -6. 评估标准 - -使用专业技术术语,确保提示词的可执行性和可验证性。""", - - "创意": """你是一位专业的创意领域提示工程师。基于以下意图分析,生成一个创意设计提示词: - -意图分析: -{analysis} - -请生成的提示词包含: -1. 创意方向和灵感来源 -2. 风格和氛围要求 -3. 目标受众定义 -4. 设计元素规范 -5. 创意表现形式 -6. 评估标准 - -使用专业创意术语,确保提示词的创新性和可执行性。""", - - "分析": """你是一位专业的数据分析提示工程师。基于以下意图分析,生成一个数据分析提示词: - -意图分析: -{analysis} - -请生成的提示词包含: -1. 分析目标和范围 -2. 数据要求和规范 -3. 分析方法和工具 -4. 输出格式要求 -5. 关键指标定义 -6. 质量控制标准 - -使用专业分析术语,确保提示词的科学性和可操作性。""", - - "咨询": """你是一位专业的咨询领域提示工程师。基于以下意图分析,生成一个咨询服务提示词: - -意图分析: -{analysis} - -请生成的提示词包含: -1. 咨询问题界定 -2. 背景信息要求 -3. 分析框架设定 -4. 建议输出格式 -5. 实施考虑因素 -6. 效果评估标准 - -使用专业咨询术语,确保提示词的专业性和实用性。""" - } - - # 选择领域专家模板 - expert_prompt = domain_expert_templates.get( - intent_analysis['core_intent'], - """你是一位专业的通用领域提示工程师。基于以下意图分析,生成一个专业的提示词: - -意图分析: -{analysis} - -请生成的提示词包含: -1. 明确的目标定义 -2. 具体要求和规范 -3. 质量标准 -4. 约束条件 -5. 预期输出 -6. 评估标准 - -确保提示词的清晰性和可执行性。""" - ) - - try: - # 生成最终提示词 - final_response = client.chat.completions.create( - model="deepseek-chat", - messages=[ - {"role": "system", "content": expert_prompt.format( - analysis=json.dumps(intent_analysis, ensure_ascii=False, indent=2) - )}, - {"role": "user", "content": user_input} - ], - temperature=0.7 - ) - - generated_prompt = final_response.choices[0].message.content.strip() - - except Exception as e: - current_app.logger.error(f"生成提示词失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': '生成提示词过程出错', - 'data': None - }) - - try: - # 保存到数据库 - prompt = Prompt( - input_text=user_input, - generated_text=generated_prompt, - wx_user_id=uid, - #intent_analysis=json.dumps(intent_analysis, ensure_ascii=False), - created_at=datetime.utcnow() - ) - db.session.add(prompt) - db.session.commit() - - except Exception as e: - current_app.logger.error(f"保存到数据库失败: {str(e)}") - db.session.rollback() - # 即使保存失败,也返回生成的结果 - - return jsonify({ - 'code': 200, - 'message': 'success', - 'data': { - 'prompt_id': prompt.id if 'prompt' in locals() else None, - 'intent_analysis': intent_analysis, - 'generated_prompt': generated_prompt, - 'created_at': prompt.created_at.strftime('%Y-%m-%d %H:%M:%S') if 'prompt' in locals() else None - } - }) - - except Exception as e: - current_app.logger.error(f"生成专家提示词失败: {str(e)}") - return jsonify({ - 'code': 500, - 'message': str(e), - 'data': None - }) - -@main_bp.route('/expert_generate') -def expert_generate(): - """专家提示词生成页面""" - return render_template('expert_generate.html') - -# ... 其他路由保持不变,但要把 @app 改成 @main_bp ... \ No newline at end of file diff --git a/flask_prompt_master/static/css/style.css b/flask_prompt_master/static/css/style.css deleted file mode 100644 index 1477de7..0000000 --- a/flask_prompt_master/static/css/style.css +++ /dev/null @@ -1,18 +0,0 @@ -.prompt-container { - display: flex; - flex-wrap: wrap; - gap: 16px; - padding: 20px; - max-width: 1200px; - margin: 0 auto; -} - -.prompt-card { - width: calc((100% - 64px) / 5); - min-width: 180px; - margin: 0; - background: #fff; - border-radius: 8px; - padding: 12px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} \ No newline at end of file diff --git a/flask_prompt_master/templates/__pycache__/__init__.cpython-312.pyc b/flask_prompt_master/templates/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 62a9cdc603b35e5e6c647bb69d44080324b76dee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191 zcmX@j%ge<81kRERGUS2uV-N=hn4pZ$0zk%eh7^Vr#vF!R#wbQchDs()=9i2>VNJ$c zoF%Eb1v!Z&sl|SpOt;tzit=*{N{Wk^fwC(ZK7-8oW#nQNlbBgjoE(#ulUSS`4^b1J zn^;_uS`-7<9}^#+nU`4-AFo$Xd5gm)H$SB`C)KWq184-uu3`}512ZEd<2?qsA~qlg E035$CVE_OC diff --git a/flask_prompt_master/templates/__pycache__/prompts.cpython-312.pyc b/flask_prompt_master/templates/__pycache__/prompts.cpython-312.pyc deleted file mode 100644 index 4bce57778051ff3e22d8f7156441658f9a1d82a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51694 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 P_zy5BW5zbg 0 + + if exists: + print(f"模板已存在,跳过: {template['name']}") + duplicate_count += 1 + continue + + # 准备模板数据 + template_data = { + 'name': template['name'], + 'description': template['description'], + 'category': template.get('category', ''), + 'industry': template.get('industry', ''), + 'profession': template.get('profession', ''), + 'sub_category': template.get('sub_category', ''), + 'system_prompt': template['system_prompt'] + } + + # 执行插入 + cursor.execute(insert_sql, template_data) + success_count += 1 + + print(f"成功插入模板: {template['name']}") + + except Exception as e: + print(f"插入模板 {template['name']} 失败:") + print(f"错误类型: {type(e).__name__}") + print(f"错误信息: {str(e)}") + error_count += 1 + continue + + # 提交事务 + conn.commit() + + print("\n=== 数据插入完成 ===") + print(f"成功插入: {success_count} 个模板") + print(f"重复跳过: {duplicate_count} 个模板") + print(f"插入失败: {error_count} 个模板") + print(f"总计模板: {len(all_templates)} 个") + print("===================") + + except Exception as e: + print(f"数据库连接失败: {str(e)}") + if 'conn' in locals(): + conn.rollback() + finally: + if 'cursor' in locals(): + cursor.close() + if 'conn' in locals(): + conn.close() if __name__ == '__main__': - init_db() \ No newline at end of file + insert_all_templates() \ No newline at end of file diff --git a/init_tedb.py b/init_tedb.py deleted file mode 100644 index 66590b7..0000000 --- a/init_tedb.py +++ /dev/null @@ -1,298 +0,0 @@ -from flask_prompt_master import create_app, db -from flask_prompt_master.models import PromptTemplate - -def init_db(): - """初始化数据库""" - app = create_app() - with app.app_context(): - # 创建所有表 - db.create_all() - print("数据库表创建完成!") - -def init_prompt_templates(): - """初始化提示词模板""" - templates = [ - # ... 保留原有模板 ... - - # 考公模板 - { - 'name': '行测-言语理解', - 'description': '针对行测言语理解题目的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '行测', - 'sub_category': '言语理解', - 'system_prompt': """你是一个专业的公务员考试行测言语理解专家。 - -对于用户输入的言语理解相关问题,你需要: -1. 分析题目类型(主旨理解、细节理解、语句表达、逻辑填空等) -2. 提供解题思路和方法 -3. 指出关键词和重点句 -4. 分析选项特点和陷阱 -5. 总结该类题目的通用解题技巧 - -请用清晰、专业的语言描述,帮助考生提高解题效率和准确率。""" - }, - { - 'name': '行测-数量关系', - 'description': '针对行测数量关系题目的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '行测', - 'sub_category': '数量关系', - 'system_prompt': """你是一个专业的公务员考试行测数量关系专家。 - -对于用户输入的数量关系问题,你需要: -1. 识别题目类型(数字推理、数学运算等) -2. 提供快速解题方法 -3. 指出计算技巧和shortcuts -4. 分析易错点和陷阱 -5. 总结该类题目的通用解题策略 - -请注重实用性和效率,帮助考生在有限时间内提高正确率。""" - }, - { - 'name': '行测-判断推理', - 'description': '针对行测判断推理题目的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '行测', - 'sub_category': '判断推理', - 'system_prompt': """你是一个专业的公务员考试行测判断推理专家。 - -对于用户输入的判断推理问题,你需要: -1. 识别题型(图形推理、定义判断、类比推理、逻辑判断) -2. 提供系统的分析方法 -3. 指出关键信息和规律 -4. 分析常见的推理方式 -5. 总结该类题目的解题技巧 - -请用逻辑清晰的语言,帮助考生提高推理能力和解题速度。""" - }, - { - 'name': '申论-大作文', - 'description': '针对申论大作文的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '申论', - 'sub_category': '大作文', - 'system_prompt': """你是一个专业的公务员考试申论写作专家。 - -对于用户输入的申论作文主题,你需要: -1. 分析题目要求和角度 -2. 提供论证思路和框架 -3. 推荐合适的论据和例证 -4. 指导语言表达和行文技巧 -5. 提供优秀范文示例 - -请注重思想性和实践性的结合,帮助考生提高申论写作水平。""" - }, - { - 'name': '申论-材料分析', - 'description': '针对申论材料分析题的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '申论', - 'sub_category': '材料分析', - 'system_prompt': """你是一个专业的公务员考试申论材料分析专家。 - -对于用户输入的材料分析题目,你需要: -1. 提供阅读材料的方法和技巧 -2. 指导如何提取关键信息 -3. 分析问题的答题思路 -4. 指导语言组织和表达 -5. 提供答题模板和范例 - -请用专业的视角,帮助考生提高材料分析能力。""" - }, - { - 'name': '行测-资料分析', - 'description': '针对行测资料分析题目的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '行测', - 'sub_category': '资料分析', - 'system_prompt': """你是一个专业的公务员考试行测资料分析专家。 - -对于用户输入的资料分析问题,你需要: -1. 快速定位关键数据 -2. 提供计算简化方法 -3. 分析数据间的关系 -4. 指出常见的陷阱 -5. 总结速算技巧 - -请注重实用性,帮助考生提高资料分析题的正确率和速度。""" - }, - { - 'name': '申论-对策建议', - 'description': '针对申论对策建议题的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '申论', - 'sub_category': '对策建议', - 'system_prompt': """你是一个专业的公务员考试申论对策建议专家。 - -对于用户输入的对策建议题目,你需要: -1. 分析问题的成因 -2. 提供多角度的解决方案 -3. 确保建议的可行性 -4. 注重措施的具体性 -5. 使用规范的行政语言 - -请从实践角度出发,帮助考生提出有效的对策建议。""" - }, - # 考公-面试模板 - { - 'name': '结构化面试-综合分析', - 'description': '针对公务员面试综合分析题的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '面试', - 'sub_category': '综合分析', - 'system_prompt': """你是一个专业的公务员面试辅导专家。 - -对于用户输入的综合分析题目,你需要: -1. 分析题目中的核心问题和关键词 -2. 提供多维度的分析框架 -3. 结合实际案例进行论证 -4. 给出具体可行的解决方案 -5. 使用规范的语言表达 - -请注重答题的全面性、逻辑性和实用性,帮助考生提高面试表现。""" - }, - { - 'name': '结构化面试-人际沟通', - 'description': '针对公务员面试人际沟通题的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '面试', - 'sub_category': '人际沟通', - 'system_prompt': """你是一个专业的公务员面试人际沟通专家。 - -对于用户输入的人际沟通题目,你需要: -1. 分析情境中的矛盾点 -2. 提供处理问题的思路 -3. 运用沟通技巧和方法 -4. 注重情商和态度 -5. 体现公职人员的素养 - -请帮助考生展现良好的沟通能力和职业素养。""" - }, - { - 'name': '行测-常识判断', - 'description': '针对行测常识判断题目的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '行测', - 'sub_category': '常识判断', - 'system_prompt': """你是一个专业的公务员考试行测常识判断专家。 - -对于用户输入的常识判断问题,你需要: -1. 梳理常识考点范围 -2. 提供记忆和理解方法 -3. 分析易混淆知识点 -4. 总结答题技巧 -5. 提供实践应用示例 - -请帮助考生系统掌握常识判断的重点和方法。""" - }, - { - 'name': '申论-概括提炼', - 'description': '针对申论概括提炼题的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '申论', - 'sub_category': '概括提炼', - 'system_prompt': """你是一个专业的公务员考试申论概括提炼专家。 - -对于用户输入的概括提炼题目,你需要: -1. 教授快速阅读技巧 -2. 指导关键信息提取 -3. 分析归纳方法 -4. 指导语言精炼技巧 -5. 提供答题模板 - -请帮助考生提高信息处理和表达能力。""" - }, - { - 'name': '时政热点-分析', - 'description': '针对公务员考试时政热点的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '时政', - 'sub_category': '热点分析', - 'system_prompt': """你是一个专业的公务员考试时政分析专家。 - -对于用户输入的时政热点,你需要: -1. 梳理事件背景和过程 -2. 分析政策导向和意义 -3. 总结核心观点 -4. 提供多角度思考 -5. 联系实际应用 - -请帮助考生把握时政热点的要点和考察方向。""" - }, - { - 'name': '面试-应急处理', - 'description': '针对公务员面试应急处理题的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '面试', - 'sub_category': '应急处理', - 'system_prompt': """你是一个专业的公务员面试应急处理专家。 - -对于用户输入的应急处理题目,你需要: -1. 分析突发事件的类型和特点 -2. 提供处置的基本原则 -3. 制定具体应对措施 -4. 注重舆情应对 -5. 总结预防和改进建议 - -请帮助考生掌握应急处理的要点和方法。""" - }, - { - 'name': '面试-组织管理', - 'description': '针对公务员面试组织管理题的提示词优化', - 'category': '考公', - 'industry': '公务员', - 'profession': '面试', - 'sub_category': '组织管理', - 'system_prompt': """你是一个专业的公务员面试组织管理专家。 - -对于用户输入的组织管理题目,你需要: -1. 分析管理问题的本质 -2. 运用管理学原理 -3. 提供具体工作方法 -4. 注重团队协作 -5. 体现领导能力 - -请帮助考生展现管理才能和领导素质。""" - } - ] - - try: - # 添加模板 - for template in templates: - # 检查是否已存在 - existing = PromptTemplate.query.filter_by( - name=template['name'], - category=template['category'], - sub_category=template['sub_category'] - ).first() - - if not existing: - new_template = PromptTemplate(**template) - db.session.add(new_template) - print(f"添加模板: {template['name']}") - else: - print(f"模板已存在: {template['name']}") - - db.session.commit() - print("\n=== 模板初始化完成 ===") - - except Exception as e: - print(f"初始化模板失败: {str(e)}") - db.session.rollback() - -if __name__ == '__main__': - init_db() \ No newline at end of file diff --git a/instance/app.db b/instance/app.db deleted file mode 100644 index 3ce2b28bee17c256308fcc9dccb81d89ce83aed5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110592 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

Z85A|j^+`Wk*IKRD%Sf^K-Qxm%21 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 T5 {backup_file}' - subprocess.run(cmd, shell=True, check=True) - print(f"数据库备份成功: {backup_file}") - - except subprocess.CalledProcessError as e: - print(f"备份失败: {str(e)}") - -if __name__ == '__main__': - backup_mysql_db() \ No newline at end of file diff --git a/src/flask_prompt_master/__init__.py b/src/flask_prompt_master/__init__.py index a158833..f91bce8 100644 --- a/src/flask_prompt_master/__init__.py +++ b/src/flask_prompt_master/__init__.py @@ -1,7 +1,7 @@ from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate -from config import Config +from src.flask_prompt_master.config import Config import os from flask_cors import CORS @@ -24,7 +24,7 @@ def create_app(config_class=Config): migrate.init_app(app, db) # 注册蓝图 - from flask_prompt_master.routes import main_bp + from src.flask_prompt_master.routes import main_bp app.register_blueprint(main_bp) return app \ No newline at end of file diff --git a/config.py b/src/flask_prompt_master/config.py similarity index 100% rename from config.py rename to src/flask_prompt_master/config.py diff --git a/src/flask_prompt_master/forms/__init__.py b/src/flask_prompt_master/forms/__init__.py new file mode 100644 index 0000000..c73bc20 --- /dev/null +++ b/src/flask_prompt_master/forms/__init__.py @@ -0,0 +1,8 @@ +""" +表单包 +包含所有表单定义 +""" + +from .forms import * + +__all__ = ['LoginForm', 'RegisterForm', 'PromptForm'] diff --git a/src/flask_prompt_master/models/__init__.py b/src/flask_prompt_master/models/__init__.py new file mode 100644 index 0000000..a59692c --- /dev/null +++ b/src/flask_prompt_master/models/__init__.py @@ -0,0 +1,8 @@ +""" +数据模型包 +包含所有数据库模型定义 +""" + +from .models import * + +__all__ = ['User', 'Prompt', 'Feedback'] diff --git a/src/flask_prompt_master/models/models.py b/src/flask_prompt_master/models/models.py index a5195d8..1d4c2b8 100644 --- a/src/flask_prompt_master/models/models.py +++ b/src/flask_prompt_master/models/models.py @@ -1,4 +1,4 @@ -from flask_prompt_master import db +from src.flask_prompt_master import db from datetime import datetime class User(db.Model): diff --git a/flask_prompt_master/init_db.py b/src/flask_prompt_master/promptsTemplates.py similarity index 99% rename from flask_prompt_master/init_db.py rename to src/flask_prompt_master/promptsTemplates.py index d8d7364..2400242 100644 --- a/flask_prompt_master/init_db.py +++ b/src/flask_prompt_master/promptsTemplates.py @@ -1,5 +1,5 @@ -from flask_prompt_master import create_app, db -from flask_prompt_master.models import PromptTemplate +from src.flask_prompt_master import create_app, db +from src.flask_prompt_master.models import PromptTemplate import pymysql # 导出模板数据 diff --git a/src/flask_prompt_master/routes/__init__.py b/src/flask_prompt_master/routes/__init__.py new file mode 100644 index 0000000..36e3913 --- /dev/null +++ b/src/flask_prompt_master/routes/__init__.py @@ -0,0 +1,8 @@ +""" +路由包 +包含所有应用路由定义 +""" + +from .routes import * + +__all__ = ['main', 'auth', 'prompts'] diff --git a/flask_prompt_master/routes/prompts.py b/src/flask_prompt_master/routes/prompts.py similarity index 100% rename from flask_prompt_master/routes/prompts.py rename to src/flask_prompt_master/routes/prompts.py diff --git a/src/flask_prompt_master/routes/routes.py b/src/flask_prompt_master/routes/routes.py index 1d205fd..b3e5888 100644 --- a/src/flask_prompt_master/routes/routes.py +++ b/src/flask_prompt_master/routes/routes.py @@ -1,9 +1,9 @@ from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, current_app from openai import OpenAI -from flask_prompt_master import db -from flask_prompt_master.models import User, Prompt, Feedback, PromptTemplate, WxUser -from flask_prompt_master.forms import PromptForm, FeedbackForm -from config import Config +from src.flask_prompt_master import db +from src.flask_prompt_master.models import User, Prompt, Feedback, PromptTemplate, WxUser +from src.flask_prompt_master.forms import PromptForm, FeedbackForm +from src.flask_prompt_master.config import Config import pymysql from datetime import datetime import requests diff --git a/src/flask_prompt_master/services/__init__.py b/src/flask_prompt_master/services/__init__.py new file mode 100644 index 0000000..eeaff5c --- /dev/null +++ b/src/flask_prompt_master/services/__init__.py @@ -0,0 +1,10 @@ +""" +业务逻辑包 +包含所有业务逻辑服务 +""" + +# 这里将导入具体的服务类 +# from .prompt_service import PromptService +# from .user_service import UserService + +__all__ = [] diff --git a/static/css/chat.css b/src/flask_prompt_master/static/css/chat.css similarity index 100% rename from static/css/chat.css rename to src/flask_prompt_master/static/css/chat.css diff --git a/static/css/style.css b/src/flask_prompt_master/static/css/style.css similarity index 100% rename from static/css/style.css rename to src/flask_prompt_master/static/css/style.css diff --git a/static/js/main.js b/src/flask_prompt_master/static/js/main.js similarity index 100% rename from static/js/main.js rename to src/flask_prompt_master/static/js/main.js diff --git a/flask_prompt_master/templates/__init__.py b/src/flask_prompt_master/templates/__init__.py similarity index 100% rename from flask_prompt_master/templates/__init__.py rename to src/flask_prompt_master/templates/__init__.py diff --git a/flask_prompt_master/templates/base.html b/src/flask_prompt_master/templates/base.html similarity index 100% rename from flask_prompt_master/templates/base.html rename to src/flask_prompt_master/templates/base.html diff --git a/flask_prompt_master/templates/expert_generate.html b/src/flask_prompt_master/templates/expert_generate.html similarity index 100% rename from flask_prompt_master/templates/expert_generate.html rename to src/flask_prompt_master/templates/expert_generate.html diff --git a/flask_prompt_master/templates/generate.html b/src/flask_prompt_master/templates/generate.html similarity index 100% rename from flask_prompt_master/templates/generate.html rename to src/flask_prompt_master/templates/generate.html diff --git a/flask_prompt_master/templates/index.html b/src/flask_prompt_master/templates/index.html similarity index 100% rename from flask_prompt_master/templates/index.html rename to src/flask_prompt_master/templates/index.html diff --git a/flask_prompt_master/templates/prompt.html b/src/flask_prompt_master/templates/prompt.html similarity index 100% rename from flask_prompt_master/templates/prompt.html rename to src/flask_prompt_master/templates/prompt.html diff --git a/flask_prompt_master/templates/prompt_list.html b/src/flask_prompt_master/templates/prompt_list.html similarity index 100% rename from flask_prompt_master/templates/prompt_list.html rename to src/flask_prompt_master/templates/prompt_list.html diff --git a/flask_prompt_master/templates/prompts.py b/src/flask_prompt_master/templates/prompts.py similarity index 100% rename from flask_prompt_master/templates/prompts.py rename to src/flask_prompt_master/templates/prompts.py diff --git a/src/flask_prompt_master/utils/__init__.py b/src/flask_prompt_master/utils/__init__.py new file mode 100644 index 0000000..5a08f35 --- /dev/null +++ b/src/flask_prompt_master/utils/__init__.py @@ -0,0 +1,10 @@ +""" +工具包 +包含所有工具函数和辅助类 +""" + +# 这里将导入具体的工具函数 +# from .validators import validate_prompt +# from .helpers import format_response + +__all__ = [] diff --git a/sync_templates.py b/sync_templates.py deleted file mode 100644 index 500642e..0000000 --- a/sync_templates.py +++ /dev/null @@ -1,98 +0,0 @@ -import pymysql -from flask_prompt_master.init_db import templates - -def sync_templates(): - """同步提示词模板数据到数据库""" - try: - # 连接数据库 - conn = pymysql.connect( - host='localhost', - user='root', - password='123456', - database='food_db', - charset='utf8mb4' - ) - cursor = conn.cursor() - - # 获取现有模板 - cursor.execute("SELECT name FROM prompt_template") - existing_templates = {row[0] for row in cursor.fetchall()} - - # 准备插入和更新的SQL语句 - insert_sql = """ - INSERT INTO prompt_template - (name, description, category, industry, profession, sub_category, system_prompt, is_default) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s) - """ - - update_sql = """ - UPDATE prompt_template - SET description = %s, - category = %s, - industry = %s, - profession = %s, - sub_category = %s, - system_prompt = %s, - is_default = %s - WHERE name = %s - """ - - # 统计计数 - inserted_count = 0 - updated_count = 0 - - # 遍历模板数据 - for template in templates: - template_name = template['name'] - - if template_name in existing_templates: - # 更新现有模板 - cursor.execute(update_sql, ( - template['description'], - template.get('category', ''), - template.get('industry', ''), - template.get('profession', ''), - template.get('sub_category', ''), - template['system_prompt'], - template.get('is_default', False), - template_name - )) - updated_count += 1 - print(f"更新模板: {template_name}") - else: - # 插入新模板 - cursor.execute(insert_sql, ( - template_name, - template['description'], - template.get('category', ''), - template.get('industry', ''), - template.get('profession', ''), - template.get('sub_category', ''), - template['system_prompt'], - template.get('is_default', False) - )) - inserted_count += 1 - print(f"新增模板: {template_name}") - - # 提交事务 - conn.commit() - - # 打印同步结果 - print("\n=== 模板同步完成 ===") - print(f"新增模板数: {inserted_count}") - print(f"更新模板数: {updated_count}") - print(f"总模板数: {len(templates)}") - print("===================") - - except Exception as e: - print(f"同步模板失败: {str(e)}") - if 'conn' in locals(): - conn.rollback() - finally: - if 'cursor' in locals(): - cursor.close() - if 'conn' in locals(): - conn.close() - -if __name__ == '__main__': - sync_templates() \ No newline at end of file diff --git a/templates/base.html b/templates/base.html deleted file mode 100644 index e9d0f9a..0000000 --- a/templates/base.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - 提示词大师 - {% block title %}{% endblock %} - - - - -

- -
- -
- {% with messages = get_flashed_messages() %} - {% if messages %} -
- {% for message in messages %} -
{{ message }}
- {% endfor %} -
- {% endif %} - {% endwith %} - - {% block content %}{% endblock %} -
- -
-

© 2025 提示词大师

-
- - diff --git a/templates/feedback.html b/templates/feedback.html deleted file mode 100644 index 498bad7..0000000 --- a/templates/feedback.html +++ /dev/null @@ -1,37 +0,0 @@ -{% extends "base.html" %} - -{% block title %}提供反馈{% endblock %} - -{% block content %} - -{% endblock %} diff --git a/templates/generate.html b/templates/generate.html deleted file mode 100644 index 4a2159d..0000000 --- a/templates/generate.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "base.html" %} - -{% block title %}生成提示词{% endblock %} - -{% block content %} -
-

生成提示词

-
- {{ form.hidden_tag() }} -
- {{ form.input_text.label }} - {{ form.input_text(class="form-control", rows=5) }} - {% for error in form.input_text.errors %} - {{ error }} - {% endfor %} -
-
- {{ form.submit(class="btn btn-primary") }} -
-
-
-{% endblock %} diff --git a/templates/prompt.html b/templates/prompt.html deleted file mode 100644 index b074d92..0000000 --- a/templates/prompt.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "base.html" %} - -{% block title %}提示词详情{% endblock %} - -{% block content %} -
-

生成的提示词

- -
-
-

您的输入:

-

{{ prompt.input_text }}

-
- -
-

生成的提示词:

-

{{ prompt.generated_text }}

-
- - -
-
-{% endblock %} diff --git a/test_db.py b/test_db.py index 1646710..98bc446 100644 --- a/test_db.py +++ b/test_db.py @@ -1,7 +1,7 @@ -from flask_prompt_master import create_app, db +from src.flask_prompt_master import create_app, db import pymysql -from flask_prompt_master.init_db import templates as init_templates -from flask_prompt_master.templates.prompts import templates as prompt_templates +from src.flask_prompt_master.promptsTemplates import templates as init_templates +from src.flask_prompt_master.templates.prompts import templates as prompt_templates def insert_all_templates(): """向 prompt_template 表插入所有模板数据"""