完成后端架构重构等

This commit is contained in:
super
2026-04-23 15:25:41 +08:00
parent 46f46039ea
commit 34bc980eea
76 changed files with 3242 additions and 1111 deletions

View File

@@ -13,7 +13,7 @@ client_name=ShuFuAI
# java_api_base=http://47.111.163.154:18080
# java_api_base=http://127.0.0.1:18080
java_api_base=http://8.136.19.173:18080
java_api_base=http://127.0.0.1:18080
# java_api_base=http://8.136.19.173:18080

View File

@@ -12,9 +12,14 @@ from flask import request, redirect, url_for, session, jsonify, render_template,
from config import mysql_host, mysql_user, mysql_password, mysql_database
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_DIR = os.path.join(BASE_DIR, 'static')
ASSETS_DIR = os.path.join(BASE_DIR, 'assets')
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_DIR = os.path.join(BASE_DIR, 'static')
ASSETS_DIR = os.path.join(BASE_DIR, 'assets')
WEB_SOURCE_DIR = os.path.join(BASE_DIR, 'web_source')
TEMPLATE_FALLBACK_DIRS = (
WEB_SOURCE_DIR,
os.path.join(WEB_SOURCE_DIR, 'templates_backup'),
)
def get_db():
@@ -30,9 +35,13 @@ def get_db():
def _render_html(template_name: str, **context):
"""读取 HTML 模板:若为加密文件则先解密,再渲染。未加密或解密失败时按明文渲染。"""
path = os.path.join(BASE_DIR, "web_source", template_name)
if not os.path.isfile(path):
return render_template(template_name, **context)
path = next(
(candidate for candidate in (os.path.join(base_path, template_name) for base_path in TEMPLATE_FALLBACK_DIRS)
if os.path.isfile(candidate)),
None,
)
if path is None:
return render_template(template_name, **context)
with open(path, "rb") as f:
raw = f.read()
try:
@@ -45,9 +54,13 @@ def _render_html(template_name: str, **context):
def _render_html_new(template_name: str, **context):
"""读取 HTML 模板:若为加密文件则先解密,再渲染。未加密或解密失败时按明文渲染。"""
path = os.path.join(BASE_DIR, "web_source", template_name)
if not os.path.isfile(path):
return render_template(template_name, **context)
path = next(
(candidate for candidate in (os.path.join(base_path, template_name) for base_path in TEMPLATE_FALLBACK_DIRS)
if os.path.isfile(candidate)),
None,
)
if path is None:
return render_template(template_name, **context)
with open(path, "rb") as f:
raw = f.read()
try:

View File

@@ -2,7 +2,7 @@
主页面蓝图首页、home、图片工作台、品牌页、静态文件、Logo
"""
import os
from flask import Blueprint, send_file
from flask import Blueprint, send_file, render_template_string
from app_common import (
get_db,
@@ -20,7 +20,39 @@ import requests
from config import base_url,version,JAVA_API_BASE
main_bp = Blueprint('main', __name__)
main_bp = Blueprint('main', __name__)
def _resolve_asset_filename(filename):
"""Resolve hashed Vite assets without maintaining hardcoded alias tables."""
safe_name = os.path.basename(filename)
exact_path = os.path.join(ASSETS_DIR, safe_name)
if os.path.isfile(exact_path):
return safe_name
base_name, ext = os.path.splitext(safe_name)
if not base_name or not ext:
return safe_name
parts = base_name.split('-')
if len(parts) < 2:
return safe_name
try:
asset_names = os.listdir(ASSETS_DIR)
except OSError:
return safe_name
for prefix_length in range(len(parts) - 1, 0, -1):
prefix = '-'.join(parts[:prefix_length])
matches = [
asset_name for asset_name in asset_names
if asset_name.endswith(ext) and asset_name.startswith(prefix)
]
if len(matches) == 1:
return matches[0]
return safe_name
@main_bp.route('/')
@@ -50,10 +82,42 @@ def wb():
return _render_html('index.html')
@main_bp.route('/brand')
@login_required
def brand_page():
return _render_html('brand.html', user_id=session.get('user_id'))
@main_bp.route('/brand')
@login_required
def brand_page():
repo_brand_path = os.path.abspath(os.path.join(BASE_DIR, '..', 'web_source', 'brand.html'))
if os.path.isfile(repo_brand_path):
try:
with open(repo_brand_path, 'rb') as f:
raw = f.read()
try:
from html_crypto import decrypt
content = decrypt(raw).decode('utf-8')
except Exception:
if raw[:7] == b'gAAAAAB':
raise
content = raw.decode('utf-8', errors='replace')
return render_template_string(content, user_id=session.get('user_id'))
except Exception:
pass
return _render_html('brand.html', user_id=session.get('user_id'))
@main_bp.route('/brand/legacy')
@login_required
def brand_page_legacy():
legacy_path = os.path.join(BASE_DIR, 'web_source', 'templates_backup', 'brand.html')
if not os.path.isfile(legacy_path):
return '', 404
with open(legacy_path, 'rb') as f:
content = f.read().decode('utf-8', errors='replace')
content = content.replace(
'<header class="top-bar">',
'<header class="top-bar" style="display:none !important;">',
1,
)
content = content.replace('height: calc(100vh - 56px);', 'height: 100vh;', 1)
return render_template_string(content, user_id=session.get('user_id'))
@@ -69,10 +133,11 @@ def serve_static(filename):
return send_file(file_abs, as_attachment=False)
@main_bp.route('/assets/<path:filename>')
def serve_assets(filename):
"""提供 static 目录及子目录下的静态文件访问。"""
filepath = os.path.normpath(os.path.join(ASSETS_DIR, filename))
@main_bp.route('/assets/<path:filename>')
def serve_assets(filename):
"""提供 static 目录及子目录下的静态文件访问。"""
filename = _resolve_asset_filename(filename)
filepath = os.path.normpath(os.path.join(ASSETS_DIR, filename))
static_abs = os.path.abspath(ASSETS_DIR)
file_abs = os.path.abspath(filepath)
if not file_abs.startswith(static_abs) or not os.path.isfile(file_abs):
@@ -82,14 +147,19 @@ def serve_assets(filename):
@main_bp.route('/new_web_source/<path:filename>')
def serve_new_web_source(filename):
"""提供 static 目录及子目录下的静态文件访问。"""
filepath = os.path.normpath(os.path.join("new_web_source", filename))
static_abs = os.path.abspath("new_web_source")
file_abs = os.path.abspath(filepath)
if not file_abs.startswith(static_abs) or not os.path.isfile(file_abs):
return '', 404
return send_file(file_abs, as_attachment=False)
"""提供 new_web_source 目录下的静态页面文件访问。"""
candidate_dirs = [
os.path.abspath(os.path.join(BASE_DIR, 'new_web_source')),
os.path.abspath(os.path.join(BASE_DIR, '..', 'new_web_source')),
]
for static_abs in candidate_dirs:
filepath = os.path.normpath(os.path.join(static_abs, filename))
file_abs = os.path.abspath(filepath)
if not file_abs.startswith(static_abs):
continue
if os.path.isfile(file_abs):
return send_file(file_abs, as_attachment=False)
return '', 404
@main_bp.route('/logo.jpg', methods=['GET'])
@@ -161,4 +231,4 @@ def proxy(path):
return Response("无法连接到后端服务", status=502)
except Exception as e:
print(f"代理请求失败: {e}")
return Response(f"代理错误: {str(e)}", status=500)
return Response(f"代理错误: {str(e)}", status=500)

View File

@@ -3,11 +3,12 @@ coze_token = "sat_12nW40INoJxArrDXbY4lSCoudbqkOYTcphC99BP2efWyzxmsk4q81WDX3ezWgq
workflow_id = "7608812635877900322"
STITCH_WORKFLOW_ID = "7608813873483300907"
import os
from dotenv import load_dotenv
from queue import Queue
load_dotenv()
_base_url = os.getenv("base_url","http://159.75.121.33:15124")
import os
from dotenv import load_dotenv
from queue import Queue
load_dotenv()
_base_url = os.getenv("base_url","http://159.75.121.33:15124")
base_dir = os.path.dirname(os.path.abspath(__file__))
# MySQL 配置
mysql_host = os.getenv("mysql_host")
@@ -15,10 +16,11 @@ mysql_user = os.getenv("mysql_user")
mysql_password = os.getenv("mysql_password","WTFrb5y6hNLz6hNy")
mysql_database = os.getenv("mysql_database","aiimage")
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://127.0.0.1:18080")
proxy_mode = int(os.getenv("proxy_mode",1))
_client_name = os.getenv("client_name", "").strip()
client_name = f"{_client_name}.exe" if _client_name else "client.exe"
JAVA_API_BASE = os.getenv("java_api_base", "http://127.0.0.1:18080")
# 紫鸟浏览器配置
from urllib.parse import unquote

View File

@@ -433,7 +433,7 @@ def main():
webview.start(
debug=True,
storage_path=cache_path,
private_mode=False
private_mode=True
)