From 64715a2c9e47a247a37c02250d904953ac4f498a Mon Sep 17 00:00:00 2001 From: shenlei Date: Tue, 4 Aug 2026 12:27:36 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=85=BE=E8=AE=AF=20AppID=20=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E8=A1=A5=E5=85=A8=20tencent=20=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增/编辑 App 时,腾讯 AppID 允许只填数字,后端统一归一化为 tencent 前缀;前端输入框失焦即时补全,保存前再校正一次。 Co-Authored-By: Claude Opus 5 --- backend/routers/config.py | 10 ++++++++++ frontend/src/views/ConfigView.vue | 10 +++++++++- tests/test_api_config.py | 25 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/backend/routers/config.py b/backend/routers/config.py index 2d49457..515e3e5 100644 --- a/backend/routers/config.py +++ b/backend/routers/config.py @@ -254,6 +254,14 @@ def _apply_special_app_prefix_override(app: dict) -> None: app["app_id_prefix_override"] = 1 +def _normalize_tencent_app_id(app: dict) -> None: + """腾讯 AppID 统一带 tencent 前缀(允许只填数字 ID)。""" + value = str(app.get("tencent") or "").strip() + if not value: + return + app["tencent"] = value if value.startswith("tencent") else f"tencent{value}" + + def _next_app_id(apps: dict, servers: dict, app: dict) -> str: """根据环境前缀或 App 特殊覆盖生成下一个配置 ID。""" prefix = app.get("app_id_prefix_override") @@ -412,6 +420,7 @@ async def create_app(app: dict): # 按服务环境自动生成三位 ID(例如测试环境 1xx、正式环境 2xx)。 _apply_special_app_prefix_override(app) + _normalize_tencent_app_id(app) new_id = _next_app_id(apps, config.get("servers", {}), app) # 自动生成 upload_key @@ -434,6 +443,7 @@ async def update_app(app_id: str, app: dict): if app_id not in apps: raise HTTPException(status_code=404, detail="App 不存在") + _normalize_tencent_app_id(app) apps[app_id] = app config["apps"] = apps save_config(config) diff --git a/frontend/src/views/ConfigView.vue b/frontend/src/views/ConfigView.vue index 4ecb2aa..d63cdb0 100644 --- a/frontend/src/views/ConfigView.vue +++ b/frontend/src/views/ConfigView.vue @@ -491,7 +491,7 @@
- +
@@ -1014,12 +1014,20 @@ const formatSize = (bytes) => { return (bytes / (1024 * 1024)).toFixed(1) + ' MB' } +// 腾讯 AppID 统一带 tencent 前缀(允许只填数字 ID) +const normalizeTencentAppId = () => { + const value = (appForm.value.tencent || '').trim() + appForm.value.tencent = value && !value.startsWith('tencent') ? `tencent${value}` : value +} + const saveApp = async () => { if (!appForm.value.name || !appForm.value.AppGuid) { alert('请填写必填字段:App 名称、AppGuid') return } + normalizeTencentAppId() + // 清理空证书 if (appForm.value.certificates) { Object.keys(appForm.value.certificates).forEach(key => { diff --git a/tests/test_api_config.py b/tests/test_api_config.py index d445843..d614f09 100644 --- a/tests/test_api_config.py +++ b/tests/test_api_config.py @@ -48,6 +48,31 @@ def test_create_app_rejects_unknown_environment_id_rule(client, tmp_config): assert "ID 规则" in resp.json()["detail"] +def test_create_app_prefixes_tencent_app_id(client, tmp_config): + resp = client.post("/api/config/apps", json={ + "name": "腾讯App", "server": "测试环境", "AppGuid": "guid", "tencent": "123456", + }) + assert resp.status_code == 200 + app_id = resp.json()["id"] + assert client.get("/api/config/apps").json()[app_id]["tencent"] == "tencent123456" + + +def test_create_app_keeps_existing_tencent_prefix(client, tmp_config): + resp = client.post("/api/config/apps", json={ + "name": "腾讯App2", "server": "测试环境", "AppGuid": "guid", "tencent": "tencent123456", + }) + app_id = resp.json()["id"] + assert client.get("/api/config/apps").json()[app_id]["tencent"] == "tencent123456" + + +def test_update_app_prefixes_tencent_app_id(client, tmp_config): + resp = client.put("/api/config/apps/1", json={ + "name": "改名App", "AppGuid": "test-guid", "tencent": " 987654 ", + }) + assert resp.status_code == 200 + assert client.get("/api/config/apps").json()["1"]["tencent"] == "tencent987654" + + def test_update_app(client, tmp_config): resp = client.put("/api/config/apps/1", json={"name": "改名App", "AppGuid": "test-guid"}) assert resp.status_code == 200