diff --git a/backend/routers/config.py b/backend/routers/config.py
index c18a33a..8ee8562 100644
--- a/backend/routers/config.py
+++ b/backend/routers/config.py
@@ -2,6 +2,7 @@
import asyncio
import json
import os
+import re
import shutil
import zipfile
from datetime import datetime
@@ -501,19 +502,18 @@ async def get_versions():
@router.put("/versions")
async def update_versions(data: dict):
- """更新 App_Ver 和 Build_Ver"""
+ """更新 App_Ver,并将 Build_Ver 重置为对应的 .0。"""
app_ver = data.get("app_ver", "").strip()
- build_ver = data.get("build_ver", "").strip()
+ if not re.fullmatch(r"\d+\.\d+\.\d+", app_ver):
+ raise HTTPException(status_code=400, detail="App_Ver 必须为主版本.次版本.修订号,例如 2.196.0")
- if not app_ver or not build_ver:
- raise HTTPException(status_code=400, detail="版本号不能为空")
-
- config = load_config()
- config["versions"] = {
- "app_ver": app_ver,
- "build_ver": build_ver,
- }
+ build_ver = f"{app_ver}.0"
async with _config_lock:
+ config = load_config()
+ config["versions"] = {
+ "app_ver": app_ver,
+ "build_ver": build_ver,
+ }
save_config(config)
return {"message": "版本号已更新", "app_ver": app_ver, "build_ver": build_ver}
diff --git a/frontend/src/__tests__/ConfigView.test.js b/frontend/src/__tests__/ConfigView.test.js
index 5c8dad1..a0cd825 100644
--- a/frontend/src/__tests__/ConfigView.test.js
+++ b/frontend/src/__tests__/ConfigView.test.js
@@ -181,6 +181,6 @@ describe('ConfigView.vue', () => {
expect(wrapper.text()).toContain('应用版本号')
expect(wrapper.text()).not.toContain('打包参数')
- expect(wrapper.findAll('input').length).toBe(2)
+ expect(wrapper.findAll('input').length).toBe(1)
})
})
diff --git a/frontend/src/views/ConfigView.vue b/frontend/src/views/ConfigView.vue
index c10ce06..35052ae 100644
--- a/frontend/src/views/ConfigView.vue
+++ b/frontend/src/views/ConfigView.vue
@@ -273,11 +273,7 @@
格式:主版本.次版本.修订号
-
+ 保存后 Build_Ver 将自动重置为 App_Ver.0;App Store 打包时构建号自动 +1。
@@ -1037,7 +1033,7 @@ const saveVersions = async () => {
const res = await authFetch('/api/config/versions', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(versions.value),
+ body: JSON.stringify({ app_ver: versions.value.app_ver }),
})
if (res.ok) {
const data = await res.json()
diff --git a/tests/test_api_config.py b/tests/test_api_config.py
index d7dbb49..ccfec86 100644
--- a/tests/test_api_config.py
+++ b/tests/test_api_config.py
@@ -144,3 +144,19 @@ def test_update_build_settings(client, tmp_config):
resp = client.put("/api/config/build", json={"max_concurrent_builds": 4})
assert resp.status_code == 200
assert client.get("/api/config/build").json()["max_concurrent_builds"] == 4
+
+
+# ---- Versions ----
+
+def test_update_versions_resets_build_number(client, tmp_config):
+ resp = client.put("/api/config/versions", json={"app_ver": "2.196.0"})
+ assert resp.status_code == 200
+ assert resp.json()["app_ver"] == "2.196.0"
+ assert resp.json()["build_ver"] == "2.196.0.0"
+ assert client.get("/api/config/versions").json()["build_ver"] == "2.196.0.0"
+
+
+def test_update_versions_rejects_invalid_app_version(client, tmp_config):
+ resp = client.put("/api/config/versions", json={"app_ver": "2.196"})
+ assert resp.status_code == 400
+ assert "App_Ver" in resp.json()["detail"]
diff --git a/tests/test_security.py b/tests/test_security.py
index 0143e8c..32f2ca6 100644
--- a/tests/test_security.py
+++ b/tests/test_security.py
@@ -56,9 +56,9 @@ def test_config_routes_limit_regular_users_to_apps_and_versions(client, tmp_conf
assert client.get("/api/config/apps", headers=headers).status_code == 200
assert client.post("/api/config/apps", json={"name": "普通用户 App"}, headers=headers).status_code == 200
assert client.get("/api/config/versions", headers=headers).status_code == 200
- assert client.put("/api/config/versions", json={
- "app_ver": "2.196.0", "build_ver": "2.196.0.0",
- }, headers=headers).status_code == 200
+ versions = client.put("/api/config/versions", json={"app_ver": "2.196.0"}, headers=headers)
+ assert versions.status_code == 200
+ assert versions.json()["build_ver"] == "2.196.0.0"
assert client.get("/api/config", headers=headers).status_code == 403
assert client.get("/api/config/servers", headers=headers).status_code == 403
assert client.put("/api/config/build", json={"max_concurrent_builds": 1}, headers=headers).status_code == 403