diff --git a/app/.env b/app/.env index 6a503c9..77818f1 100644 --- a/app/.env +++ b/app/.env @@ -1,13 +1,14 @@ -base_url=http://159.75.121.33:15124 -workflow_id=7608812635877900322 -mysql_host=159.75.121.33 -mysql_user=AIimage - -proxy_url=https://api.jikip.com/ip-get?num=1&minute=1&format=json&area=all&protocol=1&mode=2&key=r4m8dov52giup2o -proxy_mode=2 - -client_name=NanriAI -# java_api_base=http://8.136.19.173:18080 -java_api_base=http://127.0.0.1:18080 - - +base_url=http://8.136.19.173:15124 +workflow_id=7608812635877900322 +mysql_host=8.136.19.173 +mysql_user=aiimage + +proxy_url=https://api.jikip.com/ip-get?num=1&minute=1&format=json&area=all&protocol=1&mode=2&key=t24g6gi44ubufd8 +proxy_mode=2 + +client_name=ShuFuAI + + +java_api_base=http://8.136.19.173:18080 + + diff --git a/app/ali_oss.py b/app/ali_oss.py index 179fadd..35fbe08 100644 --- a/app/ali_oss.py +++ b/app/ali_oss.py @@ -14,7 +14,6 @@ def upload_file(file_content: bytes, key: str): cfg.credentials_provider = credentials_provider cfg.region = region cfg.endpoint = endpoint - cfg.retry_max_attempts = 3 client = oss.Client(cfg) result = client.put_object( diff --git a/app/app.py b/app/app.py index 940be83..751bbbc 100644 --- a/app/app.py +++ b/app/app.py @@ -15,13 +15,24 @@ from blueprints.main import main_bp from blueprints.admin import admin_bp from blueprints.image import image_bp from blueprints.brand import brand_bp +from blueprints.communication import communication_bp def create_app(): app = Flask(__name__, template_folder=BASE_DIR, static_folder=BASE_DIR) - CORS(app) - app.secret_key = os.environ.get('SECRET_KEY', secrets.token_hex(32)) + frontend_origin = os.environ.get('FRONTEND_ORIGIN', '*') + cors_origins = frontend_origin if frontend_origin != '*' else '*' + CORS( + app, + supports_credentials=True, + resources={r"/api/*": {"origins": cors_origins}, r"/login": {"origins": cors_origins}}, + ) + # 生产环境必须通过环境变量注入固定 SECRET_KEY;否则服务重启会使旧会话失效。 + app.secret_key = os.environ.get('SECRET_KEY', 'dev-secret-key-change-me') app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7) + app.config['SESSION_COOKIE_HTTPONLY'] = True + app.config['SESSION_COOKIE_SAMESITE'] = os.environ.get('SESSION_COOKIE_SAMESITE', 'Lax') + app.config['SESSION_COOKIE_SECURE'] = os.environ.get('SESSION_COOKIE_SECURE', '0') == '1' # 注册蓝图(不设 url_prefix,保持原有 URL 路径不变,前端无需改动) app.register_blueprint(auth_bp) @@ -29,6 +40,7 @@ def create_app(): app.register_blueprint(admin_bp) app.register_blueprint(image_bp) app.register_blueprint(brand_bp) + app.register_blueprint(communication_bp) return app diff --git a/app/blueprints/__pycache__/communication.cpython-39.pyc b/app/blueprints/__pycache__/communication.cpython-39.pyc new file mode 100644 index 0000000..d33fdb6 Binary files /dev/null and b/app/blueprints/__pycache__/communication.cpython-39.pyc differ diff --git a/app/blueprints/communication.py b/app/blueprints/communication.py index 7d85a76..ef56333 100644 --- a/app/blueprints/communication.py +++ b/app/blueprints/communication.py @@ -1,18 +1,67 @@ -from queue import Empty +import threading +import time +from queue import Empty, Full -from flask import Blueprint, jsonify +from flask import Blueprint, jsonify, request from config import JSON_TASK_QUEUE communication_bp = Blueprint('communication', __name__) +_del_brand_cache = {} +_del_brand_cache_lock = threading.Lock() +_latest_del_brand_item = None +_latest_del_brand_ts = 0.0 + + +def _resolve_request_id(): + rid = request.args.get('id') + if rid is not None and str(rid).strip() != '': + return str(rid) + if request.method == 'POST': + body = request.get_json(silent=True) or {} + rid = body.get('id') + if rid is not None and str(rid).strip() != '': + return str(rid) + return None + @communication_bp.route('/api/amazon/del_brand', methods=['GET', 'POST']) def del_brand(): - """返回队列中的一个元素;队列为空时返回空提示。""" + """返回队列中的一个元素;同一 id 重复请求返回已缓存的同一元素;2分钟内不同 id 也返回最近元素。""" + global _latest_del_brand_item, _latest_del_brand_ts + request_id = _resolve_request_id() + if not request_id: + return jsonify({'success': False, 'message': '缺少参数 id', 'data': None}), 400 + + with _del_brand_cache_lock: + if request_id in _del_brand_cache: + item = _del_brand_cache[request_id] + print("【删除品牌】缓存命中", request_id, item) + return jsonify({'success': True, 'data': item}) + if _latest_del_brand_item is not None and (time.time() - _latest_del_brand_ts) <= 120: + _del_brand_cache[request_id] = _latest_del_brand_item + print("【删除品牌】2分钟窗口命中", request_id, _latest_del_brand_item) + return jsonify({'success': True, 'data': _latest_del_brand_item}) + try: item = JSON_TASK_QUEUE.get_nowait() - return jsonify({'success': True, 'data': item}) except Empty: + print("队列为空") return jsonify({'success': False, 'message': '队列为空', 'data': None}) + + with _del_brand_cache_lock: + if request_id in _del_brand_cache: + try: + JSON_TASK_QUEUE.put_nowait(item) + except Full: + print("【删除品牌】队列已满,无法归还重复拉取的任务") + item = _del_brand_cache[request_id] + print("【删除品牌】并发归并", request_id, item) + return jsonify({'success': True, 'data': item}) + _del_brand_cache[request_id] = item + _latest_del_brand_item = item + _latest_del_brand_ts = time.time() + print("【删除品牌】返回任务数据", item) + return jsonify({'success': True, 'data': item}) diff --git a/app/brand_spider/__pycache__/main.cpython-39.pyc b/app/brand_spider/__pycache__/main.cpython-39.pyc index 14ba46b..05fe062 100644 Binary files a/app/brand_spider/__pycache__/main.cpython-39.pyc and b/app/brand_spider/__pycache__/main.cpython-39.pyc differ diff --git a/app/config.py b/app/config.py index 3e86f27..8f5c626 100644 --- a/app/config.py +++ b/app/config.py @@ -18,9 +18,9 @@ proxy_url = os.getenv("proxy_url") proxy_mode = int(os.getenv("proxy_mode",1)) client_name=os.getenv("client_name") + ".exe" -# JAVA_API_BASE = os.getenv("java_api_base", "http://8.136.19.173:18080") JAVA_API_BASE = os.getenv("java_api_base", "http://127.0.0.1:18080") + cache_path = "./user_data" region = "cn-hangzhou" @@ -39,8 +39,8 @@ os.environ['OSS_ACCESS_KEY_SECRET'] = accessKeySecret os.environ['SECRET_KEY'] = "ddffc7c1d02121d9554d7b080b2511b6" -debug = True -version = "1.0.13" +debug = False +version = "1.0.22" APP_UPDATE_URL = f"{_base_url}/api/version/latest" # 检测更新接口地址,返回 { "file_url": "...", "version": "x.x.x" } os.environ['APP_VERSION'] = version os.environ['APP_UPDATE_URL'] = APP_UPDATE_URL diff --git a/app/main.py b/app/main.py index 2fa401f..5a7d640 100644 --- a/app/main.py +++ b/app/main.py @@ -237,6 +237,9 @@ class WindowAPI: def enqueue_json(self, data): """保存任务到队列""" try: + print("==============================") + print(datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S"),"调用传入",data) + print("==================================") payload = data if isinstance(data, str): payload = json.loads(data) @@ -349,7 +352,7 @@ def main(): window.expose(api.close, api.minimize, api.maximize, api.toggle_maximize, generate_images, api.save_image, api.save_image_to_folder, api.select_folder, api.select_brand_xlsx_files, api.select_brand_folder, api.save_file_from_url, api.save_template_xlsx,api.save_template_zip,api.upload_file_to_java,api.enqueue_json) webview.start( - debug=True, + debug=False, storage_path=cache_path, private_mode=False ) diff --git a/app/static/bg.jpg b/app/static/bg.jpg index de6e38d..2775db8 100644 Binary files a/app/static/bg.jpg and b/app/static/bg.jpg differ diff --git a/app/tool/__pycache__/devices.cpython-39.pyc b/app/tool/__pycache__/devices.cpython-39.pyc index f8f664a..efea90f 100644 Binary files a/app/tool/__pycache__/devices.cpython-39.pyc and b/app/tool/__pycache__/devices.cpython-39.pyc differ