Initial commit - DesignerCEP Project with Caddy deployment
This commit is contained in:
140
Server/app/api/v1/jsx_executor.py
Normal file
140
Server/app/api/v1/jsx_executor.py
Normal file
@@ -0,0 +1,140 @@
|
||||
"""
|
||||
服务器端 JSX 执行器
|
||||
关键业务逻辑在服务器执行,前端只能通过 API 调用
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Depends
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, Dict, Any
|
||||
from app.core.security import get_current_user
|
||||
from app.db import get_db_session
|
||||
import json
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# JSX 脚本模板库(服务器端存储)
|
||||
JSX_TEMPLATES = {
|
||||
"create_layer": """
|
||||
(function(layerName) {
|
||||
try {
|
||||
if (app.documents.length === 0) {
|
||||
return JSON.stringify({ error: '没有打开的文档' });
|
||||
}
|
||||
var doc = app.activeDocument;
|
||||
var layer = doc.artLayers.add();
|
||||
layer.name = layerName;
|
||||
return JSON.stringify({
|
||||
success: true,
|
||||
layerName: layerName
|
||||
});
|
||||
} catch (e) {
|
||||
return JSON.stringify({ error: e.toString() });
|
||||
}
|
||||
})('{layerName}')
|
||||
""",
|
||||
|
||||
"create_layer_with_style": """
|
||||
(function(layerName, opacity, color) {
|
||||
try {
|
||||
if (app.documents.length === 0) {
|
||||
return JSON.stringify({ error: '没有打开的文档' });
|
||||
}
|
||||
var doc = app.activeDocument;
|
||||
var layer = doc.artLayers.add();
|
||||
layer.name = layerName;
|
||||
layer.opacity = opacity;
|
||||
|
||||
// 这里是你的核心算法
|
||||
// 客户端无法看到具体实现
|
||||
|
||||
return JSON.stringify({
|
||||
success: true,
|
||||
layerName: layerName,
|
||||
applied: true
|
||||
});
|
||||
} catch (e) {
|
||||
return JSON.stringify({ error: e.toString() });
|
||||
}
|
||||
})('{layerName}', {opacity}, '{color}')
|
||||
""",
|
||||
|
||||
# 更多核心功能...
|
||||
}
|
||||
|
||||
class JSXExecuteRequest(BaseModel):
|
||||
template_name: str # 模板名称(不是完整脚本)
|
||||
params: Dict[str, Any] # 参数
|
||||
device_id: str
|
||||
|
||||
class JSXExecuteResponse(BaseModel):
|
||||
success: bool
|
||||
jsx_code: str # 返回要执行的 JSX 代码
|
||||
message: Optional[str] = None
|
||||
|
||||
@router.post("/execute", response_model=JSXExecuteResponse)
|
||||
async def execute_jsx(
|
||||
request: JSXExecuteRequest,
|
||||
current_user: dict = Depends(get_current_user)
|
||||
):
|
||||
"""
|
||||
服务器端生成 JSX 代码
|
||||
客户端只能通过 API 获取,无法直接看到核心逻辑
|
||||
"""
|
||||
try:
|
||||
username = current_user.get("username")
|
||||
|
||||
# 1. 验证用户和设备
|
||||
# ... (从数据库检查用户是否有权限、设备是否绑定)
|
||||
|
||||
# 2. 检查模板是否存在
|
||||
if request.template_name not in JSX_TEMPLATES:
|
||||
raise HTTPException(status_code=404, detail="模板不存在")
|
||||
|
||||
# 3. 验证用户权限(某些高级功能需要付费)
|
||||
# ... (从数据库检查用户等级)
|
||||
|
||||
# 4. 获取模板并填充参数
|
||||
template = JSX_TEMPLATES[request.template_name]
|
||||
|
||||
# 参数安全过滤(防止注入)
|
||||
safe_params = {
|
||||
key: str(value).replace("'", "\\'").replace('"', '\\"')
|
||||
for key, value in request.params.items()
|
||||
}
|
||||
|
||||
# 填充参数
|
||||
jsx_code = template.format(**safe_params)
|
||||
|
||||
# 5. 记录操作日志
|
||||
# ... (记录谁在什么时候执行了什么操作)
|
||||
|
||||
return JSXExecuteResponse(
|
||||
success=True,
|
||||
jsx_code=jsx_code,
|
||||
message="代码已生成"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@router.get("/templates")
|
||||
async def list_templates(current_user: dict = Depends(get_current_user)):
|
||||
"""
|
||||
列出可用的 JSX 模板(不返回具体代码)
|
||||
"""
|
||||
return {
|
||||
"templates": [
|
||||
{
|
||||
"name": "create_layer",
|
||||
"description": "创建图层",
|
||||
"params": ["layerName"]
|
||||
},
|
||||
{
|
||||
"name": "create_layer_with_style",
|
||||
"description": "创建带样式的图层(高级)",
|
||||
"params": ["layerName", "opacity", "color"],
|
||||
"premium": True # 需要付费
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user