diff --git a/apps/jingrow/frontend/src/app/router/index.ts b/apps/jingrow/frontend/src/app/router/index.ts
index 78bcec6..e226c19 100644
--- a/apps/jingrow/frontend/src/app/router/index.ts
+++ b/apps/jingrow/frontend/src/app/router/index.ts
@@ -18,6 +18,12 @@ const router = createRouter({
},
{
path: '/',
+ name: 'HomePage',
+ component: () => import('../../views/HomePage.vue'),
+ meta: { requiresAuth: false }
+ },
+ {
+ path: '/app',
name: 'AppLayout',
component: () => import('../layouts/AppLayout.vue'),
meta: { requiresAuth: true },
diff --git a/apps/jingrow/frontend/src/locales/zh-CN.json b/apps/jingrow/frontend/src/locales/zh-CN.json
index 7724eea..50b8a72 100644
--- a/apps/jingrow/frontend/src/locales/zh-CN.json
+++ b/apps/jingrow/frontend/src/locales/zh-CN.json
@@ -17,7 +17,7 @@
"Pending Review": "待审核",
"Dashboard": "仪表板",
"Agents": "AI智能体",
- "Settings": "设置",
+ "Settings": "系统设置",
"Agent Detail": "智能体详情",
"Flow Builder": "流程编排",
"Profile": "个人资料",
diff --git a/apps/jingrow/frontend/src/views/HomePage.vue b/apps/jingrow/frontend/src/views/HomePage.vue
new file mode 100644
index 0000000..a7a4a01
--- /dev/null
+++ b/apps/jingrow/frontend/src/views/HomePage.vue
@@ -0,0 +1,1602 @@
+
+
+
+
+
+
+
diff --git a/apps/jingrow/jingrow/services/whitelist.py b/apps/jingrow/jingrow/services/whitelist.py
index 6b0990e..cbf6da0 100644
--- a/apps/jingrow/jingrow/services/whitelist.py
+++ b/apps/jingrow/jingrow/services/whitelist.py
@@ -60,15 +60,6 @@ async def authenticate_request(request: Request, allow_guest: bool) -> bool:
async def _process_whitelist_call(request: Request, full_module_path: str):
"""通用处理:接收完整点分路径 '' 并执行调用"""
try:
- async def _get_request_data(req: Request) -> Dict[str, Any]:
- """GET 使用查询参数,其他方法使用 JSON body"""
- if req.method == 'GET':
- return dict(req.query_params)
- try:
- return await req.json()
- except Exception:
- return {}
-
# 确保 apps 目录在 sys.path 中(支持跨 app 导入)
ensure_apps_on_sys_path()
@@ -96,8 +87,28 @@ async def _process_whitelist_call(request: Request, full_module_path: str):
if not await authenticate_request(request, whitelist_info['allow_guest']):
raise HTTPException(status_code=401, detail="Authentication required")
+ # 根据请求类型获取数据
+ if request.method == 'GET':
+ request_data = dict(request.query_params)
+ else:
+ # 检查 Content-Type 是否为 multipart/form-data
+ content_type = request.headers.get('content-type', '')
+ is_multipart = 'multipart/form-data' in content_type
+
+ if is_multipart:
+ # 处理文件上传
+ form = await request.form()
+ request_data = {}
+ for key, value in form.items():
+ request_data[key] = value
+ else:
+ # 处理 JSON body
+ try:
+ request_data = await request.json()
+ except Exception:
+ request_data = {}
+
# 调用函数(只有通过白名单验证的函数才能执行到这里)
- request_data = await _get_request_data(request)
result = func(**request_data)
return JSONResponse(content={"success": True, "data": result})
diff --git a/apps/jingrow/jingrow/tools/remove_background/remove_background.py b/apps/jingrow/jingrow/tools/remove_background/remove_background.py
index ed4921f..c4ba473 100644
--- a/apps/jingrow/jingrow/tools/remove_background/remove_background.py
+++ b/apps/jingrow/jingrow/tools/remove_background/remove_background.py
@@ -15,6 +15,127 @@ from jingrow.utils.auth import get_jingrow_cloud_api_headers, get_jingrow_cloud_
logger = logging.getLogger(__name__)
+@jingrow.whitelist(allow_guest=True)
+def remove_background_from_file_free(file) -> Dict[str, Any]:
+ """
+ 免费图片去背景工具(无需认证)
+ 参考 remove_background_from_file 实现,调用 Jingrow Cloud API 实现图片背景移除
+
+ Args:
+ file: 上传的文件对象
+
+ Returns:
+ dict: 处理结果,格式与 remove_background_from_file 一致
+ """
+ try:
+ # 获取认证头(使用系统配置的 API Key)
+ headers = get_jingrow_cloud_api_headers()
+
+ if not headers or not headers.get('Authorization'):
+ return {
+ "success": False,
+ "error": "API密钥未设置,请联系管理员配置"
+ }
+
+ # 读取文件内容
+ # whitelist 服务传递的 file 是 FastAPI 的 UploadFile 对象
+ # UploadFile.file 是底层的 SpooledTemporaryFile,可以同步读取
+ # 需要先重置文件指针到开头(因为可能已经被读取过)
+ file.file.seek(0)
+ file_content = file.file.read()
+
+ if not file_content or len(file_content) == 0:
+ return {
+ "success": False,
+ "error": "文件内容为空"
+ }
+
+ # 获取文件扩展名和内容类型
+ filename = getattr(file, 'filename', None) or 'image.png'
+ ext = filename.split('.')[-1].lower() if '.' in filename else 'png'
+ if ext == 'jpg':
+ ext = 'jpg'
+ content_type = 'image/jpeg'
+ elif ext == 'jpeg':
+ ext = 'jpg'
+ content_type = 'image/jpeg'
+ elif ext == 'png':
+ ext = 'png'
+ content_type = 'image/png'
+ elif ext == 'webp':
+ ext = 'webp'
+ content_type = 'image/webp'
+ else:
+ ext = 'png'
+ content_type = 'image/png'
+
+ # 处理EXIF orientation(参考 remove_background_from_file)
+ image = Image.open(io.BytesIO(file_content))
+ image = ImageOps.exif_transpose(image)
+ output = io.BytesIO()
+ save_format = image.format or content_type.split('/')[-1].upper()
+ image.save(output, format=save_format)
+ image_bytes = output.getvalue()
+
+ # 调用文件上传端点(与 remove_background_from_file 使用相同的接口)
+ api_url = f"{get_jingrow_cloud_api_url()}/rmbg/file/free"
+
+ # 移除 Content-Type,让 requests 自动设置 multipart/form-data
+ upload_headers = {k: v for k, v in headers.items() if k.lower() != 'content-type'}
+ files = {
+ 'file': (f'image.{ext}', image_bytes, content_type)
+ }
+
+ # 转发请求
+ response = requests.post(
+ api_url,
+ files=files,
+ headers=upload_headers,
+ timeout=180
+ )
+
+ if response.status_code == 200:
+ result_data = response.json()
+
+ # 使用 image_url 字段,返回格式与 remove_background_from_file 一致
+ if 'image_url' in result_data:
+ image_url = result_data.get('image_url', '')
+ return {
+ "success": True,
+ "data": [{
+ "success": True,
+ "image_url": image_url,
+ "index": 1,
+ "total": 1
+ }],
+ "total_processed": 1,
+ "total_success": 1
+ }
+
+ return {
+ "success": False,
+ "error": result_data.get('error', '未找到图片URL')
+ }
+ else:
+ try:
+ error_data = response.json()
+ error_message = error_data.get("message") or error_data.get("error") or f"API请求失败 (HTTP {response.status_code})"
+ except:
+ error_message = f"API请求失败 (HTTP {response.status_code})"
+
+ return {
+ "success": False,
+ "error": error_message
+ }
+
+ except Exception as e:
+ logger.error(f"调用图片去背景API异常:{str(e)}", exc_info=True)
+ return {
+ "success": False,
+ "error": f"调用图片去背景API异常:{str(e)}"
+ }
+
+
@jingrow.whitelist()
def remove_background_from_file(image_data: Union[str, list]) -> Dict[str, Any]:
"""