增加诗词收藏功能
This commit is contained in:
45
create_poetry_favorites_table.py
Normal file
45
create_poetry_favorites_table.py
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
创建古诗词收藏表
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from src.flask_prompt_master import create_app, db
|
||||
from src.flask_prompt_master.models.poetry_favorites import PoetryFavorite
|
||||
|
||||
def create_poetry_favorites_table():
|
||||
"""创建古诗词收藏表"""
|
||||
app = create_app()
|
||||
|
||||
with app.app_context():
|
||||
try:
|
||||
# 创建表
|
||||
db.create_all()
|
||||
print("✅ 古诗词收藏表创建成功!")
|
||||
|
||||
# 检查表是否存在
|
||||
from sqlalchemy import inspect
|
||||
inspector = inspect(db.engine)
|
||||
if 'poetry_favorites' in inspector.get_table_names():
|
||||
print("✅ 表 'poetry_favorites' 已存在")
|
||||
else:
|
||||
print("❌ 表 'poetry_favorites' 创建失败")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 创建表失败: {e}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("开始创建古诗词收藏表...")
|
||||
success = create_poetry_favorites_table()
|
||||
if success:
|
||||
print("🎉 古诗词收藏功能数据库初始化完成!")
|
||||
else:
|
||||
print("💥 数据库初始化失败!")
|
||||
sys.exit(1)
|
||||
70
logs/app.log
70
logs/app.log
@@ -1203,3 +1203,73 @@ OSError: [Errno 5] Input/output error
|
||||
2025-09-14 10:21:05,361 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
2025-09-14 10:23:47,060 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
2025-09-14 10:25:23,276 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
2025-09-14 14:02:48,216 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
2025-09-14 14:05:04,009 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
2025-09-14 15:40:23,178 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-14 15:40:23,246 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-14 15:42:53,566 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-14 15:42:53,582 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-14 15:45:51,041 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-14 15:45:51,093 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-14 15:46:43,416 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-14 15:46:43,421 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-14 15:49:14,934 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-14 15:49:14,938 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-14 19:00:32,760 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-14 19:00:32,792 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-17 00:05:52,296 ERROR: Exception on / [POST] [in /home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py:1414]
|
||||
Traceback (most recent call last):
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 2190, in wsgi_app
|
||||
response = self.full_dispatch_request()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1486, in full_dispatch_request
|
||||
rv = self.handle_user_exception(e)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask_cors/extension.py", line 176, in wrapped_function
|
||||
return cors_after_request(app.make_response(f(*args, **kwargs)))
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1484, in full_dispatch_request
|
||||
rv = self.dispatch_request()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1469, in dispatch_request
|
||||
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/aitsc/src/flask_prompt_master/routes/routes.py", line 129, in index
|
||||
generated_text = generate_with_llm(form.input_text.data, template_id)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/aitsc/src/flask_prompt_master/routes/routes.py", line 53, in generate_with_llm
|
||||
print("\n=== API 调用参数 ===")
|
||||
OSError: [Errno 5] Input/output error
|
||||
2025-09-18 22:23:27,175 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-18 22:23:27,176 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-18 22:24:31,816 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-18 22:24:31,819 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-18 22:25:31,117 ERROR: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:101]
|
||||
2025-09-18 22:25:31,119 ERROR: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out. [in /home/renjianbo/aitsc/src/flask_prompt_master/routes/poetry.py:165]
|
||||
2025-09-18 23:32:56,838 ERROR: Exception on / [POST] [in /home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py:1414]
|
||||
Traceback (most recent call last):
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 2190, in wsgi_app
|
||||
response = self.full_dispatch_request()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1486, in full_dispatch_request
|
||||
rv = self.handle_user_exception(e)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask_cors/extension.py", line 176, in wrapped_function
|
||||
return cors_after_request(app.make_response(f(*args, **kwargs)))
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1484, in full_dispatch_request
|
||||
rv = self.dispatch_request()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1469, in dispatch_request
|
||||
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/aitsc/src/flask_prompt_master/routes/routes.py", line 129, in index
|
||||
generated_text = generate_with_llm(form.input_text.data, template_id)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/aitsc/src/flask_prompt_master/routes/routes.py", line 53, in generate_with_llm
|
||||
print("\n=== API 调用参数 ===")
|
||||
OSError: [Errno 5] Input/output error
|
||||
2025-09-18 23:38:00,352 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
2025-09-18 23:43:08,941 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
2025-09-18 23:46:46,603 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
2025-09-18 23:58:37,127 INFO: 应用启动 [in /home/renjianbo/aitsc/config/base.py:82]
|
||||
|
||||
2
logs/gunicorn.log
Normal file
2
logs/gunicorn.log
Normal file
@@ -0,0 +1,2 @@
|
||||
nohup: ignoring input
|
||||
[2025-09-18 23:58:37,127] INFO in base: 应用启动
|
||||
@@ -1 +1 @@
|
||||
6470
|
||||
3055
|
||||
|
||||
@@ -1026,3 +1026,224 @@
|
||||
123.139.37.169 - - [14/Sep/2025:13:01:11 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1114
|
||||
123.139.37.169 - - [14/Sep/2025:13:02:49 +0800] "GET / HTTP/1.1" 200 49733 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 547778
|
||||
123.139.37.169 - - [14/Sep/2025:13:02:49 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 946
|
||||
123.139.37.169 - - [14/Sep/2025:13:06:00 +0800] "GET /meal-planning HTTP/1.1" 200 25595 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 108538
|
||||
123.139.37.169 - - [14/Sep/2025:13:06:00 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/meal-planning" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 847
|
||||
123.139.37.169 - - [14/Sep/2025:13:06:16 +0800] "GET /meal-planning/history HTTP/1.1" 200 22501 "http://101.43.95.130:5002/meal-planning" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 109498
|
||||
123.139.37.169 - - [14/Sep/2025:13:06:17 +0800] "GET /api/meal-planning/list?page=1&per_page=10 HTTP/1.1" 200 8014 "http://101.43.95.130:5002/meal-planning/history" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 353592
|
||||
123.139.37.169 - - [14/Sep/2025:13:06:52 +0800] "GET /meal-planning/history HTTP/1.1" 200 22501 "http://101.43.95.130:5002/meal-planning/history" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 104920
|
||||
123.139.37.169 - - [14/Sep/2025:13:06:53 +0800] "GET /api/meal-planning/list?page=1&per_page=10 HTTP/1.1" 200 8014 "http://101.43.95.130:5002/meal-planning/history" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 283018
|
||||
123.139.37.169 - - [14/Sep/2025:13:06:55 +0800] "GET / HTTP/1.1" 200 49733 "http://101.43.95.130:5002/meal-planning/history" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 191698
|
||||
123.139.37.169 - - [14/Sep/2025:13:06:55 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 787
|
||||
123.139.37.169 - - [14/Sep/2025:13:57:51 +0800] "GET / HTTP/1.1" 200 49733 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 315844
|
||||
123.139.37.169 - - [14/Sep/2025:13:57:51 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4495
|
||||
123.139.37.169 - - [14/Sep/2025:13:58:03 +0800] "GET / HTTP/1.1" 200 49733 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 288608
|
||||
123.139.37.169 - - [14/Sep/2025:13:58:03 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1447
|
||||
123.139.37.169 - - [14/Sep/2025:13:59:08 +0800] "GET /poetry/ HTTP/1.1" 404 207 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4767
|
||||
123.139.37.169 - - [14/Sep/2025:13:59:48 +0800] "GET / HTTP/1.1" 200 49733 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 165693
|
||||
123.139.37.169 - - [14/Sep/2025:13:59:48 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 910
|
||||
123.139.37.169 - - [14/Sep/2025:14:03:29 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 575974
|
||||
123.139.37.169 - - [14/Sep/2025:14:03:29 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4304
|
||||
123.139.37.169 - - [14/Sep/2025:14:05:07 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 564941
|
||||
123.139.37.169 - - [14/Sep/2025:14:05:07 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 5684
|
||||
123.139.37.169 - - [14/Sep/2025:14:05:37 +0800] "GET /poetry/ HTTP/1.1" 200 24261 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 469144
|
||||
123.139.37.169 - - [14/Sep/2025:14:05:38 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4388
|
||||
123.139.37.169 - - [14/Sep/2025:15:40:23 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 30333748
|
||||
123.139.37.169 - - [14/Sep/2025:15:42:51 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 585339
|
||||
123.139.37.169 - - [14/Sep/2025:15:42:51 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1030
|
||||
123.139.37.169 - - [14/Sep/2025:15:42:53 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 70287693
|
||||
123.139.37.169 - - [14/Sep/2025:15:45:09 +0800] "GET /poetry/ HTTP/1.1" 200 24261 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 522767
|
||||
123.139.37.169 - - [14/Sep/2025:15:45:10 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1427
|
||||
123.139.37.169 - - [14/Sep/2025:15:45:51 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 30285508
|
||||
123.139.37.169 - - [14/Sep/2025:15:46:15 +0800] "GET /poetry/analyze HTTP/1.1" 405 153 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4681
|
||||
123.139.37.169 - - [14/Sep/2025:15:46:43 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 30226757
|
||||
123.139.37.169 - - [14/Sep/2025:15:48:31 +0800] "GET /poetry/ HTTP/1.1" 200 24261 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 254600
|
||||
123.139.37.169 - - [14/Sep/2025:15:48:31 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1316
|
||||
123.139.37.169 - - [14/Sep/2025:15:49:14 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 30287544
|
||||
3.131.215.38 - - [14/Sep/2025:16:19:03 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 457508
|
||||
3.131.215.38 - - [14/Sep/2025:16:20:21 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 332333
|
||||
123.139.37.169 - - [14/Sep/2025:18:59:21 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 285379
|
||||
123.139.37.169 - - [14/Sep/2025:18:59:21 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 883
|
||||
123.139.37.169 - - [14/Sep/2025:18:59:32 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 146408
|
||||
123.139.37.169 - - [14/Sep/2025:18:59:32 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 858
|
||||
123.139.37.169 - - [14/Sep/2025:18:59:35 +0800] "GET /poetry/ HTTP/1.1" 200 24261 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 93277
|
||||
123.139.37.169 - - [14/Sep/2025:18:59:35 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 802
|
||||
123.139.37.169 - - [14/Sep/2025:19:00:32 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 30255615
|
||||
123.139.37.169 - - [14/Sep/2025:19:19:52 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 319790
|
||||
123.139.37.169 - - [14/Sep/2025:19:19:52 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 846
|
||||
123.139.37.169 - - [14/Sep/2025:19:19:52 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 862
|
||||
123.139.37.169 - - [14/Sep/2025:19:29:48 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 567057
|
||||
123.139.37.169 - - [14/Sep/2025:19:29:48 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4374
|
||||
123.139.37.169 - - [14/Sep/2025:19:29:48 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1293
|
||||
123.139.37.169 - - [14/Sep/2025:19:29:54 +0800] "GET /poetry/ HTTP/1.1" 200 24261 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 119385
|
||||
123.139.37.169 - - [14/Sep/2025:19:29:54 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 966
|
||||
167.94.145.110 - - [15/Sep/2025:06:36:21 +0800] "GET / HTTP/1.1" 200 49893 "-" "-" 645898
|
||||
167.94.145.110 - - [15/Sep/2025:06:36:26 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 688031
|
||||
167.94.145.110 - - [15/Sep/2025:06:36:27 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 1080
|
||||
167.94.145.110 - - [15/Sep/2025:06:36:27 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 4201
|
||||
167.94.145.110 - - [15/Sep/2025:06:36:48 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 4120
|
||||
167.94.145.110 - - [15/Sep/2025:06:36:49 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 890
|
||||
167.94.145.110 - - [15/Sep/2025:06:36:50 +0800] "GET /wiki HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 884
|
||||
43.128.25.40 - - [15/Sep/2025:09:17:18 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" 516944
|
||||
43.128.25.40 - - [15/Sep/2025:09:17:18 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" 1020
|
||||
1.82.133.130 - - [15/Sep/2025:14:34:30 +0800] "GET / HTTP/1.0" 200 49893 "-" "-" 292596
|
||||
1.82.133.130 - - [15/Sep/2025:14:34:34 +0800] "HEAD / HTTP/1.1" 200 0 "-" "Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/86.0.4240.111Safari/537.36" 112478
|
||||
110.40.39.111 - - [15/Sep/2025:16:46:38 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3" 513382
|
||||
110.40.39.111 - - [15/Sep/2025:16:46:39 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50" 712
|
||||
3.131.215.38 - - [15/Sep/2025:17:50:48 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 475016
|
||||
3.131.215.38 - - [15/Sep/2025:17:52:10 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 333585
|
||||
171.116.202.7 - - [16/Sep/2025:02:50:48 +0800] "GET / HTTP/1.1" 200 49893 "-" "-" 290679
|
||||
180.95.231.101 - - [16/Sep/2025:02:50:56 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 481936
|
||||
111.113.88.90 - - [16/Sep/2025:02:50:56 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 724
|
||||
185.224.128.17 - - [16/Sep/2025:06:35:09 +0800] "CONNECT example.com:80 HTTP/1.1" 404 207 "-" "-" 925
|
||||
162.142.125.207 - - [16/Sep/2025:06:58:18 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 435618
|
||||
167.94.146.54 - - [16/Sep/2025:12:18:48 +0800] "GET / HTTP/1.1" 200 49893 "-" "-" 468320
|
||||
167.94.146.54 - - [16/Sep/2025:12:18:53 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 344402
|
||||
167.94.146.54 - - [16/Sep/2025:12:18:58 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 729
|
||||
167.94.146.54 - - [16/Sep/2025:12:18:58 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 704
|
||||
167.94.146.54 - - [16/Sep/2025:12:19:03 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 702
|
||||
167.94.146.54 - - [16/Sep/2025:12:19:04 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 704
|
||||
167.94.146.54 - - [16/Sep/2025:12:19:05 +0800] "GET /login HTTP/1.1" 200 13723 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 4058
|
||||
3.130.96.91 - - [16/Sep/2025:17:04:22 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 473680
|
||||
3.130.96.91 - - [16/Sep/2025:17:05:35 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 310503
|
||||
123.139.95.59 - - [17/Sep/2025:00:04:58 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 279793
|
||||
123.139.95.59 - - [17/Sep/2025:00:04:59 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 806
|
||||
123.139.95.59 - - [17/Sep/2025:00:05:00 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1019
|
||||
123.139.95.59 - - [17/Sep/2025:00:05:52 +0800] "POST / HTTP/1.1" 500 265 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 277335
|
||||
123.139.95.59 - - [17/Sep/2025:00:05:55 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 295732
|
||||
185.224.128.17 - - [17/Sep/2025:07:51:12 +0800] "CONNECT example.com:80 HTTP/1.1" 404 207 "-" "-" 657
|
||||
175.30.48.152 - - [17/Sep/2025:07:52:19 +0800] "HEAD http://110.242.68.4/ HTTP/1.1" 200 0 "-" "Mozilla/5.01669615 Mozilla/5.0 (Linux; Android 5.1; S900PROBT Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Safari/537.36" 239835
|
||||
220.197.51.69 - - [17/Sep/2025:07:52:20 +0800] "GET http://www.rfa.org/english/ HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" 669
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:20 +0800] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 983
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:21 +0800] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 647
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:21 +0800] "GET http://www.epochtimes.com/ HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" 236453
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:21 +0800] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 661
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:21 +0800] "GET http://www.wujieliulan.com/ HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" 461468
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:22 +0800] "GET http://www.minghui.org/ HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" 106589
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:22 +0800] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 963
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:22 +0800] "GET http://dongtaiwang.com/ HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" 241988
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:22 +0800] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 665
|
||||
182.138.158.161 - - [17/Sep/2025:07:52:22 +0800] "CONNECT www.baidu.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 619
|
||||
124.31.105.231 - - [17/Sep/2025:07:52:23 +0800] "CONNECT cn.bing.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 736
|
||||
124.31.105.231 - - [17/Sep/2025:07:52:24 +0800] "GET http://www.soso.com/ HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" 410600
|
||||
124.31.105.231 - - [17/Sep/2025:07:52:24 +0800] "CONNECT www.voanews.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 663
|
||||
124.31.105.231 - - [17/Sep/2025:07:52:24 +0800] "CONNECT www.so.com:443 HTTP/1.1" 404 207 "-" "PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3" 706
|
||||
167.94.146.59 - - [17/Sep/2025:12:20:06 +0800] "GET / HTTP/1.1" 200 49893 "-" "-" 522863
|
||||
167.94.146.59 - - [17/Sep/2025:12:20:10 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 370462
|
||||
167.94.146.59 - - [17/Sep/2025:12:20:11 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 971
|
||||
167.94.146.59 - - [17/Sep/2025:12:20:12 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 1065
|
||||
167.94.146.59 - - [17/Sep/2025:12:20:16 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 686
|
||||
167.94.146.59 - - [17/Sep/2025:12:20:17 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 695
|
||||
167.94.146.59 - - [17/Sep/2025:12:20:18 +0800] "GET /login HTTP/1.1" 200 13723 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 3454
|
||||
167.94.138.180 - - [17/Sep/2025:13:00:52 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 453822
|
||||
167.94.138.180 - - [17/Sep/2025:13:00:53 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 717
|
||||
167.94.138.180 - - [17/Sep/2025:13:00:55 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 676
|
||||
167.94.138.180 - - [17/Sep/2025:13:01:02 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 712
|
||||
167.94.138.180 - - [17/Sep/2025:13:01:04 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 716
|
||||
167.94.138.180 - - [17/Sep/2025:13:01:06 +0800] "GET /login HTTP/1.1" 200 13723 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 3155
|
||||
206.168.34.219 - - [17/Sep/2025:13:01:37 +0800] "GET /login HTTP/1.1" 200 13723 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 943
|
||||
3.132.23.201 - - [17/Sep/2025:16:46:11 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 469031
|
||||
3.132.23.201 - - [17/Sep/2025:16:48:21 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 318852
|
||||
3.134.148.59 - - [17/Sep/2025:17:27:30 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 446267
|
||||
3.134.148.59 - - [17/Sep/2025:17:28:46 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 466801
|
||||
66.228.53.78 - - [17/Sep/2025:18:20:30 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" 436163
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:03 +0800] "GET /xxl-job-admin/toLogin HTTP/1.0" 404 207 "-" "-" 992
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:03 +0800] "GET http://10.204.9.230/flag.html HTTP/1.1" 404 207 "-" "-" 1003
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:03 +0800] "GET /ws/v1/cluster/ HTTP/1.0" 404 207 "-" "-" 805
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:03 +0800] "GET /lab HTTP/1.0" 404 207 "-" "-" 897
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:03 +0800] "GET /pods HTTP/1.0" 404 207 "-" "-" 795
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:03 +0800] "GET http://101.91.15.155/vul/Tst_SsrF.html HTTP/1.0" 404 207 "-" "-" 924
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:03 +0800] "GET /json HTTP/1.0" 404 207 "-" "-" 817
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET /login HTTP/1.0" 200 13723 "-" "-" 3989
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET /v2/keys HTTP/1.0" 404 207 "-" "-" 1282
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET /actuator HTTP/1.1" 404 207 "-" "-" 935
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET /ws?method=connectArthas&id=e63fbc2664227b16 HTTP/1.1" 404 207 "-" "-" 876
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET /nacos/ HTTP/1.1" 404 207 "-" "-" 694
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET /tplus/view/login.html HTTP/1.1" 404 207 "-" "-" 591
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET / HTTP/1.0" 200 49893 "-" "-" 261629
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET / HTTP/1.1" 200 49893 "-" "-" 239451
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET // HTTP/1.1" 200 49893 "-" "-" 333396
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:05 +0800] "GET / HTTP/1.1" 200 49893 "-" "-" 250405
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:06 +0800] "OPTIONS / HTTP/1.0" 200 0 "-" "-" 941
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:06 +0800] "GET / HTTP/1.0" 200 49893 "-" "-" 115529
|
||||
124.220.188.32 - - [18/Sep/2025:06:55:08 +0800] "GET /nice%20ports%2C/Tri%6Eity.txt%2ebak HTTP/1.0" 404 207 "-" "-" 1186
|
||||
111.7.96.149 - - [18/Sep/2025:08:06:38 +0800] "GET / HTTP/1.1" 200 49893 "-" "curl/7.64.1" 273138
|
||||
36.41.66.155 - - [18/Sep/2025:08:06:47 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 286792
|
||||
36.41.66.155 - - [18/Sep/2025:08:06:48 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 141723
|
||||
36.41.66.155 - - [18/Sep/2025:08:06:49 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://ruilaizipj.com:5002/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 923
|
||||
36.41.66.155 - - [18/Sep/2025:08:06:52 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 695
|
||||
111.7.96.163 - - [18/Sep/2025:08:07:37 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 285331
|
||||
111.7.96.163 - - [18/Sep/2025:08:07:37 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 264556
|
||||
111.7.96.163 - - [18/Sep/2025:08:07:37 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://www.ruilaizipj.com:5002/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 829
|
||||
111.7.96.163 - - [18/Sep/2025:08:07:41 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 733
|
||||
36.41.66.49 - - [18/Sep/2025:08:07:57 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 142369
|
||||
36.41.66.49 - - [18/Sep/2025:08:07:57 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 130334
|
||||
36.41.66.49 - - [18/Sep/2025:08:07:58 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 809
|
||||
36.41.66.49 - - [18/Sep/2025:08:08:02 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" 686
|
||||
185.224.128.17 - - [18/Sep/2025:09:59:23 +0800] "CONNECT example.com:80 HTTP/1.1" 404 207 "-" "-" 688
|
||||
66.132.153.131 - - [18/Sep/2025:14:10:47 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 657370
|
||||
66.132.153.131 - - [18/Sep/2025:14:10:48 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 727
|
||||
66.132.153.131 - - [18/Sep/2025:14:10:48 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 685
|
||||
66.132.153.131 - - [18/Sep/2025:14:10:52 +0800] "PRI * HTTP/2.0" 404 207 "-" "-" 735
|
||||
66.132.153.131 - - [18/Sep/2025:14:10:54 +0800] "GET /favicon.ico HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 719
|
||||
66.132.153.131 - - [18/Sep/2025:14:10:55 +0800] "GET /wiki HTTP/1.1" 404 207 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 814
|
||||
58.212.237.154 - - [18/Sep/2025:14:10:56 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1" 280199
|
||||
206.168.34.38 - - [18/Sep/2025:14:11:24 +0800] "GET /login HTTP/1.1" 200 13723 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" 3302
|
||||
3.130.96.91 - - [18/Sep/2025:16:27:21 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126.0.0.0 Safari/537.36" 425736
|
||||
123.139.94.4 - - [18/Sep/2025:22:21:27 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 273802
|
||||
123.139.94.4 - - [18/Sep/2025:22:21:27 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4330
|
||||
123.139.94.4 - - [18/Sep/2025:22:21:29 +0800] "GET /poetry/ HTTP/1.1" 200 24261 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 5131
|
||||
123.139.94.4 - - [18/Sep/2025:22:21:29 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 697
|
||||
123.139.94.4 - - [18/Sep/2025:22:23:27 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 30201844
|
||||
123.139.94.4 - - [18/Sep/2025:22:24:31 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 30199174
|
||||
123.139.94.4 - - [18/Sep/2025:22:24:34 +0800] "GET /poetry/examples HTTP/1.1" 200 16817 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 6378
|
||||
123.139.94.4 - - [18/Sep/2025:22:24:34 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/examples" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 701
|
||||
123.139.94.4 - - [18/Sep/2025:22:24:50 +0800] "GET /poetry/?title=%E6%98%A5%E6%99%93&author=%E5%AD%9F%E6%B5%A9%E7%84%B6&dynasty=%E5%94%90 HTTP/1.1" 200 24261 "http://101.43.95.130:5002/poetry/examples" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 5275
|
||||
123.139.94.4 - - [18/Sep/2025:22:24:50 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/?title=%E6%98%A5%E6%99%93&author=%E5%AD%9F%E6%B5%A9%E7%84%B6&dynasty=%E5%94%90" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 729
|
||||
123.139.94.4 - - [18/Sep/2025:22:25:31 +0800] "POST /poetry/analyze HTTP/1.1" 200 184 "http://101.43.95.130:5002/poetry/?title=%E6%98%A5%E6%99%93&author=%E5%AD%9F%E6%B5%A9%E7%84%B6&dynasty=%E5%94%90" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 30206243
|
||||
123.139.94.4 - - [18/Sep/2025:23:30:56 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 301780
|
||||
123.139.94.4 - - [18/Sep/2025:23:30:56 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 743
|
||||
123.139.94.4 - - [18/Sep/2025:23:32:03 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 186816
|
||||
123.139.94.4 - - [18/Sep/2025:23:32:03 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 710
|
||||
123.139.94.4 - - [18/Sep/2025:23:32:56 +0800] "POST / HTTP/1.1" 500 265 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 287623
|
||||
123.139.94.4 - - [18/Sep/2025:23:33:56 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 363738
|
||||
127.0.0.1 - - [18/Sep/2025:23:38:18 +0800] "GET / HTTP/1.1" 200 49893 "-" "curl/7.29.0" 460763
|
||||
123.139.94.4 - - [18/Sep/2025:23:38:21 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 569785
|
||||
123.139.94.4 - - [18/Sep/2025:23:38:21 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4335
|
||||
123.139.94.4 - - [18/Sep/2025:23:38:32 +0800] "GET /poetry/ HTTP/1.1" 200 24261 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 435941
|
||||
123.139.94.4 - - [18/Sep/2025:23:38:32 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1130
|
||||
127.0.0.1 - - [18/Sep/2025:23:38:59 +0800] "GET /poetry/ HTTP/1.1" 200 24261 "-" "curl/7.29.0" 1093
|
||||
123.139.94.4 - - [18/Sep/2025:23:39:26 +0800] "POST /poetry/analyze HTTP/1.1" 200 6213 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 40290252
|
||||
123.139.94.4 - - [18/Sep/2025:23:44:11 +0800] "POST /poetry/analyze HTTP/1.1" 200 5949 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 37279540
|
||||
127.0.0.1 - - [18/Sep/2025:23:45:52 +0800] "GET /poetry/ HTTP/1.1" 200 29579 "-" "curl/7.29.0" 18228
|
||||
123.139.94.4 - - [18/Sep/2025:23:46:50 +0800] "GET / HTTP/1.1" 200 49893 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 610282
|
||||
123.139.94.4 - - [18/Sep/2025:23:46:50 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4427
|
||||
123.139.94.4 - - [18/Sep/2025:23:46:52 +0800] "GET /poetry/ HTTP/1.1" 200 34651 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 131630
|
||||
123.139.94.4 - - [18/Sep/2025:23:46:52 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4553
|
||||
123.139.94.4 - - [18/Sep/2025:23:47:38 +0800] "POST /poetry/analyze HTTP/1.1" 200 4972 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 35537462
|
||||
123.139.94.4 - - [18/Sep/2025:23:50:12 +0800] "POST / HTTP/1.1" 200 54554 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 23198888
|
||||
123.139.94.4 - - [18/Sep/2025:23:50:12 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 1114
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:21 +0800] "GET /poetry/ HTTP/1.1" 200 34651 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 125608
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:21 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4297
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:28 +0800] "GET /meal-planning/history HTTP/1.1" 200 22501 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 439262
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:29 +0800] "GET /api/meal-planning/list?page=1&per_page=10 HTTP/1.1" 200 8014 "http://101.43.95.130:5002/meal-planning/history" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 538265
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:33 +0800] "GET /poetry/ HTTP/1.1" 200 34651 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 164706
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:33 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 795
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:35 +0800] "GET /poetry/examples HTTP/1.1" 200 16817 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 101378
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:35 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/examples" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4340
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:37 +0800] "GET /poetry/ HTTP/1.1" 200 34651 "http://101.43.95.130:5002/poetry/examples" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 459813
|
||||
123.139.94.4 - - [18/Sep/2025:23:51:38 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 773
|
||||
123.139.94.4 - - [18/Sep/2025:23:58:52 +0800] "GET / HTTP/1.1" 200 50061 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 585814
|
||||
123.139.94.4 - - [18/Sep/2025:23:58:52 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 4598
|
||||
127.0.0.1 - - [18/Sep/2025:23:59:01 +0800] "GET /poetry/favorites HTTP/1.1" 200 24950 "-" "curl/7.29.0" 15484
|
||||
123.139.94.4 - - [18/Sep/2025:23:59:40 +0800] "GET /poetry/ HTTP/1.1" 200 41001 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 151487
|
||||
123.139.94.4 - - [18/Sep/2025:23:59:40 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 823
|
||||
123.139.94.4 - - [19/Sep/2025:00:00:35 +0800] "POST /poetry/analyze HTTP/1.1" 200 5772 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 39751657
|
||||
123.139.94.4 - - [19/Sep/2025:00:00:35 +0800] "POST /poetry/favorites/check HTTP/1.1" 200 57 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 430537
|
||||
123.139.94.4 - - [19/Sep/2025:00:00:44 +0800] "POST /poetry/favorites/add HTTP/1.1" 200 61 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 576436
|
||||
123.139.94.4 - - [19/Sep/2025:00:02:51 +0800] "GET /poetry/favorites HTTP/1.1" 200 24950 "http://101.43.95.130:5002/poetry/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 121194
|
||||
123.139.94.4 - - [19/Sep/2025:00:02:51 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/poetry/favorites" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 809
|
||||
123.139.94.4 - - [19/Sep/2025:00:02:52 +0800] "GET /poetry/favorites/list?page=1&per_page=10&search=&dynasty=&author= HTTP/1.1" 200 311 "http://101.43.95.130:5002/poetry/favorites" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 442664
|
||||
123.139.94.4 - - [19/Sep/2025:00:02:56 +0800] "GET /poetry/favorites/1 HTTP/1.1" 200 6227 "http://101.43.95.130:5002/poetry/favorites" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 414377
|
||||
123.139.94.4 - - [19/Sep/2025:00:03:10 +0800] "GET /poetry/favorites/1 HTTP/1.1" 200 6227 "http://101.43.95.130:5002/poetry/favorites" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 102769
|
||||
123.139.94.4 - - [19/Sep/2025:00:04:15 +0800] "GET / HTTP/1.1" 200 50061 "http://101.43.95.130:5002/poetry/favorites" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 203744
|
||||
123.139.94.4 - - [19/Sep/2025:00:04:15 +0800] "GET /api/check-login HTTP/1.1" 200 35 "http://101.43.95.130:5002/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 804
|
||||
|
||||
@@ -4173,3 +4173,450 @@ SystemExit: 1
|
||||
[2025-09-14 10:25:24 +0800] [6498] [INFO] Booting worker with pid: 6498
|
||||
[2025-09-14 10:25:24 +0800] [6498] [INFO] 工作进程 6498 已启动
|
||||
[2025-09-14 10:25:24 +0800] [6498] [INFO] 工作进程 6498 初始化完成
|
||||
[2025-09-14 14:02:47 +0800] [32217] [DEBUG] Current configuration:
|
||||
config: gunicorn.conf.py
|
||||
wsgi_app: None
|
||||
bind: ['0.0.0.0:5002']
|
||||
backlog: 2048
|
||||
workers: 5
|
||||
worker_class: sync
|
||||
threads: 1
|
||||
worker_connections: 1000
|
||||
max_requests: 1000
|
||||
max_requests_jitter: 100
|
||||
timeout: 120
|
||||
graceful_timeout: 60
|
||||
keepalive: 2
|
||||
limit_request_line: 4094
|
||||
limit_request_fields: 100
|
||||
limit_request_field_size: 8190
|
||||
reload: False
|
||||
reload_engine: auto
|
||||
reload_extra_files: []
|
||||
spew: False
|
||||
check_config: False
|
||||
print_config: False
|
||||
preload_app: True
|
||||
sendfile: None
|
||||
reuse_port: False
|
||||
chdir: /home/renjianbo/aitsc
|
||||
daemon: False
|
||||
raw_env: ['FLASK_ENV=production']
|
||||
pidfile: logs/gunicorn.pid
|
||||
worker_tmp_dir: None
|
||||
user: 1003
|
||||
group: 1003
|
||||
umask: 0
|
||||
initgroups: False
|
||||
tmp_upload_dir: None
|
||||
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
|
||||
forwarded_allow_ips: ['127.0.0.1']
|
||||
accesslog: logs/gunicorn_access.log
|
||||
disable_redirect_access_to_syslog: False
|
||||
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s
|
||||
errorlog: logs/gunicorn_error.log
|
||||
loglevel: debug
|
||||
capture_output: False
|
||||
logger_class: gunicorn.glogging.Logger
|
||||
logconfig: None
|
||||
logconfig_dict: {}
|
||||
logconfig_json: None
|
||||
syslog_addr: udp://localhost:514
|
||||
syslog: False
|
||||
syslog_prefix: None
|
||||
syslog_facility: user
|
||||
enable_stdio_inheritance: False
|
||||
statsd_host: None
|
||||
dogstatsd_tags:
|
||||
statsd_prefix:
|
||||
proc_name: None
|
||||
default_proc_name: run_dev:app
|
||||
pythonpath: None
|
||||
paste: None
|
||||
on_starting: <function on_starting at 0x7fb559a28c20>
|
||||
on_reload: <function on_reload at 0x7fb559a28b80>
|
||||
when_ready: <function WhenReady.when_ready at 0x7fb55a13a5c0>
|
||||
pre_fork: <function pre_fork at 0x7fb559a28e00>
|
||||
post_fork: <function post_fork at 0x7fb559a86ca0>
|
||||
post_worker_init: <function post_worker_init at 0x7fb559a86d40>
|
||||
worker_int: <function worker_int at 0x7fb559a28cc0>
|
||||
worker_abort: <function worker_abort at 0x7fb559a86de0>
|
||||
pre_exec: <function PreExec.pre_exec at 0x7fb55a13ade0>
|
||||
pre_request: <function PreRequest.pre_request at 0x7fb55a13af20>
|
||||
post_request: <function PostRequest.post_request at 0x7fb55a13afc0>
|
||||
child_exit: <function ChildExit.child_exit at 0x7fb55a13b100>
|
||||
worker_exit: <function WorkerExit.worker_exit at 0x7fb55a13b240>
|
||||
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7fb55a13b380>
|
||||
on_exit: <function OnExit.on_exit at 0x7fb55a13b4c0>
|
||||
ssl_context: <function NewSSLContext.ssl_context at 0x7fb55a13b6a0>
|
||||
proxy_protocol: False
|
||||
proxy_allow_ips: ['127.0.0.1']
|
||||
keyfile: None
|
||||
certfile: None
|
||||
ssl_version: 2
|
||||
cert_reqs: 0
|
||||
ca_certs: None
|
||||
suppress_ragged_eofs: True
|
||||
do_handshake_on_connect: False
|
||||
ciphers: None
|
||||
raw_paste_global_conf: []
|
||||
strip_header_spaces: False
|
||||
[2025-09-14 14:02:49 +0800] [32217] [INFO] Starting gunicorn 21.2.0
|
||||
[2025-09-14 14:02:49 +0800] [32217] [INFO] Gunicorn服务器启动中...
|
||||
[2025-09-14 14:02:49 +0800] [32217] [DEBUG] Arbiter booted
|
||||
[2025-09-14 14:02:49 +0800] [32217] [INFO] Listening at: http://0.0.0.0:5002 (32217)
|
||||
[2025-09-14 14:02:49 +0800] [32217] [INFO] Using worker: sync
|
||||
[2025-09-14 14:02:49 +0800] [32217] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:02:49 +0800] [32262] [INFO] Booting worker with pid: 32262
|
||||
[2025-09-14 14:02:49 +0800] [32262] [INFO] 工作进程 32262 已启动
|
||||
[2025-09-14 14:02:49 +0800] [32217] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:02:49 +0800] [32262] [INFO] 工作进程 32262 初始化完成
|
||||
[2025-09-14 14:02:49 +0800] [32263] [INFO] Booting worker with pid: 32263
|
||||
[2025-09-14 14:02:49 +0800] [32263] [INFO] 工作进程 32263 已启动
|
||||
[2025-09-14 14:02:49 +0800] [32263] [INFO] 工作进程 32263 初始化完成
|
||||
[2025-09-14 14:02:49 +0800] [32217] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:02:49 +0800] [32264] [INFO] Booting worker with pid: 32264
|
||||
[2025-09-14 14:02:49 +0800] [32264] [INFO] 工作进程 32264 已启动
|
||||
[2025-09-14 14:02:49 +0800] [32264] [INFO] 工作进程 32264 初始化完成
|
||||
[2025-09-14 14:02:49 +0800] [32217] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:02:49 +0800] [32266] [INFO] Booting worker with pid: 32266
|
||||
[2025-09-14 14:02:49 +0800] [32266] [INFO] 工作进程 32266 已启动
|
||||
[2025-09-14 14:02:49 +0800] [32266] [INFO] 工作进程 32266 初始化完成
|
||||
[2025-09-14 14:02:50 +0800] [32217] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:02:50 +0800] [32267] [INFO] Booting worker with pid: 32267
|
||||
[2025-09-14 14:02:50 +0800] [32267] [INFO] 工作进程 32267 已启动
|
||||
[2025-09-14 14:02:50 +0800] [32267] [INFO] 工作进程 32267 初始化完成
|
||||
[2025-09-14 14:02:50 +0800] [32217] [DEBUG] 5 workers
|
||||
[2025-09-14 14:03:28 +0800] [32267] [DEBUG] GET /
|
||||
[2025-09-14 14:03:29 +0800] [32263] [DEBUG] GET /api/check-login
|
||||
[2025-09-14 14:03:48 +0800] [32266] [INFO] 工作进程 32266 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32267] [INFO] 工作进程 32267 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32264] [INFO] 工作进程 32264 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32263] [INFO] 工作进程 32263 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32262] [INFO] 工作进程 32262 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32217] [INFO] Handling signal: int
|
||||
[2025-09-14 14:03:48 +0800] [32262] [INFO] 工作进程 32262 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32267] [INFO] 工作进程 32267 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32263] [INFO] 工作进程 32263 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32264] [INFO] 工作进程 32264 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32266] [INFO] 工作进程 32266 被中断
|
||||
[2025-09-14 14:03:48 +0800] [32262] [INFO] Worker exiting (pid: 32262)
|
||||
[2025-09-14 14:03:48 +0800] [32263] [INFO] Worker exiting (pid: 32263)
|
||||
[2025-09-14 14:03:48 +0800] [32267] [INFO] Worker exiting (pid: 32267)
|
||||
[2025-09-14 14:03:48 +0800] [32264] [INFO] Worker exiting (pid: 32264)
|
||||
[2025-09-14 14:03:48 +0800] [32266] [INFO] Worker exiting (pid: 32266)
|
||||
[2025-09-14 14:03:50 +0800] [32217] [INFO] Shutting down: Master
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] Starting gunicorn 21.2.0
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] Gunicorn服务器启动中...
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] Listening at: http://0.0.0.0:5002 (4123)
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] Using worker: sync
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:05:06 +0800] [7999] [INFO] Booting worker with pid: 7999
|
||||
[2025-09-14 14:05:06 +0800] [7999] [INFO] 工作进程 7999 已启动
|
||||
[2025-09-14 14:05:06 +0800] [7999] [INFO] 工作进程 7999 初始化完成
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:05:06 +0800] [8108] [INFO] Booting worker with pid: 8108
|
||||
[2025-09-14 14:05:06 +0800] [8108] [INFO] 工作进程 8108 已启动
|
||||
[2025-09-14 14:05:06 +0800] [8108] [INFO] 工作进程 8108 初始化完成
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:05:06 +0800] [8207] [INFO] Booting worker with pid: 8207
|
||||
[2025-09-14 14:05:06 +0800] [8207] [INFO] 工作进程 8207 已启动
|
||||
[2025-09-14 14:05:06 +0800] [8207] [INFO] 工作进程 8207 初始化完成
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:05:06 +0800] [8286] [INFO] Booting worker with pid: 8286
|
||||
[2025-09-14 14:05:06 +0800] [8286] [INFO] 工作进程 8286 已启动
|
||||
[2025-09-14 14:05:06 +0800] [8286] [INFO] 工作进程 8286 初始化完成
|
||||
[2025-09-14 14:05:06 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 14:05:06 +0800] [8389] [INFO] Booting worker with pid: 8389
|
||||
[2025-09-14 14:05:06 +0800] [8389] [INFO] 工作进程 8389 已启动
|
||||
[2025-09-14 14:05:06 +0800] [8389] [INFO] 工作进程 8389 初始化完成
|
||||
[2025-09-14 15:40:23,178] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:40:23,246] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:42:53,566] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:42:53,582] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:45:51,041] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:45:51,093] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:46:43,416] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:46:43,421] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:49:14,934] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 15:49:14,938] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 16:23:57 +0800] [8207] [WARNING] Invalid request from ip=3.131.215.38: Invalid HTTP request line: 'SSH-2.0-Go'
|
||||
[2025-09-14 19:00:32,760] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 19:00:32,792] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-14 19:27:18 +0800] [4123] [ERROR] Worker (pid:7999) was sent SIGHUP!
|
||||
[2025-09-14 19:27:18 +0800] [4123] [ERROR] Worker (pid:8207) was sent SIGHUP!
|
||||
[2025-09-14 19:27:18 +0800] [4123] [ERROR] Worker (pid:8286) was sent SIGHUP!
|
||||
[2025-09-14 19:27:18 +0800] [4123] [ERROR] Worker (pid:8389) was sent SIGHUP!
|
||||
[2025-09-14 19:27:18 +0800] [4123] [ERROR] Worker (pid:8108) was sent SIGHUP!
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [18868] [INFO] Booting worker with pid: 18868
|
||||
[2025-09-14 19:27:18 +0800] [18868] [INFO] 工作进程 18868 已启动
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [18868] [INFO] 工作进程 18868 初始化完成
|
||||
[2025-09-14 19:27:18 +0800] [18869] [INFO] Booting worker with pid: 18869
|
||||
[2025-09-14 19:27:18 +0800] [18869] [INFO] 工作进程 18869 已启动
|
||||
[2025-09-14 19:27:18 +0800] [18869] [INFO] 工作进程 18869 初始化完成
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [18870] [INFO] Booting worker with pid: 18870
|
||||
[2025-09-14 19:27:18 +0800] [18870] [INFO] 工作进程 18870 已启动
|
||||
[2025-09-14 19:27:18 +0800] [18870] [INFO] 工作进程 18870 初始化完成
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [18871] [INFO] Booting worker with pid: 18871
|
||||
[2025-09-14 19:27:18 +0800] [18871] [INFO] 工作进程 18871 已启动
|
||||
[2025-09-14 19:27:18 +0800] [18871] [INFO] 工作进程 18871 初始化完成
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] Handling signal: hup
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] Hang up: Master
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] Gunicorn服务器重载中...
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [18872] [INFO] Booting worker with pid: 18872
|
||||
[2025-09-14 19:27:18 +0800] [18872] [INFO] 工作进程 18872 已启动
|
||||
[2025-09-14 19:27:18 +0800] [18872] [INFO] 工作进程 18872 初始化完成
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [18873] [INFO] Booting worker with pid: 18873
|
||||
[2025-09-14 19:27:18 +0800] [18873] [INFO] 工作进程 18873 已启动
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [18873] [INFO] 工作进程 18873 初始化完成
|
||||
[2025-09-14 19:27:18 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-14 19:27:18 +0800] [18874] [INFO] Booting worker with pid: 18874
|
||||
[2025-09-14 19:27:18 +0800] [18874] [INFO] 工作进程 18874 已启动
|
||||
[2025-09-14 19:27:18 +0800] [18869] [INFO] Worker exiting (pid: 18869)
|
||||
[2025-09-14 19:27:18 +0800] [18874] [INFO] 工作进程 18874 初始化完成
|
||||
[2025-09-14 19:27:18 +0800] [18868] [INFO] Worker exiting (pid: 18868)
|
||||
[2025-09-14 19:27:18 +0800] [18870] [INFO] Worker exiting (pid: 18870)
|
||||
[2025-09-14 19:27:18 +0800] [18876] [INFO] Booting worker with pid: 18876
|
||||
[2025-09-14 19:27:18 +0800] [18876] [INFO] 工作进程 18876 已启动
|
||||
[2025-09-14 19:27:18 +0800] [18876] [INFO] 工作进程 18876 初始化完成
|
||||
[2025-09-14 19:27:18 +0800] [18871] [INFO] Worker exiting (pid: 18871)
|
||||
[2025-09-14 19:27:18 +0800] [18875] [INFO] Booting worker with pid: 18875
|
||||
[2025-09-14 19:27:18 +0800] [18875] [INFO] 工作进程 18875 已启动
|
||||
[2025-09-14 19:27:18 +0800] [18875] [INFO] 工作进程 18875 初始化完成
|
||||
[2025-09-14 22:09:13 +0800] [18872] [WARNING] Invalid request from ip=79.124.49.202: Invalid HTTP request line: '\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr'
|
||||
[2025-09-15 04:03:49 +0800] [18872] [WARNING] Invalid request from ip=185.170.144.3: Invalid HTTP request line: '\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr'
|
||||
[2025-09-15 04:28:40 +0800] [18873] [WARNING] Invalid request from ip=194.0.234.12: Invalid HTTP request line: '\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr'
|
||||
[2025-09-15 05:49:25 +0800] [18872] [WARNING] Invalid request from ip=79.124.49.202: Invalid HTTP request line: '\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr'
|
||||
[2025-09-15 11:57:43 +0800] [18873] [WARNING] Invalid request from ip=93.123.109.112: Invalid HTTP request line: 'SSH-2.0-Go'
|
||||
[2025-09-15 14:34:29 +0800] [18875] [WARNING] Invalid request from ip=1.82.133.130: Invalid HTTP request line: ''
|
||||
[2025-09-15 17:54:09 +0800] [18872] [WARNING] Invalid request from ip=3.131.215.38: Invalid HTTP request line: 'SSH-2.0-Go'
|
||||
[2025-09-15 20:48:14 +0800] [18875] [WARNING] Invalid request from ip=37.60.241.154: Invalid HTTP request line: 'SSH-2.0-OpenSSH'
|
||||
[2025-09-16 17:08:44 +0800] [18875] [WARNING] Invalid request from ip=3.130.96.91: Invalid HTTP request line: 'SSH-2.0-Go'
|
||||
[2025-09-16 19:37:44 +0800] [4123] [CRITICAL] WORKER TIMEOUT (pid:18872)
|
||||
[2025-09-16 19:37:44 +0800] [18872] [INFO] 工作进程 18872 异常退出
|
||||
[2025-09-16 19:37:44 +0800] [18872] [INFO] Worker exiting (pid: 18872)
|
||||
[2025-09-16 19:37:44 +0800] [4123] [ERROR] Worker (pid:18872) exited with code 1
|
||||
[2025-09-16 19:37:44 +0800] [4123] [ERROR] Worker (pid:18872) exited with code 1.
|
||||
[2025-09-16 19:37:44 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-16 19:37:44 +0800] [19487] [INFO] Booting worker with pid: 19487
|
||||
[2025-09-16 19:37:44 +0800] [19487] [INFO] 工作进程 19487 已启动
|
||||
[2025-09-16 19:37:44 +0800] [19487] [INFO] 工作进程 19487 初始化完成
|
||||
[2025-09-17 00:05:52,296] ERROR in app: Exception on / [POST]
|
||||
Traceback (most recent call last):
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 2190, in wsgi_app
|
||||
response = self.full_dispatch_request()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1486, in full_dispatch_request
|
||||
rv = self.handle_user_exception(e)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask_cors/extension.py", line 176, in wrapped_function
|
||||
return cors_after_request(app.make_response(f(*args, **kwargs)))
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1484, in full_dispatch_request
|
||||
rv = self.dispatch_request()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1469, in dispatch_request
|
||||
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/aitsc/src/flask_prompt_master/routes/routes.py", line 129, in index
|
||||
generated_text = generate_with_llm(form.input_text.data, template_id)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/aitsc/src/flask_prompt_master/routes/routes.py", line 53, in generate_with_llm
|
||||
print("\n=== API 调用参数 ===")
|
||||
OSError: [Errno 5] Input/output error
|
||||
[2025-09-17 02:25:19 +0800] [19487] [WARNING] Invalid request from ip=185.170.144.3: Invalid HTTP request line: '\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr'
|
||||
[2025-09-17 16:51:46 +0800] [18875] [WARNING] Invalid request from ip=3.132.23.201: Invalid HTTP request line: 'SSH-2.0-Go'
|
||||
[2025-09-17 17:33:10 +0800] [18875] [WARNING] Invalid request from ip=3.134.148.59: Invalid HTTP request line: 'SSH-2.0-Go'
|
||||
[2025-09-18 06:55:03 +0800] [18876] [WARNING] Invalid request from ip=124.220.188.32: Invalid HTTP request line: '*1'
|
||||
[2025-09-18 06:55:06 +0800] [18875] [WARNING] Invalid request from ip=124.220.188.32: Invalid HTTP request line: ''
|
||||
[2025-09-18 06:55:06 +0800] [18874] [WARNING] Invalid request from ip=124.220.188.32: Invalid HTTP Version: 'RTSP/1.0'
|
||||
[2025-09-18 06:55:06 +0800] [18876] [WARNING] Invalid request from ip=124.220.188.32: Invalid HTTP request line: 'EHLO'
|
||||
[2025-09-18 06:55:06 +0800] [18876] [WARNING] Invalid request from ip=124.220.188.32: Invalid HTTP request line: 'HELP'
|
||||
[2025-09-18 06:55:08 +0800] [18875] [WARNING] Invalid request from ip=124.220.188.32: Invalid HTTP request line: '\x03\x00\x00*%à\x00\x00\x00\x00\x00Cookie: mstshash=nmap'
|
||||
[2025-09-18 06:55:08 +0800] [18875] [WARNING] Invalid request from ip=124.220.188.32: Invalid HTTP Version: 'SIP/2.0'
|
||||
[2025-09-18 12:35:58 +0800] [4123] [CRITICAL] WORKER TIMEOUT (pid:19487)
|
||||
[2025-09-18 12:35:58 +0800] [19487] [INFO] 工作进程 19487 异常退出
|
||||
[2025-09-18 12:35:58 +0800] [19487] [INFO] Worker exiting (pid: 19487)
|
||||
[2025-09-18 12:35:59 +0800] [4123] [ERROR] Worker (pid:19487) exited with code 1
|
||||
[2025-09-18 12:35:59 +0800] [4123] [ERROR] Worker (pid:19487) exited with code 1.
|
||||
[2025-09-18 12:35:59 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 12:35:59 +0800] [13848] [INFO] Booting worker with pid: 13848
|
||||
[2025-09-18 12:35:59 +0800] [13848] [INFO] 工作进程 13848 已启动
|
||||
[2025-09-18 12:35:59 +0800] [13848] [INFO] 工作进程 13848 初始化完成
|
||||
[2025-09-18 14:12:57 +0800] [4123] [CRITICAL] WORKER TIMEOUT (pid:13848)
|
||||
[2025-09-18 14:12:57 +0800] [13848] [INFO] 工作进程 13848 异常退出
|
||||
[2025-09-18 14:12:57 +0800] [13848] [INFO] Worker exiting (pid: 13848)
|
||||
[2025-09-18 14:12:58 +0800] [4123] [ERROR] Worker (pid:13848) exited with code 1
|
||||
[2025-09-18 14:12:58 +0800] [4123] [ERROR] Worker (pid:13848) exited with code 1.
|
||||
[2025-09-18 14:12:58 +0800] [4123] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 14:12:58 +0800] [23602] [INFO] Booting worker with pid: 23602
|
||||
[2025-09-18 14:12:58 +0800] [23602] [INFO] 工作进程 23602 已启动
|
||||
[2025-09-18 14:12:58 +0800] [23602] [INFO] 工作进程 23602 初始化完成
|
||||
[2025-09-18 16:31:19 +0800] [18876] [WARNING] Invalid request from ip=3.130.96.91: Invalid HTTP request line: 'SSH-2.0-Go'
|
||||
[2025-09-18 22:23:27,175] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-18 22:23:27,176] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-18 22:24:31,816] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-18 22:24:31,819] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-18 22:25:31,117] ERROR in poetry: 生成古诗词AI解析时出错: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-18 22:25:31,119] ERROR in poetry: 古诗词分析失败: 古诗词解析生成失败: HTTPSConnectionPool(host='api.deepseek.com', port=443): Read timed out.
|
||||
[2025-09-18 23:32:56,838] ERROR in app: Exception on / [POST]
|
||||
Traceback (most recent call last):
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 2190, in wsgi_app
|
||||
response = self.full_dispatch_request()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1486, in full_dispatch_request
|
||||
rv = self.handle_user_exception(e)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask_cors/extension.py", line 176, in wrapped_function
|
||||
return cors_after_request(app.make_response(f(*args, **kwargs)))
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1484, in full_dispatch_request
|
||||
rv = self.dispatch_request()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/miniconda3/envs/myenv/lib/python3.12/site-packages/flask/app.py", line 1469, in dispatch_request
|
||||
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/aitsc/src/flask_prompt_master/routes/routes.py", line 129, in index
|
||||
generated_text = generate_with_llm(form.input_text.data, template_id)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/renjianbo/aitsc/src/flask_prompt_master/routes/routes.py", line 53, in generate_with_llm
|
||||
print("\n=== API 调用参数 ===")
|
||||
OSError: [Errno 5] Input/output error
|
||||
[2025-09-18 23:36:45 +0800] [18873] [INFO] Worker exiting (pid: 18873)
|
||||
[2025-09-18 23:36:45 +0800] [4123] [INFO] Handling signal: term
|
||||
[2025-09-18 23:36:45 +0800] [18875] [INFO] Worker exiting (pid: 18875)
|
||||
[2025-09-18 23:36:45 +0800] [18874] [INFO] Worker exiting (pid: 18874)
|
||||
[2025-09-18 23:36:45 +0800] [18876] [INFO] Worker exiting (pid: 18876)
|
||||
[2025-09-18 23:36:45 +0800] [23602] [INFO] Worker exiting (pid: 23602)
|
||||
[2025-09-18 23:36:46 +0800] [4123] [ERROR] Worker (pid:18875) exited with code 120
|
||||
[2025-09-18 23:36:46 +0800] [4123] [ERROR] Worker (pid:18875) exited with code 120.
|
||||
[2025-09-18 23:36:47 +0800] [4123] [ERROR] Worker (pid:18874) exited with code 120
|
||||
[2025-09-18 23:36:47 +0800] [4123] [ERROR] Worker (pid:18874) exited with code 120.
|
||||
[2025-09-18 23:36:47 +0800] [4123] [ERROR] Worker (pid:18873) exited with code 120
|
||||
[2025-09-18 23:36:47 +0800] [4123] [ERROR] Worker (pid:18873) exited with code 120.
|
||||
[2025-09-18 23:36:47 +0800] [4123] [INFO] Shutting down: Master
|
||||
[2025-09-18 23:38:01 +0800] [29418] [INFO] Starting gunicorn 21.2.0
|
||||
[2025-09-18 23:38:01 +0800] [29418] [INFO] Gunicorn服务器启动中...
|
||||
[2025-09-18 23:38:01 +0800] [29418] [INFO] Listening at: http://0.0.0.0:5002 (29418)
|
||||
[2025-09-18 23:38:01 +0800] [29418] [INFO] Using worker: sync
|
||||
[2025-09-18 23:38:01 +0800] [29418] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:38:01 +0800] [29465] [INFO] Booting worker with pid: 29465
|
||||
[2025-09-18 23:38:01 +0800] [29465] [INFO] 工作进程 29465 已启动
|
||||
[2025-09-18 23:38:01 +0800] [29465] [INFO] 工作进程 29465 初始化完成
|
||||
[2025-09-18 23:38:01 +0800] [29418] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:38:01 +0800] [29466] [INFO] Booting worker with pid: 29466
|
||||
[2025-09-18 23:38:01 +0800] [29466] [INFO] 工作进程 29466 已启动
|
||||
[2025-09-18 23:38:01 +0800] [29466] [INFO] 工作进程 29466 初始化完成
|
||||
[2025-09-18 23:38:02 +0800] [29418] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:38:02 +0800] [29467] [INFO] Booting worker with pid: 29467
|
||||
[2025-09-18 23:38:02 +0800] [29467] [INFO] 工作进程 29467 已启动
|
||||
[2025-09-18 23:38:02 +0800] [29467] [INFO] 工作进程 29467 初始化完成
|
||||
[2025-09-18 23:38:02 +0800] [29418] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:38:02 +0800] [29468] [INFO] Booting worker with pid: 29468
|
||||
[2025-09-18 23:38:02 +0800] [29468] [INFO] 工作进程 29468 已启动
|
||||
[2025-09-18 23:38:02 +0800] [29468] [INFO] 工作进程 29468 初始化完成
|
||||
[2025-09-18 23:38:02 +0800] [29418] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:38:02 +0800] [29470] [INFO] Booting worker with pid: 29470
|
||||
[2025-09-18 23:38:02 +0800] [29470] [INFO] 工作进程 29470 已启动
|
||||
[2025-09-18 23:38:02 +0800] [29470] [INFO] 工作进程 29470 初始化完成
|
||||
[2025-09-18 23:42:57 +0800] [29465] [INFO] Worker exiting (pid: 29465)
|
||||
[2025-09-18 23:42:57 +0800] [29418] [INFO] Handling signal: term
|
||||
[2025-09-18 23:42:57 +0800] [29466] [INFO] Worker exiting (pid: 29466)
|
||||
[2025-09-18 23:42:57 +0800] [29467] [INFO] Worker exiting (pid: 29467)
|
||||
[2025-09-18 23:42:57 +0800] [29468] [INFO] Worker exiting (pid: 29468)
|
||||
[2025-09-18 23:42:57 +0800] [29470] [INFO] Worker exiting (pid: 29470)
|
||||
[2025-09-18 23:42:59 +0800] [29418] [INFO] Shutting down: Master
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] Starting gunicorn 21.2.0
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] Gunicorn服务器启动中...
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] Listening at: http://0.0.0.0:5002 (22801)
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] Using worker: sync
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:43:09 +0800] [22828] [INFO] Booting worker with pid: 22828
|
||||
[2025-09-18 23:43:09 +0800] [22828] [INFO] 工作进程 22828 已启动
|
||||
[2025-09-18 23:43:09 +0800] [22828] [INFO] 工作进程 22828 初始化完成
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:43:09 +0800] [22830] [INFO] Booting worker with pid: 22830
|
||||
[2025-09-18 23:43:09 +0800] [22830] [INFO] 工作进程 22830 已启动
|
||||
[2025-09-18 23:43:09 +0800] [22830] [INFO] 工作进程 22830 初始化完成
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:43:09 +0800] [22831] [INFO] Booting worker with pid: 22831
|
||||
[2025-09-18 23:43:09 +0800] [22831] [INFO] 工作进程 22831 已启动
|
||||
[2025-09-18 23:43:09 +0800] [22831] [INFO] 工作进程 22831 初始化完成
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:43:09 +0800] [22832] [INFO] Booting worker with pid: 22832
|
||||
[2025-09-18 23:43:09 +0800] [22832] [INFO] 工作进程 22832 已启动
|
||||
[2025-09-18 23:43:09 +0800] [22832] [INFO] 工作进程 22832 初始化完成
|
||||
[2025-09-18 23:43:09 +0800] [22801] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:43:09 +0800] [22833] [INFO] Booting worker with pid: 22833
|
||||
[2025-09-18 23:43:09 +0800] [22833] [INFO] 工作进程 22833 已启动
|
||||
[2025-09-18 23:43:09 +0800] [22833] [INFO] 工作进程 22833 初始化完成
|
||||
[2025-09-18 23:46:34 +0800] [22830] [INFO] Worker exiting (pid: 22830)
|
||||
[2025-09-18 23:46:34 +0800] [22801] [INFO] Handling signal: term
|
||||
[2025-09-18 23:46:34 +0800] [22828] [INFO] Worker exiting (pid: 22828)
|
||||
[2025-09-18 23:46:34 +0800] [22831] [INFO] Worker exiting (pid: 22831)
|
||||
[2025-09-18 23:46:34 +0800] [22832] [INFO] Worker exiting (pid: 22832)
|
||||
[2025-09-18 23:46:34 +0800] [22833] [INFO] Worker exiting (pid: 22833)
|
||||
[2025-09-18 23:46:36 +0800] [22801] [INFO] Shutting down: Master
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] Starting gunicorn 21.2.0
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] Gunicorn服务器启动中...
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] Listening at: http://0.0.0.0:5002 (15746)
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] Using worker: sync
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:46:47 +0800] [15760] [INFO] Booting worker with pid: 15760
|
||||
[2025-09-18 23:46:47 +0800] [15760] [INFO] 工作进程 15760 已启动
|
||||
[2025-09-18 23:46:47 +0800] [15760] [INFO] 工作进程 15760 初始化完成
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:46:47 +0800] [15761] [INFO] Booting worker with pid: 15761
|
||||
[2025-09-18 23:46:47 +0800] [15761] [INFO] 工作进程 15761 已启动
|
||||
[2025-09-18 23:46:47 +0800] [15761] [INFO] 工作进程 15761 初始化完成
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:46:47 +0800] [15762] [INFO] Booting worker with pid: 15762
|
||||
[2025-09-18 23:46:47 +0800] [15762] [INFO] 工作进程 15762 已启动
|
||||
[2025-09-18 23:46:47 +0800] [15762] [INFO] 工作进程 15762 初始化完成
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:46:47 +0800] [15763] [INFO] Booting worker with pid: 15763
|
||||
[2025-09-18 23:46:47 +0800] [15763] [INFO] 工作进程 15763 已启动
|
||||
[2025-09-18 23:46:47 +0800] [15763] [INFO] 工作进程 15763 初始化完成
|
||||
[2025-09-18 23:46:47 +0800] [15746] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:46:47 +0800] [15764] [INFO] Booting worker with pid: 15764
|
||||
[2025-09-18 23:46:47 +0800] [15764] [INFO] 工作进程 15764 已启动
|
||||
[2025-09-18 23:46:47 +0800] [15764] [INFO] 工作进程 15764 初始化完成
|
||||
[2025-09-18 23:58:26 +0800] [15760] [INFO] Worker exiting (pid: 15760)
|
||||
[2025-09-18 23:58:26 +0800] [15746] [INFO] Handling signal: term
|
||||
[2025-09-18 23:58:26 +0800] [15761] [INFO] Worker exiting (pid: 15761)
|
||||
[2025-09-18 23:58:26 +0800] [15762] [INFO] Worker exiting (pid: 15762)
|
||||
[2025-09-18 23:58:26 +0800] [15763] [INFO] Worker exiting (pid: 15763)
|
||||
[2025-09-18 23:58:26 +0800] [15764] [INFO] Worker exiting (pid: 15764)
|
||||
[2025-09-18 23:58:27 +0800] [15746] [INFO] Shutting down: Master
|
||||
[2025-09-18 23:58:37 +0800] [3055] [INFO] Starting gunicorn 21.2.0
|
||||
[2025-09-18 23:58:37 +0800] [3055] [INFO] Gunicorn服务器启动中...
|
||||
[2025-09-18 23:58:37 +0800] [3055] [INFO] Listening at: http://0.0.0.0:5002 (3055)
|
||||
[2025-09-18 23:58:37 +0800] [3055] [INFO] Using worker: sync
|
||||
[2025-09-18 23:58:37 +0800] [3055] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:58:37 +0800] [3074] [INFO] Booting worker with pid: 3074
|
||||
[2025-09-18 23:58:37 +0800] [3074] [INFO] 工作进程 3074 已启动
|
||||
[2025-09-18 23:58:37 +0800] [3074] [INFO] 工作进程 3074 初始化完成
|
||||
[2025-09-18 23:58:38 +0800] [3055] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:58:38 +0800] [3075] [INFO] Booting worker with pid: 3075
|
||||
[2025-09-18 23:58:38 +0800] [3075] [INFO] 工作进程 3075 已启动
|
||||
[2025-09-18 23:58:38 +0800] [3075] [INFO] 工作进程 3075 初始化完成
|
||||
[2025-09-18 23:58:38 +0800] [3055] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:58:38 +0800] [3076] [INFO] Booting worker with pid: 3076
|
||||
[2025-09-18 23:58:38 +0800] [3076] [INFO] 工作进程 3076 已启动
|
||||
[2025-09-18 23:58:38 +0800] [3076] [INFO] 工作进程 3076 初始化完成
|
||||
[2025-09-18 23:58:38 +0800] [3055] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:58:38 +0800] [3077] [INFO] Booting worker with pid: 3077
|
||||
[2025-09-18 23:58:38 +0800] [3077] [INFO] 工作进程 3077 已启动
|
||||
[2025-09-18 23:58:38 +0800] [3077] [INFO] 工作进程 3077 初始化完成
|
||||
[2025-09-18 23:58:38 +0800] [3055] [INFO] 工作进程 [booting] 即将启动
|
||||
[2025-09-18 23:58:38 +0800] [3078] [INFO] Booting worker with pid: 3078
|
||||
[2025-09-18 23:58:38 +0800] [3078] [INFO] 工作进程 3078 已启动
|
||||
[2025-09-18 23:58:38 +0800] [3078] [INFO] 工作进程 3078 初始化完成
|
||||
|
||||
@@ -56,6 +56,10 @@ def create_app(config_class=None):
|
||||
from src.flask_prompt_master.routes.meal_planning import meal_planning_bp
|
||||
app.register_blueprint(meal_planning_bp)
|
||||
|
||||
# 注册古诗词解析蓝图
|
||||
from src.flask_prompt_master.routes.poetry import poetry_bp
|
||||
app.register_blueprint(poetry_bp)
|
||||
|
||||
# 初始化后台管理
|
||||
from src.flask_prompt_master.admin import init_admin
|
||||
init_admin(app)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
71
src/flask_prompt_master/models/poetry_favorites.py
Normal file
71
src/flask_prompt_master/models/poetry_favorites.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime
|
||||
from src.flask_prompt_master import db
|
||||
|
||||
class PoetryFavorite(db.Model):
|
||||
"""古诗词收藏表"""
|
||||
__tablename__ = 'poetry_favorites'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
user_id = db.Column(db.String(50), nullable=False, comment='用户ID(可以是IP或session_id)')
|
||||
|
||||
# 古诗词基本信息
|
||||
poetry_title = db.Column(db.String(200), nullable=False, comment='诗词标题')
|
||||
author = db.Column(db.String(100), nullable=False, comment='作者姓名')
|
||||
dynasty = db.Column(db.String(50), nullable=True, comment='朝代')
|
||||
|
||||
# 解析参数
|
||||
translation_style = db.Column(db.String(100), nullable=True, comment='翻译风格')
|
||||
interpretation_depth = db.Column(db.String(100), nullable=True, comment='解读深度')
|
||||
purpose = db.Column(db.String(100), nullable=True, comment='使用目的')
|
||||
target_audience = db.Column(db.String(100), nullable=True, comment='目标读者')
|
||||
translation_quality = db.Column(db.String(100), nullable=True, comment='译文质量')
|
||||
annotation_detail = db.Column(db.String(100), nullable=True, comment='注释详细程度')
|
||||
interpretation_level = db.Column(db.String(100), nullable=True, comment='解读层次')
|
||||
|
||||
# 解析结果
|
||||
original_text = db.Column(db.Text, nullable=True, comment='原文内容')
|
||||
analysis_result = db.Column(db.Text, nullable=False, comment='AI解析结果')
|
||||
|
||||
# 用户信息
|
||||
notes = db.Column(db.Text, nullable=True, comment='用户备注')
|
||||
tags = db.Column(db.String(500), nullable=True, comment='标签(JSON格式)')
|
||||
|
||||
# 时间信息
|
||||
created_time = db.Column(db.DateTime, default=datetime.now, comment='创建时间')
|
||||
updated_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间')
|
||||
|
||||
def to_dict(self):
|
||||
"""转换为字典"""
|
||||
return {
|
||||
'id': self.id,
|
||||
'poetry_title': self.poetry_title,
|
||||
'author': self.author,
|
||||
'dynasty': self.dynasty,
|
||||
'translation_style': self.translation_style,
|
||||
'interpretation_depth': self.interpretation_depth,
|
||||
'purpose': self.purpose,
|
||||
'target_audience': self.target_audience,
|
||||
'translation_quality': self.translation_quality,
|
||||
'annotation_detail': self.annotation_detail,
|
||||
'interpretation_level': self.interpretation_level,
|
||||
'original_text': self.original_text,
|
||||
'analysis_result': self.analysis_result,
|
||||
'notes': self.notes,
|
||||
'tags': self.tags,
|
||||
'created_time': self.created_time.strftime('%Y-%m-%d %H:%M:%S') if self.created_time else None,
|
||||
'updated_time': self.updated_time.strftime('%Y-%m-%d %H:%M:%S') if self.updated_time else None
|
||||
}
|
||||
|
||||
def to_summary_dict(self):
|
||||
"""转换为摘要字典(用于列表显示)"""
|
||||
return {
|
||||
'id': self.id,
|
||||
'poetry_title': self.poetry_title,
|
||||
'author': self.author,
|
||||
'dynasty': self.dynasty,
|
||||
'purpose': self.purpose,
|
||||
'target_audience': self.target_audience,
|
||||
'notes': self.notes,
|
||||
'created_time': self.created_time.strftime('%Y-%m-%d %H:%M:%S') if self.created_time else None
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
415
src/flask_prompt_master/routes/poetry.py
Normal file
415
src/flask_prompt_master/routes/poetry.py
Normal file
@@ -0,0 +1,415 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
古诗词查询与解析路由
|
||||
"""
|
||||
from flask import Blueprint, render_template, request, jsonify, flash, current_app
|
||||
from flask_login import login_required, current_user
|
||||
import requests
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from typing import Dict, Any, Optional
|
||||
from src.flask_prompt_master.services.poetry_favorite_service import PoetryFavoriteService
|
||||
|
||||
# 配置日志
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 创建蓝图
|
||||
poetry_bp = Blueprint('poetry', __name__, url_prefix='/poetry')
|
||||
|
||||
# 配置API
|
||||
SK_API_KEY = "sk-fdf7cc1c73504e628ec0119b7e11b8cc"
|
||||
|
||||
def generate_poetry_analysis(poetry_title, author, dynasty, translation_style,
|
||||
interpretation_depth, purpose, target_audience,
|
||||
translation_quality, annotation_detail, interpretation_level, max_retries=3):
|
||||
"""
|
||||
使用AI模型生成古诗词解析
|
||||
|
||||
Args:
|
||||
poetry_title: 古诗词标题
|
||||
author: 作者姓名
|
||||
dynasty: 朝代
|
||||
translation_style: 翻译风格
|
||||
interpretation_depth: 解读深度
|
||||
purpose: 使用目的
|
||||
target_audience: 目标读者
|
||||
translation_quality: 译文质量要求
|
||||
annotation_detail: 注释详细程度
|
||||
interpretation_level: 解读层次
|
||||
max_retries: 最大重试次数
|
||||
|
||||
Returns:
|
||||
str: AI生成的古诗词解析
|
||||
"""
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
logger.info(f"开始生成古诗词AI解析 (尝试 {attempt + 1}/{max_retries})")
|
||||
|
||||
# 构建提示词
|
||||
system_prompt = f"""你是一位专业的古典文学专家和古诗词翻译家,精通中国古代诗词的文学价值、历史背景、文化内涵和艺术特色。你擅长将古典诗词翻译成现代汉语,既保持原诗的意境和美感,又让现代读者容易理解。你能够提供准确、优美、富有诗意的现代译文,并配以详细的注释和深入的解读。
|
||||
|
||||
背景信息:这首诗词将用于{purpose},目标读者是{target_audience}。请确保译文{translation_quality},注释{annotation_detail},解读{interpretation_level}。
|
||||
|
||||
约束条件:
|
||||
1. 提供准确的原文内容,确保字词无误
|
||||
2. 现代译文要优美流畅,保持原诗的意境和美感
|
||||
3. 注释要详细准确,包含字词解释、典故出处、历史背景
|
||||
4. 解读要深入浅出,适合{target_audience}理解
|
||||
5. 译文要符合现代汉语表达习惯,避免生硬直译
|
||||
6. 如果找不到指定诗词,要提供相似作品或说明原因
|
||||
|
||||
输出格式要求:
|
||||
1. 使用标准Markdown格式
|
||||
2. 标题使用 # ## ### 层级结构
|
||||
3. 重要内容使用 **粗体** 强调
|
||||
4. 列表使用 - 或 1. 格式
|
||||
5. 代码或特殊内容使用 `代码块` 格式
|
||||
6. 确保格式清晰,便于阅读和复制
|
||||
|
||||
请严格按照Markdown格式输出:"""
|
||||
|
||||
user_prompt = f"""请根据提供的古诗词信息,查找并提供完整的诗词内容、现代译文、详细注释和深度解读:
|
||||
|
||||
诗词标题:{poetry_title}
|
||||
作者:{author}
|
||||
朝代:{dynasty}
|
||||
翻译要求:{translation_style}
|
||||
解读深度:{interpretation_depth}
|
||||
|
||||
请提供完整的古诗词解析,包括原文、译文、注释和解读。"""
|
||||
|
||||
# 构建消息
|
||||
messages = [
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": user_prompt}
|
||||
]
|
||||
|
||||
logger.info("发送请求到DeepSeek API")
|
||||
|
||||
# 发送请求
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {SK_API_KEY}"
|
||||
}
|
||||
|
||||
data = {
|
||||
"model": "deepseek-chat",
|
||||
"messages": messages,
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 2000 # 增加token限制以支持更长的古诗词解析
|
||||
}
|
||||
|
||||
response = requests.post("https://api.deepseek.com/v1/chat/completions",
|
||||
headers=headers, json=data, timeout=60) # 增加超时时间
|
||||
response.raise_for_status()
|
||||
|
||||
result = response.json()["choices"][0]["message"]["content"]
|
||||
|
||||
logger.info("古诗词AI解析生成成功")
|
||||
return result
|
||||
|
||||
except requests.exceptions.Timeout as e:
|
||||
logger.warning(f"API请求超时 (尝试 {attempt + 1}/{max_retries}): {e}")
|
||||
if attempt == max_retries - 1:
|
||||
raise Exception(f"古诗词解析生成失败: API请求多次超时")
|
||||
time.sleep(2 ** attempt) # 指数退避
|
||||
continue
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.warning(f"API请求异常 (尝试 {attempt + 1}/{max_retries}): {e}")
|
||||
if attempt == max_retries - 1:
|
||||
raise Exception(f"古诗词解析生成失败: API请求异常 - {e}")
|
||||
time.sleep(2 ** attempt) # 指数退避
|
||||
continue
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"生成古诗词AI解析时出错 (尝试 {attempt + 1}/{max_retries}): {e}")
|
||||
if attempt == max_retries - 1:
|
||||
raise Exception(f"古诗词解析生成失败: {e}")
|
||||
time.sleep(2 ** attempt) # 指数退避
|
||||
continue
|
||||
|
||||
@poetry_bp.route('/')
|
||||
def poetry_page():
|
||||
"""古诗词查询与解析页面"""
|
||||
return render_template('poetry/poetry_page.html')
|
||||
|
||||
@poetry_bp.route('/analyze', methods=['POST'])
|
||||
def analyze_poetry():
|
||||
"""分析古诗词"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
|
||||
# 获取表单数据
|
||||
poetry_title = data.get('poetry_title', '').strip()
|
||||
author = data.get('author', '').strip()
|
||||
dynasty = data.get('dynasty', '').strip()
|
||||
translation_style = data.get('translation_style', '优美流畅')
|
||||
interpretation_depth = data.get('interpretation_depth', '深入浅出')
|
||||
purpose = data.get('purpose', '学习欣赏')
|
||||
target_audience = data.get('target_audience', '一般读者')
|
||||
translation_quality = data.get('translation_quality', '高质量')
|
||||
annotation_detail = data.get('annotation_detail', '详细准确')
|
||||
interpretation_level = data.get('interpretation_level', '深入浅出')
|
||||
|
||||
# 验证必填字段
|
||||
if not poetry_title:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': '请输入诗词标题'
|
||||
})
|
||||
|
||||
if not author:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': '请输入作者姓名'
|
||||
})
|
||||
|
||||
# 生成古诗词解析
|
||||
result = generate_poetry_analysis(
|
||||
poetry_title=poetry_title,
|
||||
author=author,
|
||||
dynasty=dynasty,
|
||||
translation_style=translation_style,
|
||||
interpretation_depth=interpretation_depth,
|
||||
purpose=purpose,
|
||||
target_audience=target_audience,
|
||||
translation_quality=translation_quality,
|
||||
annotation_detail=annotation_detail,
|
||||
interpretation_level=interpretation_level
|
||||
)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'result': result,
|
||||
'poetry_info': {
|
||||
'title': poetry_title,
|
||||
'author': author,
|
||||
'dynasty': dynasty
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"古诗词分析失败: {e}")
|
||||
|
||||
# 根据错误类型提供更友好的错误信息
|
||||
error_message = str(e)
|
||||
if "超时" in error_message or "timeout" in error_message.lower():
|
||||
user_message = "网络连接超时,请稍后重试。如果问题持续存在,可能是服务器繁忙,请稍后再试。"
|
||||
elif "API" in error_message or "api" in error_message.lower():
|
||||
user_message = "AI服务暂时不可用,请稍后重试。"
|
||||
elif "解析" in error_message:
|
||||
user_message = "古诗词解析服务暂时不可用,请稍后重试。"
|
||||
else:
|
||||
user_message = "古诗词分析失败,请检查输入信息后重试。"
|
||||
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': user_message,
|
||||
'error_detail': error_message if current_app.debug else None
|
||||
})
|
||||
|
||||
@poetry_bp.route('/examples')
|
||||
def poetry_examples():
|
||||
"""古诗词示例页面"""
|
||||
examples = [
|
||||
{
|
||||
'title': '静夜思',
|
||||
'author': '李白',
|
||||
'dynasty': '唐',
|
||||
'description': '思乡怀人之作,语言简洁,意境深远'
|
||||
},
|
||||
{
|
||||
'title': '春晓',
|
||||
'author': '孟浩然',
|
||||
'dynasty': '唐',
|
||||
'description': '描写春天早晨的景色,清新自然'
|
||||
},
|
||||
{
|
||||
'title': '水调歌头·明月几时有',
|
||||
'author': '苏轼',
|
||||
'dynasty': '宋',
|
||||
'description': '中秋怀人之作,豪放洒脱,富有哲理'
|
||||
},
|
||||
{
|
||||
'title': '登高',
|
||||
'author': '杜甫',
|
||||
'dynasty': '唐',
|
||||
'description': '登高望远,抒发人生感慨'
|
||||
}
|
||||
]
|
||||
|
||||
return render_template('poetry/poetry_examples.html', examples=examples)
|
||||
|
||||
@poetry_bp.route('/favorites')
|
||||
def poetry_favorites():
|
||||
"""古诗词收藏列表页面"""
|
||||
return render_template('poetry/poetry_favorites.html')
|
||||
|
||||
@poetry_bp.route('/favorites/add', methods=['POST'])
|
||||
def add_poetry_favorite():
|
||||
"""添加古诗词收藏"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
|
||||
# 验证必填字段
|
||||
required_fields = ['poetry_title', 'author', 'analysis_result']
|
||||
for field in required_fields:
|
||||
if not data.get(field):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'缺少必填字段: {field}'
|
||||
})
|
||||
|
||||
# 添加收藏
|
||||
result = PoetryFavoriteService.add_favorite(request, data)
|
||||
|
||||
if result['success']:
|
||||
return jsonify(result)
|
||||
else:
|
||||
return jsonify(result), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"添加古诗词收藏失败: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'添加收藏失败: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@poetry_bp.route('/favorites/list', methods=['GET'])
|
||||
def get_poetry_favorites():
|
||||
"""获取古诗词收藏列表"""
|
||||
try:
|
||||
page = request.args.get('page', 1, type=int)
|
||||
per_page = request.args.get('per_page', 10, type=int)
|
||||
search = request.args.get('search', '')
|
||||
dynasty = request.args.get('dynasty', '')
|
||||
author = request.args.get('author', '')
|
||||
|
||||
result = PoetryFavoriteService.get_favorites(
|
||||
request, page, per_page, search, dynasty, author
|
||||
)
|
||||
|
||||
if result['success']:
|
||||
return jsonify(result)
|
||||
else:
|
||||
return jsonify(result), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取古诗词收藏列表失败: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'获取收藏列表失败: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@poetry_bp.route('/favorites/<int:favorite_id>', methods=['GET'])
|
||||
def get_poetry_favorite_detail(favorite_id):
|
||||
"""获取古诗词收藏详情"""
|
||||
try:
|
||||
result = PoetryFavoriteService.get_favorite_by_id(request, favorite_id)
|
||||
|
||||
if result['success']:
|
||||
return jsonify(result)
|
||||
else:
|
||||
return jsonify(result), 404
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取古诗词收藏详情失败: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'获取收藏详情失败: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@poetry_bp.route('/favorites/<int:favorite_id>', methods=['PUT'])
|
||||
def update_poetry_favorite(favorite_id):
|
||||
"""更新古诗词收藏"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
|
||||
result = PoetryFavoriteService.update_favorite(
|
||||
request, favorite_id,
|
||||
data.get('notes'), data.get('tags')
|
||||
)
|
||||
|
||||
if result['success']:
|
||||
return jsonify(result)
|
||||
else:
|
||||
return jsonify(result), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"更新古诗词收藏失败: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'更新收藏失败: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@poetry_bp.route('/favorites/<int:favorite_id>', methods=['DELETE'])
|
||||
def delete_poetry_favorite(favorite_id):
|
||||
"""删除古诗词收藏"""
|
||||
try:
|
||||
result = PoetryFavoriteService.delete_favorite(request, favorite_id)
|
||||
|
||||
if result['success']:
|
||||
return jsonify(result)
|
||||
else:
|
||||
return jsonify(result), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"删除古诗词收藏失败: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'删除收藏失败: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@poetry_bp.route('/favorites/stats', methods=['GET'])
|
||||
def get_poetry_favorite_stats():
|
||||
"""获取古诗词收藏统计信息"""
|
||||
try:
|
||||
result = PoetryFavoriteService.get_favorite_stats(request)
|
||||
|
||||
if result['success']:
|
||||
return jsonify(result)
|
||||
else:
|
||||
return jsonify(result), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取古诗词收藏统计失败: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'获取统计信息失败: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@poetry_bp.route('/favorites/check', methods=['POST'])
|
||||
def check_poetry_favorite_status():
|
||||
"""检查古诗词收藏状态"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
|
||||
required_fields = ['poetry_title', 'author', 'analysis_result']
|
||||
for field in required_fields:
|
||||
if not data.get(field):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'缺少必填字段: {field}'
|
||||
})
|
||||
|
||||
result = PoetryFavoriteService.check_favorite_status(
|
||||
request,
|
||||
data['poetry_title'],
|
||||
data['author'],
|
||||
data['analysis_result']
|
||||
)
|
||||
|
||||
if result['success']:
|
||||
return jsonify(result)
|
||||
else:
|
||||
return jsonify(result), 400
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"检查古诗词收藏状态失败: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'检查收藏状态失败: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@@ -10,6 +10,10 @@ import requests
|
||||
import hashlib
|
||||
import time
|
||||
import json
|
||||
import logging
|
||||
|
||||
# 配置日志
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
main_bp = Blueprint('main', __name__)
|
||||
|
||||
@@ -49,12 +53,12 @@ def generate_with_llm(input_text, template_id=None, max_retries=3):
|
||||
|
||||
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")
|
||||
# 记录参数到日志
|
||||
logger.info("=== API 调用参数 ===")
|
||||
logger.info(f"模板ID: {template_id}")
|
||||
logger.info(f"输入文本: {input_text}")
|
||||
logger.info(f"系统提示: {system_prompt}")
|
||||
logger.info("==================")
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
|
||||
Binary file not shown.
250
src/flask_prompt_master/services/poetry_favorite_service.py
Normal file
250
src/flask_prompt_master/services/poetry_favorite_service.py
Normal file
@@ -0,0 +1,250 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
from datetime import datetime
|
||||
from src.flask_prompt_master import db
|
||||
from src.flask_prompt_master.models.poetry_favorites import PoetryFavorite
|
||||
|
||||
class PoetryFavoriteService:
|
||||
"""古诗词收藏服务类"""
|
||||
|
||||
@staticmethod
|
||||
def get_user_id(request):
|
||||
"""获取用户ID"""
|
||||
from flask import session
|
||||
|
||||
# 优先使用登录用户的ID
|
||||
if 'user_id' in session:
|
||||
return str(session['user_id'])
|
||||
|
||||
# 如果没有登录,使用IP地址作为临时用户ID
|
||||
return request.remote_addr
|
||||
|
||||
@staticmethod
|
||||
def add_favorite(request, poetry_data):
|
||||
"""添加古诗词收藏"""
|
||||
try:
|
||||
user_id = PoetryFavoriteService.get_user_id(request)
|
||||
|
||||
# 检查是否已存在相同的收藏
|
||||
existing = PoetryFavorite.query.filter_by(
|
||||
user_id=user_id,
|
||||
poetry_title=poetry_data['poetry_title'],
|
||||
author=poetry_data['author'],
|
||||
analysis_result=poetry_data['analysis_result']
|
||||
).first()
|
||||
|
||||
if existing:
|
||||
return {'success': False, 'message': '该古诗词解析已收藏'}
|
||||
|
||||
# 处理标签
|
||||
tags = poetry_data.get('tags')
|
||||
if tags and isinstance(tags, list):
|
||||
tags = json.dumps(tags, ensure_ascii=False)
|
||||
|
||||
favorite = PoetryFavorite(
|
||||
user_id=user_id,
|
||||
poetry_title=poetry_data['poetry_title'],
|
||||
author=poetry_data['author'],
|
||||
dynasty=poetry_data.get('dynasty'),
|
||||
translation_style=poetry_data.get('translation_style'),
|
||||
interpretation_depth=poetry_data.get('interpretation_depth'),
|
||||
purpose=poetry_data.get('purpose'),
|
||||
target_audience=poetry_data.get('target_audience'),
|
||||
translation_quality=poetry_data.get('translation_quality'),
|
||||
annotation_detail=poetry_data.get('annotation_detail'),
|
||||
interpretation_level=poetry_data.get('interpretation_level'),
|
||||
original_text=poetry_data.get('original_text'),
|
||||
analysis_result=poetry_data['analysis_result'],
|
||||
notes=poetry_data.get('notes'),
|
||||
tags=tags
|
||||
)
|
||||
|
||||
db.session.add(favorite)
|
||||
db.session.commit()
|
||||
|
||||
return {'success': True, 'message': '收藏成功', 'id': favorite.id}
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return {'success': False, 'message': f'收藏失败: {str(e)}'}
|
||||
|
||||
@staticmethod
|
||||
def get_favorites(request, page=1, per_page=10, search=None, dynasty=None, author=None):
|
||||
"""获取古诗词收藏列表"""
|
||||
try:
|
||||
user_id = PoetryFavoriteService.get_user_id(request)
|
||||
query = PoetryFavorite.query.filter_by(user_id=user_id)
|
||||
|
||||
# 搜索功能
|
||||
if search:
|
||||
query = query.filter(
|
||||
db.or_(
|
||||
PoetryFavorite.poetry_title.contains(search),
|
||||
PoetryFavorite.author.contains(search),
|
||||
PoetryFavorite.analysis_result.contains(search),
|
||||
PoetryFavorite.notes.contains(search)
|
||||
)
|
||||
)
|
||||
|
||||
# 朝代筛选
|
||||
if dynasty and dynasty != 'all':
|
||||
query = query.filter_by(dynasty=dynasty)
|
||||
|
||||
# 作者筛选
|
||||
if author and author != 'all':
|
||||
query = query.filter_by(author=author)
|
||||
|
||||
# 按时间倒序排列
|
||||
query = query.order_by(PoetryFavorite.created_time.desc())
|
||||
|
||||
# 分页
|
||||
pagination = query.paginate(
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
error_out=False
|
||||
)
|
||||
|
||||
favorites = [favorite.to_summary_dict() for favorite in pagination.items]
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'data': favorites,
|
||||
'total': pagination.total,
|
||||
'pages': pagination.pages,
|
||||
'current_page': page,
|
||||
'has_prev': pagination.has_prev,
|
||||
'has_next': pagination.has_next
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
return {'success': False, 'message': f'获取收藏失败: {str(e)}'}
|
||||
|
||||
@staticmethod
|
||||
def get_favorite_by_id(request, favorite_id):
|
||||
"""根据ID获取古诗词收藏详情"""
|
||||
try:
|
||||
user_id = PoetryFavoriteService.get_user_id(request)
|
||||
favorite = PoetryFavorite.query.filter_by(
|
||||
id=favorite_id,
|
||||
user_id=user_id
|
||||
).first()
|
||||
|
||||
if not favorite:
|
||||
return {'success': False, 'message': '收藏不存在'}
|
||||
|
||||
return {'success': True, 'data': favorite.to_dict()}
|
||||
|
||||
except Exception as e:
|
||||
return {'success': False, 'message': f'获取收藏详情失败: {str(e)}'}
|
||||
|
||||
@staticmethod
|
||||
def update_favorite(request, favorite_id, notes=None, tags=None):
|
||||
"""更新古诗词收藏"""
|
||||
try:
|
||||
user_id = PoetryFavoriteService.get_user_id(request)
|
||||
favorite = PoetryFavorite.query.filter_by(
|
||||
id=favorite_id,
|
||||
user_id=user_id
|
||||
).first()
|
||||
|
||||
if not favorite:
|
||||
return {'success': False, 'message': '收藏不存在'}
|
||||
|
||||
if notes is not None:
|
||||
favorite.notes = notes
|
||||
|
||||
if tags is not None:
|
||||
if isinstance(tags, list):
|
||||
tags = json.dumps(tags, ensure_ascii=False)
|
||||
favorite.tags = tags
|
||||
|
||||
favorite.updated_time = datetime.now()
|
||||
db.session.commit()
|
||||
|
||||
return {'success': True, 'message': '更新成功'}
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return {'success': False, 'message': f'更新失败: {str(e)}'}
|
||||
|
||||
@staticmethod
|
||||
def delete_favorite(request, favorite_id):
|
||||
"""删除古诗词收藏"""
|
||||
try:
|
||||
user_id = PoetryFavoriteService.get_user_id(request)
|
||||
favorite = PoetryFavorite.query.filter_by(
|
||||
id=favorite_id,
|
||||
user_id=user_id
|
||||
).first()
|
||||
|
||||
if not favorite:
|
||||
return {'success': False, 'message': '收藏不存在'}
|
||||
|
||||
db.session.delete(favorite)
|
||||
db.session.commit()
|
||||
|
||||
return {'success': True, 'message': '删除成功'}
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return {'success': False, 'message': f'删除失败: {str(e)}'}
|
||||
|
||||
@staticmethod
|
||||
def get_favorite_stats(request):
|
||||
"""获取古诗词收藏统计信息"""
|
||||
try:
|
||||
user_id = PoetryFavoriteService.get_user_id(request)
|
||||
|
||||
# 总收藏数
|
||||
total_count = PoetryFavorite.query.filter_by(user_id=user_id).count()
|
||||
|
||||
# 朝代统计
|
||||
dynasty_stats = db.session.query(
|
||||
PoetryFavorite.dynasty,
|
||||
db.func.count(PoetryFavorite.id)
|
||||
).filter_by(user_id=user_id).group_by(PoetryFavorite.dynasty).all()
|
||||
|
||||
# 作者统计
|
||||
author_stats = db.session.query(
|
||||
PoetryFavorite.author,
|
||||
db.func.count(PoetryFavorite.id)
|
||||
).filter_by(user_id=user_id).group_by(PoetryFavorite.author).all()
|
||||
|
||||
# 最近收藏
|
||||
recent_favorites = PoetryFavorite.query.filter_by(user_id=user_id)\
|
||||
.order_by(PoetryFavorite.created_time.desc())\
|
||||
.limit(5).all()
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'data': {
|
||||
'total_count': total_count,
|
||||
'dynasty_stats': dict(dynasty_stats),
|
||||
'author_stats': dict(author_stats),
|
||||
'recent_favorites': [f.to_summary_dict() for f in recent_favorites]
|
||||
}
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
return {'success': False, 'message': f'获取统计信息失败: {str(e)}'}
|
||||
|
||||
@staticmethod
|
||||
def check_favorite_status(request, poetry_title, author, analysis_result):
|
||||
"""检查古诗词是否已收藏"""
|
||||
try:
|
||||
user_id = PoetryFavoriteService.get_user_id(request)
|
||||
favorite = PoetryFavorite.query.filter_by(
|
||||
user_id=user_id,
|
||||
poetry_title=poetry_title,
|
||||
author=author,
|
||||
analysis_result=analysis_result
|
||||
).first()
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'is_favorited': favorite is not None,
|
||||
'favorite_id': favorite.id if favorite else None
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
return {'success': False, 'message': f'检查收藏状态失败: {str(e)}'}
|
||||
@@ -32,6 +32,68 @@ nav a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 功能卡片样式 */
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 30px;
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
.feature {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid #e1e5e9;
|
||||
}
|
||||
|
||||
.feature:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.feature h2 {
|
||||
color: #2c3e50;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.feature h2 i {
|
||||
color: #3498db;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.feature p {
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.feature-link {
|
||||
display: inline-block;
|
||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
||||
color: white;
|
||||
padding: 12px 24px;
|
||||
border-radius: 25px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-link:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 25px rgba(52, 152, 219, 0.3);
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
.form-group {
|
||||
margin-bottom: 1rem;
|
||||
|
||||
@@ -258,6 +258,14 @@
|
||||
<i class="fas fa-utensils"></i>
|
||||
饭菜规划
|
||||
</a>
|
||||
<a href="{{ url_for('poetry.poetry_page') }}" class="nav-link">
|
||||
<i class="fas fa-scroll"></i>
|
||||
古诗词解析
|
||||
</a>
|
||||
<a href="{{ url_for('poetry.poetry_favorites') }}" class="nav-link">
|
||||
<i class="fas fa-heart"></i>
|
||||
古诗词收藏
|
||||
</a>
|
||||
<a href="{{ url_for('meal_planning.meal_planning_history') }}" class="nav-link">
|
||||
<i class="fas fa-history"></i>
|
||||
我的规划
|
||||
|
||||
@@ -11,16 +11,19 @@
|
||||
|
||||
<section class="features">
|
||||
<div class="feature">
|
||||
<h2>智能生成</h2>
|
||||
<h2><i class="fas fa-magic"></i> 智能生成</h2>
|
||||
<p>基于先进的大模型技术,快速生成精准提示词</p>
|
||||
<a href="{{ url_for('main.generate_prompt') }}" class="feature-link">开始生成</a>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h2>用户友好</h2>
|
||||
<p>简洁直观的界面设计,轻松上手</p>
|
||||
<h2><i class="fas fa-utensils"></i> 饭菜规划</h2>
|
||||
<p>AI智能规划每日饭菜,营养搭配更科学</p>
|
||||
<a href="{{ url_for('meal_planning.meal_planning_page') }}" class="feature-link">开始规划</a>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h2>持续优化</h2>
|
||||
<p>通过用户反馈不断改进提示词质量</p>
|
||||
<h2><i class="fas fa-scroll"></i> 古诗词解析</h2>
|
||||
<p>探索中华古典诗词之美,AI智能解析助您深入理解</p>
|
||||
<a href="{{ url_for('poetry.poetry_page') }}" class="feature-link">开始解析</a>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
243
src/flask_prompt_master/templates/poetry/poetry_examples.html
Normal file
243
src/flask_prompt_master/templates/poetry/poetry_examples.html
Normal file
@@ -0,0 +1,243 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}古诗词示例{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
.examples-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.examples-header {
|
||||
text-align: center;
|
||||
color: white;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.examples-header h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.examples-header p {
|
||||
font-size: 1.2rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.examples-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 30px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.example-card {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
box-shadow: 0 15px 35px rgba(0,0,0,0.1);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.example-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
.example-card:hover {
|
||||
transform: translateY(-10px);
|
||||
box-shadow: 0 25px 50px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.example-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.example-title i {
|
||||
color: #667eea;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.example-author {
|
||||
font-size: 1.1rem;
|
||||
color: #666;
|
||||
margin-bottom: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.example-dynasty {
|
||||
display: inline-block;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 4px 12px;
|
||||
border-radius: 15px;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.example-description {
|
||||
color: #555;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.analyze-btn {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 24px;
|
||||
border-radius: 25px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.analyze-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.back-link {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.back-link a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 1.1rem;
|
||||
padding: 12px 24px;
|
||||
border: 2px solid white;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.back-link a:hover {
|
||||
background: white;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.examples-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.examples-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.example-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.examples-header h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="examples-container">
|
||||
<div class="examples-header">
|
||||
<h1><i class="fas fa-book-open"></i> 古诗词示例</h1>
|
||||
<p>点击下方示例,快速体验古诗词解析功能</p>
|
||||
</div>
|
||||
|
||||
<div class="examples-grid">
|
||||
{% for example in examples %}
|
||||
<div class="example-card" onclick="analyzeExample('{{ example.title }}', '{{ example.author }}', '{{ example.dynasty }}')">
|
||||
<div class="example-title">
|
||||
<i class="fas fa-scroll"></i>
|
||||
{{ example.title }}
|
||||
</div>
|
||||
<div class="example-author">{{ example.author }}</div>
|
||||
<div class="example-dynasty">{{ example.dynasty }}代</div>
|
||||
<div class="example-description">{{ example.description }}</div>
|
||||
<button class="analyze-btn">
|
||||
<i class="fas fa-search"></i>
|
||||
立即解析
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="back-link">
|
||||
<a href="{{ url_for('poetry.poetry_page') }}">
|
||||
<i class="fas fa-arrow-left"></i> 返回古诗词解析
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
function analyzeExample(title, author, dynasty) {
|
||||
// 跳转到古诗词解析页面,并预填表单
|
||||
const params = new URLSearchParams({
|
||||
title: title,
|
||||
author: author,
|
||||
dynasty: dynasty
|
||||
});
|
||||
|
||||
window.location.href = `{{ url_for('poetry.poetry_page') }}?${params.toString()}`;
|
||||
}
|
||||
|
||||
// 页面加载时检查URL参数,自动填充表单
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const title = urlParams.get('title');
|
||||
const author = urlParams.get('author');
|
||||
const dynasty = urlParams.get('dynasty');
|
||||
|
||||
if (title && author) {
|
||||
// 如果是从示例页面跳转过来的,自动填充表单
|
||||
setTimeout(() => {
|
||||
const titleInput = document.getElementById('poetry_title');
|
||||
const authorInput = document.getElementById('author');
|
||||
const dynastySelect = document.getElementById('dynasty');
|
||||
|
||||
if (titleInput) titleInput.value = title;
|
||||
if (authorInput) authorInput.value = author;
|
||||
if (dynastySelect && dynasty) {
|
||||
dynastySelect.value = dynasty;
|
||||
}
|
||||
|
||||
// 自动提交表单
|
||||
const form = document.getElementById('poetryForm');
|
||||
if (form) {
|
||||
form.dispatchEvent(new Event('submit'));
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
565
src/flask_prompt_master/templates/poetry/poetry_favorites.html
Normal file
565
src/flask_prompt_master/templates/poetry/poetry_favorites.html
Normal file
@@ -0,0 +1,565 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}古诗词收藏{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
.favorites-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.favorites-header {
|
||||
text-align: center;
|
||||
color: white;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.favorites-header h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.favorites-header p {
|
||||
font-size: 1.2rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.favorites-content {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
padding: 40px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.search-filters {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
padding: 20px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.search-filters input,
|
||||
.search-filters select {
|
||||
padding: 12px 16px;
|
||||
border: 2px solid #e1e5e9;
|
||||
border-radius: 10px;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.search-filters input:focus,
|
||||
.search-filters select:focus {
|
||||
outline: none;
|
||||
border-color: #667eea;
|
||||
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
|
||||
}
|
||||
|
||||
.favorites-list {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.favorite-item {
|
||||
background: #f8f9fa;
|
||||
border: 2px solid #e1e5e9;
|
||||
border-radius: 15px;
|
||||
padding: 25px;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.favorite-item:hover {
|
||||
border-color: #667eea;
|
||||
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.favorite-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.favorite-title {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.favorite-author {
|
||||
color: #667eea;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.favorite-meta {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
background: #e9ecef;
|
||||
padding: 5px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 0.85rem;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.favorite-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.view-btn {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.view-btn:hover {
|
||||
background: #5a6fd8;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background: #dc3545;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.delete-btn:hover {
|
||||
background: #c82333;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.favorite-date {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
font-size: 0.8rem;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.empty-state i {
|
||||
font-size: 4rem;
|
||||
margin-bottom: 20px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.empty-state h3 {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.empty-state a {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
padding: 12px 24px;
|
||||
border-radius: 25px;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.empty-state a:hover {
|
||||
background: #5a6fd8;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.pagination button {
|
||||
padding: 8px 16px;
|
||||
border: 2px solid #e1e5e9;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.pagination button:hover:not(:disabled) {
|
||||
border-color: #667eea;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.pagination button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.pagination .current-page {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
border-color: #667eea;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #667eea;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.favorites-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.favorites-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.search-filters {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.favorite-header {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.favorite-date {
|
||||
position: static;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.favorite-actions {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="favorites-container">
|
||||
<div class="favorites-header">
|
||||
<h1><i class="fas fa-heart"></i> 古诗词收藏</h1>
|
||||
<p>管理您收藏的古诗词解析,随时查阅经典作品</p>
|
||||
</div>
|
||||
|
||||
<div class="favorites-content">
|
||||
<!-- 搜索和筛选 -->
|
||||
<div class="search-filters">
|
||||
<input type="text" id="searchInput" placeholder="搜索诗词标题、作者或内容...">
|
||||
<select id="dynastyFilter">
|
||||
<option value="">所有朝代</option>
|
||||
<option value="先秦">先秦</option>
|
||||
<option value="汉">汉</option>
|
||||
<option value="魏晋">魏晋</option>
|
||||
<option value="南北朝">南北朝</option>
|
||||
<option value="隋">隋</option>
|
||||
<option value="唐">唐</option>
|
||||
<option value="五代">五代</option>
|
||||
<option value="宋">宋</option>
|
||||
<option value="元">元</option>
|
||||
<option value="明">明</option>
|
||||
<option value="清">清</option>
|
||||
</select>
|
||||
<select id="authorFilter">
|
||||
<option value="">所有作者</option>
|
||||
</select>
|
||||
<button id="searchBtn" class="action-btn view-btn">
|
||||
<i class="fas fa-search"></i> 搜索
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 收藏列表 -->
|
||||
<div id="favoritesList" class="favorites-list">
|
||||
<div class="loading">
|
||||
<div class="loading-spinner"></div>
|
||||
<p>正在加载收藏列表...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div id="pagination" class="pagination" style="display: none;">
|
||||
<button id="prevBtn" disabled>
|
||||
<i class="fas fa-chevron-left"></i> 上一页
|
||||
</button>
|
||||
<span id="pageInfo">第 1 页,共 1 页</span>
|
||||
<button id="nextBtn" disabled>
|
||||
下一页 <i class="fas fa-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 详情模态框 -->
|
||||
<div id="detailModal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 10000;">
|
||||
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 15px; padding: 30px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 20px 40px rgba(0,0,0,0.3);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid #f0f0f0;">
|
||||
<h2 id="modalTitle" style="margin: 0; color: #333;"></h2>
|
||||
<button onclick="closeModal()" style="background: #dc3545; color: white; border: none; padding: 8px 12px; border-radius: 50%; cursor: pointer; font-size: 1.2rem;">×</button>
|
||||
</div>
|
||||
<div id="modalContent" style="line-height: 1.8; color: #444;"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const favoritesList = document.getElementById('favoritesList');
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
const dynastyFilter = document.getElementById('dynastyFilter');
|
||||
const authorFilter = document.getElementById('authorFilter');
|
||||
const searchBtn = document.getElementById('searchBtn');
|
||||
const pagination = document.getElementById('pagination');
|
||||
const prevBtn = document.getElementById('prevBtn');
|
||||
const nextBtn = document.getElementById('nextBtn');
|
||||
const pageInfo = document.getElementById('pageInfo');
|
||||
|
||||
let currentPage = 1;
|
||||
let totalPages = 1;
|
||||
let currentFilters = {
|
||||
search: '',
|
||||
dynasty: '',
|
||||
author: ''
|
||||
};
|
||||
|
||||
// 加载收藏列表
|
||||
async function loadFavorites(page = 1) {
|
||||
try {
|
||||
favoritesList.innerHTML = `
|
||||
<div class="loading">
|
||||
<div class="loading-spinner"></div>
|
||||
<p>正在加载收藏列表...</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const params = new URLSearchParams({
|
||||
page: page,
|
||||
per_page: 10,
|
||||
...currentFilters
|
||||
});
|
||||
|
||||
const response = await fetch(`{{ url_for('poetry.get_poetry_favorites') }}?${params}`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
displayFavorites(result.data);
|
||||
updatePagination(result);
|
||||
} else {
|
||||
favoritesList.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<h3>加载失败</h3>
|
||||
<p>${result.message}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载收藏列表失败:', error);
|
||||
favoritesList.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<h3>网络错误</h3>
|
||||
<p>请检查网络连接后重试</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
// 显示收藏列表
|
||||
function displayFavorites(favorites) {
|
||||
if (favorites.length === 0) {
|
||||
favoritesList.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-heart"></i>
|
||||
<h3>暂无收藏</h3>
|
||||
<p>您还没有收藏任何古诗词解析</p>
|
||||
<a href="{{ url_for('poetry.poetry_page') }}">
|
||||
<i class="fas fa-plus"></i> 开始收藏
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
pagination.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
favoritesList.innerHTML = favorites.map(favorite => `
|
||||
<div class="favorite-item">
|
||||
<div class="favorite-date">${favorite.created_time}</div>
|
||||
<div class="favorite-header">
|
||||
<div>
|
||||
<div class="favorite-title">${favorite.poetry_title}</div>
|
||||
<div class="favorite-author">${favorite.author} ${favorite.dynasty ? `· ${favorite.dynasty}` : ''}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="favorite-meta">
|
||||
<span class="meta-item">${favorite.purpose || '学习欣赏'}</span>
|
||||
<span class="meta-item">${favorite.target_audience || '一般读者'}</span>
|
||||
</div>
|
||||
${favorite.notes ? `<div style="margin: 10px 0; padding: 10px; background: #e9ecef; border-radius: 8px; font-style: italic;">${favorite.notes}</div>` : ''}
|
||||
<div class="favorite-actions">
|
||||
<button class="action-btn view-btn" onclick="viewFavorite(${favorite.id})">
|
||||
<i class="fas fa-eye"></i> 查看详情
|
||||
</button>
|
||||
<button class="action-btn delete-btn" onclick="deleteFavorite(${favorite.id})">
|
||||
<i class="fas fa-trash"></i> 删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
pagination.style.display = 'flex';
|
||||
}
|
||||
|
||||
// 更新分页
|
||||
function updatePagination(result) {
|
||||
currentPage = result.current_page;
|
||||
totalPages = result.pages;
|
||||
|
||||
pageInfo.textContent = `第 ${currentPage} 页,共 ${totalPages} 页`;
|
||||
prevBtn.disabled = !result.has_prev;
|
||||
nextBtn.disabled = !result.has_next;
|
||||
}
|
||||
|
||||
// 搜索功能
|
||||
searchBtn.addEventListener('click', function() {
|
||||
currentFilters = {
|
||||
search: searchInput.value.trim(),
|
||||
dynasty: dynastyFilter.value,
|
||||
author: authorFilter.value
|
||||
};
|
||||
currentPage = 1;
|
||||
loadFavorites(1);
|
||||
});
|
||||
|
||||
// 回车搜索
|
||||
searchInput.addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
searchBtn.click();
|
||||
}
|
||||
});
|
||||
|
||||
// 分页按钮
|
||||
prevBtn.addEventListener('click', function() {
|
||||
if (currentPage > 1) {
|
||||
loadFavorites(currentPage - 1);
|
||||
}
|
||||
});
|
||||
|
||||
nextBtn.addEventListener('click', function() {
|
||||
if (currentPage < totalPages) {
|
||||
loadFavorites(currentPage + 1);
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化加载
|
||||
loadFavorites();
|
||||
});
|
||||
|
||||
// 查看收藏详情
|
||||
async function viewFavorite(favoriteId) {
|
||||
try {
|
||||
const response = await fetch(`{{ url_for('poetry.get_poetry_favorite_detail', favorite_id=0) }}`.replace('0', favoriteId));
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
const favorite = result.data;
|
||||
document.getElementById('modalTitle').textContent = `${favorite.poetry_title} - ${favorite.author}`;
|
||||
document.getElementById('modalContent').innerHTML = favorite.analysis_result;
|
||||
document.getElementById('detailModal').style.display = 'block';
|
||||
} else {
|
||||
alert(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查看详情失败:', error);
|
||||
alert('查看详情失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
|
||||
// 删除收藏
|
||||
async function deleteFavorite(favoriteId) {
|
||||
if (!confirm('确定要删除这个收藏吗?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`{{ url_for('poetry.delete_poetry_favorite', favorite_id=0) }}`.replace('0', favoriteId), {
|
||||
method: 'DELETE'
|
||||
});
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
alert('删除成功');
|
||||
// 重新加载当前页
|
||||
loadFavorites(currentPage);
|
||||
} else {
|
||||
alert(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error);
|
||||
alert('删除失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭模态框
|
||||
function closeModal() {
|
||||
document.getElementById('detailModal').style.display = 'none';
|
||||
}
|
||||
|
||||
// 点击模态框背景关闭
|
||||
document.getElementById('detailModal').addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
948
src/flask_prompt_master/templates/poetry/poetry_page.html
Normal file
948
src/flask_prompt_master/templates/poetry/poetry_page.html
Normal file
@@ -0,0 +1,948 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}古诗词查询与解析{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
.poetry-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.poetry-header {
|
||||
text-align: center;
|
||||
color: white;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.poetry-header h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.poetry-header p {
|
||||
font-size: 1.2rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.poetry-form-container {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
padding: 40px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
color: #333;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group select,
|
||||
.form-group textarea {
|
||||
padding: 12px 16px;
|
||||
border: 2px solid #e1e5e9;
|
||||
border-radius: 10px;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.form-group input:focus,
|
||||
.form-group select:focus,
|
||||
.form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: #667eea;
|
||||
background: white;
|
||||
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
|
||||
}
|
||||
|
||||
.form-group.full-width {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 15px 40px;
|
||||
border-radius: 50px;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.submit-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.submit-btn:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.result-container {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
padding: 40px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
margin-top: 30px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.result-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 2px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.result-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
background: #218838;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.markdown-btn {
|
||||
background: #6c757d;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.markdown-btn:hover {
|
||||
background: #5a6268;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.favorite-btn {
|
||||
background: #dc3545;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.favorite-btn:hover {
|
||||
background: #c82333;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.favorite-btn.favorited {
|
||||
background: #28a745;
|
||||
}
|
||||
|
||||
.favorite-btn.favorited:hover {
|
||||
background: #218838;
|
||||
}
|
||||
|
||||
.markdown-source {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.result-content {
|
||||
line-height: 1.8;
|
||||
color: #444;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.result-content h1,
|
||||
.result-content h2,
|
||||
.result-content h3 {
|
||||
color: #333;
|
||||
margin-top: 25px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.result-content h1 {
|
||||
font-size: 1.8rem;
|
||||
border-bottom: 2px solid #667eea;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.result-content h2 {
|
||||
font-size: 1.4rem;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.result-content h3 {
|
||||
font-size: 1.2rem;
|
||||
color: #764ba2;
|
||||
}
|
||||
|
||||
.result-content p {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.result-content ul,
|
||||
.result-content ol {
|
||||
margin-bottom: 15px;
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.result-content li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #667eea;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.error-message {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #f5c6cb;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #c3e6cb;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.examples-link {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.examples-link a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 1.1rem;
|
||||
padding: 10px 20px;
|
||||
border: 2px solid white;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.examples-link a:hover {
|
||||
background: white;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.poetry-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.poetry-form-container,
|
||||
.result-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.poetry-header h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.result-header {
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="poetry-container">
|
||||
<div class="poetry-header">
|
||||
<h1><i class="fas fa-scroll"></i> 古诗词查询与解析</h1>
|
||||
<p>探索中华古典诗词之美,AI智能解析助您深入理解</p>
|
||||
</div>
|
||||
|
||||
<div class="poetry-form-container">
|
||||
<form id="poetryForm">
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label for="poetry_title">诗词标题 *</label>
|
||||
<input type="text" id="poetry_title" name="poetry_title"
|
||||
placeholder="如:静夜思、春晓、水调歌头等" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="author">作者姓名 *</label>
|
||||
<input type="text" id="author" name="author"
|
||||
placeholder="如:李白、杜甫、苏轼等" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="dynasty">朝代</label>
|
||||
<select id="dynasty" name="dynasty">
|
||||
<option value="">请选择朝代</option>
|
||||
<option value="先秦">先秦</option>
|
||||
<option value="汉">汉</option>
|
||||
<option value="魏晋">魏晋</option>
|
||||
<option value="南北朝">南北朝</option>
|
||||
<option value="隋">隋</option>
|
||||
<option value="唐">唐</option>
|
||||
<option value="五代">五代</option>
|
||||
<option value="宋">宋</option>
|
||||
<option value="元">元</option>
|
||||
<option value="明">明</option>
|
||||
<option value="清">清</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="translation_style">翻译风格</label>
|
||||
<select id="translation_style" name="translation_style">
|
||||
<option value="优美流畅">优美流畅</option>
|
||||
<option value="忠实原文">忠实原文</option>
|
||||
<option value="现代口语">现代口语</option>
|
||||
<option value="诗意盎然">诗意盎然</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="interpretation_depth">解读深度</label>
|
||||
<select id="interpretation_depth" name="interpretation_depth">
|
||||
<option value="深入浅出">深入浅出</option>
|
||||
<option value="学术严谨">学术严谨</option>
|
||||
<option value="通俗易懂">通俗易懂</option>
|
||||
<option value="专业详细">专业详细</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="purpose">使用目的</label>
|
||||
<select id="purpose" name="purpose">
|
||||
<option value="学习欣赏">学习欣赏</option>
|
||||
<option value="教学研究">教学研究</option>
|
||||
<option value="文学创作">文学创作</option>
|
||||
<option value="文化传承">文化传承</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="target_audience">目标读者</label>
|
||||
<select id="target_audience" name="target_audience">
|
||||
<option value="一般读者">一般读者</option>
|
||||
<option value="学生群体">学生群体</option>
|
||||
<option value="文学爱好者">文学爱好者</option>
|
||||
<option value="专业研究者">专业研究者</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="translation_quality">译文质量</label>
|
||||
<select id="translation_quality" name="translation_quality">
|
||||
<option value="高质量">高质量</option>
|
||||
<option value="标准">标准</option>
|
||||
<option value="简洁明了">简洁明了</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="annotation_detail">注释详细程度</label>
|
||||
<select id="annotation_detail" name="annotation_detail">
|
||||
<option value="详细准确">详细准确</option>
|
||||
<option value="简明扼要">简明扼要</option>
|
||||
<option value="重点突出">重点突出</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="interpretation_level">解读层次</label>
|
||||
<select id="interpretation_level" name="interpretation_level">
|
||||
<option value="深入浅出">深入浅出</option>
|
||||
<option value="逐句解析">逐句解析</option>
|
||||
<option value="整体把握">整体把握</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="submit-btn">
|
||||
<i class="fas fa-search"></i> 开始解析
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="result-container" id="resultContainer">
|
||||
<div class="result-header">
|
||||
<h3 class="result-title" id="resultTitle">解析结果</h3>
|
||||
<div class="result-actions">
|
||||
<button class="copy-btn" id="copyBtn">
|
||||
<i class="fas fa-copy"></i> 复制结果
|
||||
</button>
|
||||
<button class="markdown-btn" id="markdownBtn">
|
||||
<i class="fab fa-markdown"></i> 查看源码
|
||||
</button>
|
||||
<button class="favorite-btn" id="favoriteBtn">
|
||||
<i class="far fa-heart"></i> 收藏
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="result-content" id="resultContent"></div>
|
||||
</div>
|
||||
|
||||
<div class="examples-link">
|
||||
<a href="{{ url_for('poetry.poetry_examples') }}">
|
||||
<i class="fas fa-book"></i> 查看古诗词示例
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const form = document.getElementById('poetryForm');
|
||||
const resultContainer = document.getElementById('resultContainer');
|
||||
const resultContent = document.getElementById('resultContent');
|
||||
const resultTitle = document.getElementById('resultTitle');
|
||||
const copyBtn = document.getElementById('copyBtn');
|
||||
const markdownBtn = document.getElementById('markdownBtn');
|
||||
const favoriteBtn = document.getElementById('favoriteBtn');
|
||||
const submitBtn = form.querySelector('.submit-btn');
|
||||
|
||||
// 存储当前解析结果的数据
|
||||
let currentPoetryData = null;
|
||||
|
||||
form.addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// 显示加载状态
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 解析中...';
|
||||
|
||||
// 显示结果容器
|
||||
resultContainer.style.display = 'block';
|
||||
resultContent.innerHTML = `
|
||||
<div class="loading">
|
||||
<div class="loading-spinner"></div>
|
||||
<p>AI正在解析古诗词,请稍候...</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// 滚动到结果区域
|
||||
resultContainer.scrollIntoView({ behavior: 'smooth' });
|
||||
|
||||
try {
|
||||
const formData = new FormData(form);
|
||||
const data = Object.fromEntries(formData.entries());
|
||||
|
||||
const response = await fetch('{{ url_for("poetry.analyze_poetry") }}', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
resultTitle.textContent = `${result.poetry_info.title} - ${result.poetry_info.author}`;
|
||||
resultContent.innerHTML = result.result;
|
||||
|
||||
// 保存当前解析数据
|
||||
currentPoetryData = {
|
||||
poetry_title: result.poetry_info.title,
|
||||
author: result.poetry_info.author,
|
||||
dynasty: result.poetry_info.dynasty,
|
||||
analysis_result: result.result,
|
||||
// 从表单获取其他参数
|
||||
translation_style: formData.get('translation_style'),
|
||||
interpretation_depth: formData.get('interpretation_depth'),
|
||||
purpose: formData.get('purpose'),
|
||||
target_audience: formData.get('target_audience'),
|
||||
translation_quality: formData.get('translation_quality'),
|
||||
annotation_detail: formData.get('annotation_detail'),
|
||||
interpretation_level: formData.get('interpretation_level')
|
||||
};
|
||||
|
||||
// 检查收藏状态
|
||||
checkFavoriteStatus();
|
||||
|
||||
// 显示成功消息
|
||||
showMessage('解析完成!', 'success');
|
||||
} else {
|
||||
resultContent.innerHTML = `<div class="error-message">${result.message}</div>`;
|
||||
showMessage(result.message, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
resultContent.innerHTML = '<div class="error-message">网络错误,请稍后重试</div>';
|
||||
showMessage('网络错误,请稍后重试', 'error');
|
||||
} finally {
|
||||
// 恢复按钮状态
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = '<i class="fas fa-search"></i> 开始解析';
|
||||
}
|
||||
});
|
||||
|
||||
// 复制功能 - 支持Markdown格式
|
||||
copyBtn.addEventListener('click', function() {
|
||||
console.log('复制按钮被点击');
|
||||
|
||||
// 检查是否有内容可复制
|
||||
if (!resultContent || resultContent.innerHTML.trim() === '') {
|
||||
showMessage('没有内容可复制,请先生成解析结果', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取Markdown格式的文本内容
|
||||
const markdownText = getMarkdownText(resultContent);
|
||||
console.log('生成的Markdown文本长度:', markdownText.length);
|
||||
console.log('Markdown文本预览:', markdownText.substring(0, 100) + '...');
|
||||
|
||||
if (!markdownText || markdownText.trim() === '') {
|
||||
showMessage('没有可复制的内容', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查浏览器是否支持现代剪贴板API
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
console.log('使用现代剪贴板API');
|
||||
navigator.clipboard.writeText(markdownText).then(function() {
|
||||
console.log('复制成功');
|
||||
copyBtn.innerHTML = '<i class="fas fa-check"></i> 已复制';
|
||||
copyBtn.style.background = '#28a745';
|
||||
setTimeout(() => {
|
||||
copyBtn.innerHTML = '<i class="fas fa-copy"></i> 复制结果';
|
||||
copyBtn.style.background = '#28a745';
|
||||
}, 2000);
|
||||
showMessage('Markdown格式内容已复制到剪贴板!', 'success');
|
||||
}).catch(function(err) {
|
||||
console.error('现代剪贴板API复制失败:', err);
|
||||
// 降级方案:使用传统方法
|
||||
fallbackCopy(markdownText);
|
||||
});
|
||||
} else {
|
||||
console.log('浏览器不支持现代剪贴板API,使用降级方案');
|
||||
fallbackCopy(markdownText);
|
||||
}
|
||||
});
|
||||
|
||||
// 降级复制方案
|
||||
function fallbackCopy(text) {
|
||||
try {
|
||||
// 创建临时文本区域
|
||||
const textArea = document.createElement('textarea');
|
||||
textArea.value = text;
|
||||
textArea.style.position = 'fixed';
|
||||
textArea.style.left = '-999999px';
|
||||
textArea.style.top = '-999999px';
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
const successful = document.execCommand('copy');
|
||||
document.body.removeChild(textArea);
|
||||
|
||||
if (successful) {
|
||||
console.log('降级复制成功');
|
||||
copyBtn.innerHTML = '<i class="fas fa-check"></i> 已复制';
|
||||
copyBtn.style.background = '#28a745';
|
||||
setTimeout(() => {
|
||||
copyBtn.innerHTML = '<i class="fas fa-copy"></i> 复制结果';
|
||||
copyBtn.style.background = '#28a745';
|
||||
}, 2000);
|
||||
showMessage('内容已复制到剪贴板!', 'success');
|
||||
} else {
|
||||
throw new Error('execCommand复制失败');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('降级复制也失败:', err);
|
||||
// 最后的降级方案:显示文本让用户手动复制
|
||||
showCopyDialog(text);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示复制对话框
|
||||
function showCopyDialog(text) {
|
||||
const dialog = document.createElement('div');
|
||||
dialog.style.cssText = `
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
border: 2px solid #667eea;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||
z-index: 10000;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
overflow: auto;
|
||||
`;
|
||||
|
||||
dialog.innerHTML = `
|
||||
<h3 style="margin-top: 0; color: #333;">请手动复制以下内容:</h3>
|
||||
<textarea readonly style="width: 100%; height: 300px; font-family: monospace; font-size: 12px; border: 1px solid #ccc; padding: 10px; border-radius: 5px;">${text}</textarea>
|
||||
<div style="text-align: center; margin-top: 15px;">
|
||||
<button onclick="this.parentElement.parentElement.remove()" style="background: #667eea; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer;">关闭</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(dialog);
|
||||
|
||||
// 自动选中文本
|
||||
const textarea = dialog.querySelector('textarea');
|
||||
textarea.focus();
|
||||
textarea.select();
|
||||
|
||||
showMessage('请手动复制上方文本框中的内容', 'error');
|
||||
}
|
||||
|
||||
// 收藏功能
|
||||
favoriteBtn.addEventListener('click', async function() {
|
||||
if (!currentPoetryData) {
|
||||
showMessage('请先生成古诗词解析', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (favoriteBtn.classList.contains('favorited')) {
|
||||
// 已收藏,执行取消收藏操作
|
||||
await removeFavorite();
|
||||
} else {
|
||||
// 未收藏,执行添加收藏操作
|
||||
await addFavorite();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('收藏操作失败:', error);
|
||||
showMessage('收藏操作失败,请稍后重试', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
// 添加收藏
|
||||
async function addFavorite() {
|
||||
try {
|
||||
const response = await fetch('{{ url_for("poetry.add_poetry_favorite") }}', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(currentPoetryData)
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
favoriteBtn.classList.add('favorited');
|
||||
favoriteBtn.innerHTML = '<i class="fas fa-heart"></i> 已收藏';
|
||||
showMessage('收藏成功!', 'success');
|
||||
} else {
|
||||
showMessage(result.message, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加收藏失败:', error);
|
||||
showMessage('添加收藏失败,请稍后重试', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 取消收藏
|
||||
async function removeFavorite() {
|
||||
try {
|
||||
// 这里需要先获取收藏ID,然后删除
|
||||
const response = await fetch('{{ url_for("poetry.check_poetry_favorite_status") }}', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
poetry_title: currentPoetryData.poetry_title,
|
||||
author: currentPoetryData.author,
|
||||
analysis_result: currentPoetryData.analysis_result
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success && result.favorite_id) {
|
||||
// 删除收藏
|
||||
const deleteResponse = await fetch(`{{ url_for("poetry.delete_poetry_favorite", favorite_id=0) }}`.replace('0', result.favorite_id), {
|
||||
method: 'DELETE'
|
||||
});
|
||||
|
||||
const deleteResult = await deleteResponse.json();
|
||||
|
||||
if (deleteResult.success) {
|
||||
favoriteBtn.classList.remove('favorited');
|
||||
favoriteBtn.innerHTML = '<i class="far fa-heart"></i> 收藏';
|
||||
showMessage('已取消收藏', 'success');
|
||||
} else {
|
||||
showMessage(deleteResult.message, 'error');
|
||||
}
|
||||
} else {
|
||||
showMessage('未找到收藏记录', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('取消收藏失败:', error);
|
||||
showMessage('取消收藏失败,请稍后重试', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 检查收藏状态
|
||||
async function checkFavoriteStatus() {
|
||||
if (!currentPoetryData) return;
|
||||
|
||||
try {
|
||||
const response = await fetch('{{ url_for("poetry.check_poetry_favorite_status") }}', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
poetry_title: currentPoetryData.poetry_title,
|
||||
author: currentPoetryData.author,
|
||||
analysis_result: currentPoetryData.analysis_result
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
if (result.is_favorited) {
|
||||
favoriteBtn.classList.add('favorited');
|
||||
favoriteBtn.innerHTML = '<i class="fas fa-heart"></i> 已收藏';
|
||||
} else {
|
||||
favoriteBtn.classList.remove('favorited');
|
||||
favoriteBtn.innerHTML = '<i class="far fa-heart"></i> 收藏';
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('检查收藏状态失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 将HTML内容转换为Markdown格式
|
||||
function getMarkdownText(element) {
|
||||
if (!element) return '';
|
||||
|
||||
let markdown = '';
|
||||
|
||||
// 遍历所有子节点
|
||||
for (let node of element.childNodes) {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
const text = node.textContent;
|
||||
if (text.trim()) {
|
||||
markdown += text;
|
||||
}
|
||||
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
const tagName = node.tagName.toLowerCase();
|
||||
const innerText = getMarkdownText(node);
|
||||
|
||||
switch (tagName) {
|
||||
case 'h1':
|
||||
markdown += `# ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'h2':
|
||||
markdown += `## ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'h3':
|
||||
markdown += `### ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'h4':
|
||||
markdown += `#### ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'h5':
|
||||
markdown += `##### ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'h6':
|
||||
markdown += `###### ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'p':
|
||||
if (innerText.trim()) {
|
||||
markdown += `${innerText.trim()}\n\n`;
|
||||
}
|
||||
break;
|
||||
case 'strong':
|
||||
case 'b':
|
||||
markdown += `**${innerText.trim()}**`;
|
||||
break;
|
||||
case 'em':
|
||||
case 'i':
|
||||
markdown += `*${innerText.trim()}*`;
|
||||
break;
|
||||
case 'ul':
|
||||
if (innerText.trim()) {
|
||||
markdown += `${innerText.trim()}\n\n`;
|
||||
}
|
||||
break;
|
||||
case 'ol':
|
||||
if (innerText.trim()) {
|
||||
markdown += `${innerText.trim()}\n\n`;
|
||||
}
|
||||
break;
|
||||
case 'li':
|
||||
// 处理列表项,添加适当的缩进
|
||||
const lines = innerText.trim().split('\n');
|
||||
const firstLine = lines[0];
|
||||
const restLines = lines.slice(1);
|
||||
markdown += `- ${firstLine}`;
|
||||
if (restLines.length > 0) {
|
||||
markdown += '\n' + restLines.map(line => ` ${line}`).join('\n');
|
||||
}
|
||||
markdown += '\n';
|
||||
break;
|
||||
case 'code':
|
||||
markdown += `\`${innerText.trim()}\``;
|
||||
break;
|
||||
case 'pre':
|
||||
markdown += `\`\`\`\n${innerText.trim()}\n\`\`\`\n\n`;
|
||||
break;
|
||||
case 'blockquote':
|
||||
const quoteLines = innerText.trim().split('\n');
|
||||
markdown += quoteLines.map(line => `> ${line}`).join('\n') + '\n\n';
|
||||
break;
|
||||
case 'hr':
|
||||
markdown += '---\n\n';
|
||||
break;
|
||||
case 'br':
|
||||
markdown += '\n';
|
||||
break;
|
||||
case 'div':
|
||||
case 'span':
|
||||
// 对于div和span,直接添加内容
|
||||
markdown += innerText;
|
||||
break;
|
||||
default:
|
||||
// 对于其他标签,递归处理
|
||||
markdown += innerText;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return markdown;
|
||||
}
|
||||
|
||||
// Markdown源码查看功能
|
||||
markdownBtn.addEventListener('click', function() {
|
||||
const markdownText = getMarkdownText(resultContent);
|
||||
|
||||
// 检查是否已经显示源码
|
||||
let sourceDiv = resultContent.querySelector('.markdown-source');
|
||||
|
||||
if (sourceDiv) {
|
||||
// 如果已显示,则隐藏
|
||||
sourceDiv.remove();
|
||||
markdownBtn.innerHTML = '<i class="fab fa-markdown"></i> 查看源码';
|
||||
markdownBtn.style.background = '#6c757d';
|
||||
} else {
|
||||
// 如果未显示,则显示源码
|
||||
sourceDiv = document.createElement('div');
|
||||
sourceDiv.className = 'markdown-source';
|
||||
sourceDiv.textContent = markdownText;
|
||||
|
||||
resultContent.appendChild(sourceDiv);
|
||||
markdownBtn.innerHTML = '<i class="fas fa-eye-slash"></i> 隐藏源码';
|
||||
markdownBtn.style.background = '#dc3545';
|
||||
|
||||
// 滚动到源码区域
|
||||
sourceDiv.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
});
|
||||
|
||||
function showMessage(message, type) {
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = type === 'success' ? 'success-message' : 'error-message';
|
||||
messageDiv.textContent = message;
|
||||
|
||||
form.appendChild(messageDiv);
|
||||
|
||||
setTimeout(() => {
|
||||
messageDiv.remove();
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
159
test_copy_function.html
Normal file
159
test_copy_function.html
Normal file
@@ -0,0 +1,159 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>复制功能测试</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.test-content {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.copy-btn {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.copy-btn:hover {
|
||||
background: #218838;
|
||||
}
|
||||
.result {
|
||||
margin: 10px 0;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
.error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>复制功能测试页面</h1>
|
||||
|
||||
<div class="test-content">
|
||||
<h2>测试内容</h2>
|
||||
<p>这是一个测试复制功能的页面。</p>
|
||||
<p><strong>粗体文本</strong> 和 <em>斜体文本</em></p>
|
||||
<ul>
|
||||
<li>列表项 1</li>
|
||||
<li>列表项 2</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<button class="copy-btn" onclick="testCopy()">测试复制功能</button>
|
||||
|
||||
<div id="result"></div>
|
||||
|
||||
<script>
|
||||
function testCopy() {
|
||||
const testContent = document.querySelector('.test-content');
|
||||
const resultDiv = document.getElementById('result');
|
||||
|
||||
// 获取Markdown格式的文本
|
||||
const markdownText = getMarkdownText(testContent);
|
||||
|
||||
console.log('生成的Markdown文本:', markdownText);
|
||||
|
||||
// 尝试复制
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(markdownText).then(function() {
|
||||
resultDiv.innerHTML = '<div class="result success">✅ 复制成功!内容已复制到剪贴板。</div>';
|
||||
}).catch(function(err) {
|
||||
console.error('复制失败:', err);
|
||||
resultDiv.innerHTML = '<div class="result error">❌ 复制失败: ' + err.message + '</div>';
|
||||
});
|
||||
} else {
|
||||
resultDiv.innerHTML = '<div class="result error">❌ 浏览器不支持现代剪贴板API</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// 将HTML内容转换为Markdown格式
|
||||
function getMarkdownText(element) {
|
||||
if (!element) return '';
|
||||
|
||||
let markdown = '';
|
||||
|
||||
// 遍历所有子节点
|
||||
for (let node of element.childNodes) {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
const text = node.textContent;
|
||||
if (text.trim()) {
|
||||
markdown += text;
|
||||
}
|
||||
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
const tagName = node.tagName.toLowerCase();
|
||||
const innerText = getMarkdownText(node);
|
||||
|
||||
switch (tagName) {
|
||||
case 'h1':
|
||||
markdown += `# ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'h2':
|
||||
markdown += `## ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'h3':
|
||||
markdown += `### ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'h4':
|
||||
markdown += `#### ${innerText.trim()}\n\n`;
|
||||
break;
|
||||
case 'p':
|
||||
if (innerText.trim()) {
|
||||
markdown += `${innerText.trim()}\n\n`;
|
||||
}
|
||||
break;
|
||||
case 'strong':
|
||||
case 'b':
|
||||
markdown += `**${innerText.trim()}**`;
|
||||
break;
|
||||
case 'em':
|
||||
case 'i':
|
||||
markdown += `*${innerText.trim()}*`;
|
||||
break;
|
||||
case 'ul':
|
||||
if (innerText.trim()) {
|
||||
markdown += `${innerText.trim()}\n\n`;
|
||||
}
|
||||
break;
|
||||
case 'li':
|
||||
const lines = innerText.trim().split('\n');
|
||||
const firstLine = lines[0];
|
||||
const restLines = lines.slice(1);
|
||||
markdown += `- ${firstLine}`;
|
||||
if (restLines.length > 0) {
|
||||
markdown += '\n' + restLines.map(line => ` ${line}`).join('\n');
|
||||
}
|
||||
markdown += '\n';
|
||||
break;
|
||||
default:
|
||||
markdown += innerText;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return markdown;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
180
古诗词功能部署报告.md
Normal file
180
古诗词功能部署报告.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# 古诗词查询与解析功能部署完成报告
|
||||
|
||||
## 🎉 **部署状态:成功完成**
|
||||
|
||||
**部署时间**:2025年9月14日
|
||||
**功能名称**:古诗词查询与解析
|
||||
**服务状态**:✅ 已集成到主系统
|
||||
|
||||
---
|
||||
|
||||
## 📋 **功能概述**
|
||||
|
||||
古诗词查询与解析功能是一个基于AI的智能古诗词分析工具,能够:
|
||||
- 根据诗词标题和作者信息查询古诗词
|
||||
- 提供现代汉语译文
|
||||
- 生成详细的注释和解读
|
||||
- 支持多种翻译风格和解读深度
|
||||
- 适配不同目标读者群体
|
||||
|
||||
---
|
||||
|
||||
## ✅ **已实现功能**
|
||||
|
||||
### 1. **核心功能模块**
|
||||
- ✅ 古诗词查询与解析页面
|
||||
- ✅ AI智能解析服务
|
||||
- ✅ 古诗词示例展示
|
||||
- ✅ 多种解析参数配置
|
||||
|
||||
### 2. **用户界面**
|
||||
- ✅ 现代化渐变设计风格
|
||||
- ✅ 响应式布局适配各种设备
|
||||
- ✅ 直观的表单设计
|
||||
- ✅ 实时加载反馈
|
||||
|
||||
### 3. **功能特性**
|
||||
- ✅ 支持多种翻译风格(优美流畅、忠实原文、现代口语、诗意盎然)
|
||||
- ✅ 多种解读深度(深入浅出、学术严谨、通俗易懂、专业详细)
|
||||
- ✅ 多种使用目的(学习欣赏、教学研究、文学创作、文化传承)
|
||||
- ✅ 多种目标读者(一般读者、学生群体、文学爱好者、专业研究者)
|
||||
|
||||
### 4. **用户体验**
|
||||
- ✅ 一键复制解析结果
|
||||
- ✅ 古诗词示例快速体验
|
||||
- ✅ 友好的错误提示
|
||||
- ✅ 流畅的动画效果
|
||||
|
||||
---
|
||||
|
||||
## 🔧 **技术实现详情**
|
||||
|
||||
### 后端实现
|
||||
```python
|
||||
# 古诗词解析路由
|
||||
@poetry_bp.route('/analyze', methods=['POST'])
|
||||
def analyze_poetry():
|
||||
"""分析古诗词"""
|
||||
# AI解析逻辑
|
||||
result = generate_poetry_analysis(...)
|
||||
return jsonify({'success': True, 'result': result})
|
||||
```
|
||||
|
||||
### 前端实现
|
||||
- **现代化UI设计**:渐变背景 + 卡片式布局
|
||||
- **响应式设计**:适配桌面端和移动端
|
||||
- **交互优化**:实时反馈 + 加载动画
|
||||
- **功能完整**:表单验证 + 结果展示 + 复制功能
|
||||
|
||||
### AI服务集成
|
||||
- **API调用**:DeepSeek API
|
||||
- **提示词工程**:专业的古诗词解析提示词
|
||||
- **错误处理**:完善的异常处理机制
|
||||
- **超时控制**:30秒请求超时
|
||||
|
||||
---
|
||||
|
||||
## 🌐 **访问地址**
|
||||
|
||||
### 主要功能页面
|
||||
- **古诗词解析**:`http://101.43.95.130:5002/poetry/`
|
||||
- **古诗词示例**:`http://101.43.95.130:5002/poetry/examples`
|
||||
|
||||
### 导航入口
|
||||
- **主导航菜单**:古诗词解析
|
||||
- **主页功能卡片**:古诗词解析
|
||||
- **快速访问**:从示例页面直接跳转
|
||||
|
||||
---
|
||||
|
||||
## 📁 **文件结构**
|
||||
|
||||
```
|
||||
src/flask_prompt_master/
|
||||
├── routes/
|
||||
│ └── poetry.py # 古诗词路由模块
|
||||
├── templates/
|
||||
│ └── poetry/
|
||||
│ ├── poetry_page.html # 主解析页面
|
||||
│ └── poetry_examples.html # 示例展示页面
|
||||
└── __init__.py # 已注册poetry_bp蓝图
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **功能特色**
|
||||
|
||||
### 1. **智能解析**
|
||||
- 基于DeepSeek大模型的古诗词解析
|
||||
- 专业的古典文学专家角色设定
|
||||
- 多维度参数配置
|
||||
|
||||
### 2. **用户友好**
|
||||
- 直观的表单设计
|
||||
- 丰富的选项配置
|
||||
- 实时反馈和错误处理
|
||||
|
||||
### 3. **内容丰富**
|
||||
- 支持多种古诗词类型
|
||||
- 提供详细注释和解读
|
||||
- 适配不同用户需求
|
||||
|
||||
### 4. **技术先进**
|
||||
- 现代化前端设计
|
||||
- 响应式布局
|
||||
- 流畅的用户体验
|
||||
|
||||
---
|
||||
|
||||
## 🔗 **系统集成**
|
||||
|
||||
### 导航集成
|
||||
- ✅ 主导航菜单已添加"古诗词解析"入口
|
||||
- ✅ 主页功能卡片已添加古诗词解析
|
||||
- ✅ 统一的UI设计风格
|
||||
|
||||
### 路由注册
|
||||
- ✅ 已注册poetry_bp蓝图
|
||||
- ✅ URL前缀:`/poetry`
|
||||
- ✅ 完整的路由配置
|
||||
|
||||
### 样式统一
|
||||
- ✅ 与现有系统保持一致的视觉风格
|
||||
- ✅ 响应式设计适配
|
||||
- ✅ 现代化的交互效果
|
||||
|
||||
---
|
||||
|
||||
## 📊 **使用示例**
|
||||
|
||||
### 基本使用
|
||||
1. 访问古诗词解析页面
|
||||
2. 输入诗词标题(如:静夜思)
|
||||
3. 输入作者姓名(如:李白)
|
||||
4. 选择朝代(如:唐)
|
||||
5. 配置解析参数
|
||||
6. 点击"开始解析"
|
||||
|
||||
### 快速体验
|
||||
1. 访问古诗词示例页面
|
||||
2. 点击任意示例卡片
|
||||
3. 自动跳转并填充表单
|
||||
4. 自动开始解析
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **部署完成**
|
||||
|
||||
古诗词查询与解析功能已成功集成到提示词大师系统中,用户可以通过以下方式访问:
|
||||
|
||||
1. **主导航菜单** → 古诗词解析
|
||||
2. **主页功能卡片** → 古诗词解析
|
||||
3. **直接访问** → `/poetry/`
|
||||
|
||||
功能已完全就绪,可以立即使用!
|
||||
|
||||
---
|
||||
|
||||
*部署完成时间:2025年9月14日*
|
||||
*维护人员:系统管理员*
|
||||
|
||||
@@ -126,6 +126,8 @@ pip list | grep -E "(flask|gunicorn|openai)"
|
||||
|
||||
- **主页**:`http://101.43.95.130:5002/`
|
||||
- **饭菜规划**:`http://101.43.95.130:5002/meal-planning`
|
||||
- **古诗词解析**:`http://101.43.95.130:5002/poetry/`
|
||||
- **古诗词示例**:`http://101.43.95.130:5002/poetry/examples`
|
||||
- **后台管理**:`http://101.43.95.130:5002/admin`
|
||||
- **数据分析**:`http://101.43.95.130:5002/admin/analytics_admin/`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user