feat: 支持网站目标分组轻量管理(新增、编辑、描述展示),不修改和不提交倍率

This commit is contained in:
liumangmang
2026-07-01 17:47:36 +08:00
parent e5d7af8906
commit 8c2f1c13bb
7 changed files with 248 additions and 2 deletions
+45
View File
@@ -30,6 +30,8 @@ from app.schemas.website import (
TestResult,
WebsiteCreate,
WebsiteGroupResponse,
WebsiteGroupCreate,
WebsiteGroupUpdate,
WebsiteResponse,
WebsiteSyncLogResponse,
WebsiteUpdate,
@@ -291,6 +293,49 @@ def list_website_groups(wid: int, db: Session = Depends(get_db), _=Depends(get_c
raise HTTPException(502, str(exc))
@router.post("/api/websites/{wid}/groups", response_model=dict)
def create_website_group(
wid: int,
body: WebsiteGroupCreate,
db: Session = Depends(get_db),
_=Depends(get_current_user),
):
row = db.query(Website).filter(Website.id == wid).first()
if not row:
raise HTTPException(404, "website not found")
try:
with _client(row) as c:
payload = {
"name": body.name,
"description": body.description,
}
return c.create_group(payload, row.groups_endpoint)
except Exception as exc:
raise HTTPException(502, str(exc))
@router.put("/api/websites/{wid}/groups/{group_id}", response_model=dict)
def update_website_group(
wid: int,
group_id: str,
body: WebsiteGroupUpdate,
db: Session = Depends(get_db),
_=Depends(get_current_user),
):
row = db.query(Website).filter(Website.id == wid).first()
if not row:
raise HTTPException(404, "website not found")
try:
with _client(row) as c:
payload = {
"name": body.name,
"description": body.description,
}
return c.update_group(row.group_update_endpoint, group_id, payload)
except Exception as exc:
raise HTTPException(502, str(exc))
@router.post("/api/websites/{wid}/groups/import-from-upstream/{upstream_id}", response_model=ImportGroupsResponse)
def import_groups_from_upstream(
wid: int,
+11
View File
@@ -64,9 +64,20 @@ class WebsiteGroupResponse(BaseModel):
id: str
name: str
rate_multiplier: Optional[str] = None
description: Optional[str] = None
raw: dict[str, Any] = {}
class WebsiteGroupCreate(BaseModel):
name: str = Field(..., min_length=1)
description: Optional[str] = None
class WebsiteGroupUpdate(BaseModel):
name: str = Field(..., min_length=1)
description: Optional[str] = None
class BindingSourceGroup(BaseModel):
upstream_id: int
group_id: str
+15 -1
View File
@@ -113,7 +113,13 @@ def normalize_groups(value: Any) -> list[dict[str, Any]]:
groups: list[dict[str, Any]] = []
for item in raw:
if isinstance(item, str):
groups.append({"id": item, "name": item, "rate_multiplier": None, "raw": {"id": item, "name": item}})
groups.append({
"id": item,
"name": item,
"rate_multiplier": None,
"description": None,
"raw": {"id": item, "name": item}
})
continue
if not isinstance(item, dict):
continue
@@ -122,10 +128,12 @@ def normalize_groups(value: Any) -> list[dict[str, Any]]:
continue
name = item.get("name") or item.get("group_name") or str(gid)
rate = item.get("rate_multiplier") or item.get("rateMultiplier") or item.get("ratio")
desc = item.get("description") or item.get("desc") or item.get("remark")
groups.append({
"id": str(gid),
"name": str(name),
"rate_multiplier": fixed_decimal_string(rate, 2) if rate is not None else None,
"description": str(desc) if desc is not None else None,
"raw": item,
})
return groups
@@ -262,6 +270,12 @@ class Sub2ApiWebsiteClient:
path = endpoint_template.replace("{id}", quote(group_id, safe=""))
return self._request("PUT", path, {"rate_multiplier": fixed_decimal_number(rate, 2)})
def update_group(self, endpoint_template: str, group_id: str, body: dict[str, Any]) -> dict[str, Any]:
path = endpoint_template.replace("{id}", quote(group_id, safe=""))
resp = self._request("PUT", path, body)
data = _unwrap_data(resp)
return data if isinstance(data, dict) else {"value": data}
def create_group(self, body: dict[str, Any], endpoint: str = "/groups") -> dict[str, Any]:
resp = self._request("POST", endpoint, body)
data = _unwrap_data(resp)