fix(theme): 切换前端主题后重置到首页,避免路由 404 (#5612)
* fix(theme): 切换前端主题后重置到首页,避免路由 404 经典前端与新版前端的路由路径不同,切换主题后停留在原路径会导致 404: - 经典前端切换到新版前端时跳转首页,不再原地刷新当前路径 - 新版前端保存时若前端主题发生变化,保存成功后跳转首页 Fixes #4947 * fix: 更新前端切换提示信息,修正页面跳转逻辑
This commit is contained in:
+5
-2
@@ -301,9 +301,12 @@ const OtherSetting = () => {
|
||||
showError(message);
|
||||
return;
|
||||
}
|
||||
showSuccess(t('已切换到新版前端,正在刷新页面'));
|
||||
showSuccess(t('已切换到新版前端,正在跳转首页'));
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
// 新版前端的路由与经典前端不同,原地刷新当前路径会 404,
|
||||
// 因此切换后重置到首页,由后端按新主题返回对应前端。
|
||||
// 使用 replace 避免在历史中留下已失效的路由,防止返回时再次 404。
|
||||
window.location.replace('/');
|
||||
}, 600);
|
||||
} catch (error) {
|
||||
console.error('切换新版前端失败', error);
|
||||
|
||||
Vendored
+1
-1
@@ -1361,7 +1361,7 @@
|
||||
"已发起支付": "Payment initiated",
|
||||
"已发送到 Fluent": "Sent to Fluent",
|
||||
"已取消 Passkey 注册": "Passkey registration cancelled",
|
||||
"已切换到新版前端,正在刷新页面": "Switched to the new frontend, refreshing page",
|
||||
"已切换到新版前端,正在跳转首页": "Switched to the new frontend, redirecting to home",
|
||||
"已同步到渠道": "Synced to Channel",
|
||||
"已启用": "Enabled",
|
||||
"已启用 Passkey,无需密码即可登录": "Passkey enabled, login without password",
|
||||
|
||||
Vendored
+1
-1
@@ -1362,7 +1362,7 @@
|
||||
"已发起支付": "Paiement initié",
|
||||
"已发送到 Fluent": "Envoyé à Fluent",
|
||||
"已取消 Passkey 注册": "Enregistrement du Passkey annulé",
|
||||
"已切换到新版前端,正在刷新页面": "Passage au nouveau frontend effectué, actualisation de la page",
|
||||
"已切换到新版前端,正在跳转首页": "Passage au nouveau frontend effectué, redirection vers l'accueil",
|
||||
"已同步到渠道": "Synced to Channel",
|
||||
"已启用": "Activé",
|
||||
"已启用 Passkey,无需密码即可登录": "Passkey activé. Connexion sans mot de passe disponible.",
|
||||
|
||||
Vendored
+1
-1
@@ -1341,7 +1341,7 @@
|
||||
"已发起支付": "支払いを開始しました",
|
||||
"已发送到 Fluent": "Fluentに送信されました",
|
||||
"已取消 Passkey 注册": "Passkeyの登録がキャンセルされました",
|
||||
"已切换到新版前端,正在刷新页面": "新しいフロントエンドに切り替えました。ページを更新しています",
|
||||
"已切换到新版前端,正在跳转首页": "新しいフロントエンドに切り替えました。ホームに移動しています",
|
||||
"已同步到渠道": "Synced to Channel",
|
||||
"已启用": "有効",
|
||||
"已启用 Passkey,无需密码即可登录": "Passkeyが有効になり、パスワードなしでログインできます",
|
||||
|
||||
Vendored
+1
-1
@@ -1375,7 +1375,7 @@
|
||||
"已发起支付": "Оплата инициирована",
|
||||
"已发送到 Fluent": "Отправлено в Fluent",
|
||||
"已取消 Passkey 注册": "Регистрация Passkey отменена",
|
||||
"已切换到新版前端,正在刷新页面": "Переключено на новый интерфейс, страница обновляется",
|
||||
"已切换到新版前端,正在跳转首页": "Переключено на новый интерфейс, переход на главную",
|
||||
"已同步到渠道": "Synced to Channel",
|
||||
"已启用": "Включено",
|
||||
"已启用 Passkey,无需密码即可登录": "Passkey включен, вход без пароля",
|
||||
|
||||
Vendored
+1
-1
@@ -1342,7 +1342,7 @@
|
||||
"已发起支付": "Đã khởi tạo thanh toán",
|
||||
"已发送到 Fluent": "Đã gửi đến Fluent",
|
||||
"已取消 Passkey 注册": "Đã hủy đăng ký Passkey",
|
||||
"已切换到新版前端,正在刷新页面": "Đã chuyển sang frontend mới, đang làm mới trang",
|
||||
"已切换到新版前端,正在跳转首页": "Đã chuyển sang frontend mới, đang chuyển đến trang chủ",
|
||||
"已同步到渠道": "Synced to Channel",
|
||||
"已启用": "Đã bật",
|
||||
"已启用 Passkey,无需密码即可登录": "Đã bật Passkey, đăng nhập không cần mật khẩu",
|
||||
|
||||
+1
-1
@@ -1311,7 +1311,7 @@
|
||||
"已停止批量测试": "已停止批量测试",
|
||||
"已关闭后续提醒": "已关闭后续提醒",
|
||||
"已分配内存": "已分配内存",
|
||||
"已切换到新版前端,正在刷新页面": "已切换到新版前端,正在刷新页面",
|
||||
"已切换到新版前端,正在跳转首页": "已切换到新版前端,正在跳转首页",
|
||||
"已切换为Assistant角色": "已切换为Assistant角色",
|
||||
"已切换为System角色": "已切换为System角色",
|
||||
"已切换至最优倍率视图,每个模型使用其最低倍率分组": "已切换至最优倍率视图,每个模型使用其最低倍率分组",
|
||||
|
||||
+1
-1
@@ -1338,7 +1338,7 @@
|
||||
"已发起支付": "已發起支付",
|
||||
"已发送到 Fluent": "已發送到 Fluent",
|
||||
"已取消 Passkey 注册": "已取消 Passkey 註冊",
|
||||
"已切换到新版前端,正在刷新页面": "已切換到新版前端,正在重新整理頁面",
|
||||
"已切换到新版前端,正在跳转首页": "已切換到新版前端,正在跳轉首頁",
|
||||
"已同步到渠道": "已同步到管道",
|
||||
"已启用": "已啟用",
|
||||
"已启用 Passkey,无需密码即可登录": "已啟用 Passkey,無需密碼即可登錄",
|
||||
|
||||
Vendored
+1
-1
@@ -909,7 +909,7 @@
|
||||
"已删除消息及其回复": "已删除消息及其回复",
|
||||
"已发送到 Fluent": "已发送到 Fluent",
|
||||
"已取消 Passkey 注册": "已取消 Passkey 注册",
|
||||
"已切换到新版前端,正在刷新页面": "已切换到新版前端,正在刷新页面",
|
||||
"已切换到新版前端,正在跳转首页": "已切换到新版前端,正在跳转首页",
|
||||
"已同步到渠道": "已同步到渠道",
|
||||
"已启用": "已启用",
|
||||
"已启用 Passkey,无需密码即可登录": "已启用 Passkey,无需密码即可登录",
|
||||
|
||||
@@ -126,15 +126,48 @@ export function SystemInfoSection({ defaultValues }: SystemInfoSectionProps) {
|
||||
>,
|
||||
defaultValues: normalizedDefaults,
|
||||
onSubmit: async (_data, changedFields) => {
|
||||
for (const [key, value] of Object.entries(changedFields)) {
|
||||
// 主题切换会改变后端返回的前端产物,需放到最后处理:先更新其余设置项,
|
||||
// 仅当它们全部成功后才提交主题切换,避免其它设置失败时就切换了主题,
|
||||
// 导致用户停留或刷新到另一套前端不存在的路由而 404。
|
||||
const entries = Object.entries(changedFields)
|
||||
const themeEntry = entries.find(([key]) => key === 'theme.frontend')
|
||||
const otherEntries = entries.filter(([key]) => key !== 'theme.frontend')
|
||||
|
||||
let allSucceeded = true
|
||||
for (const [key, value] of otherEntries) {
|
||||
let v = normalizeValue(value)
|
||||
if (key === 'ServerAddress') {
|
||||
v = v.replace(/\/+$/, '')
|
||||
}
|
||||
await updateOption.mutateAsync({
|
||||
const res = await updateOption.mutateAsync({
|
||||
key,
|
||||
value: v,
|
||||
})
|
||||
if (!res.success) {
|
||||
allSucceeded = false
|
||||
}
|
||||
}
|
||||
if (themeEntry && !allSucceeded) {
|
||||
// Theme was not submitted; keep form state consistent with backend.
|
||||
_data.theme.frontend = normalizedDefaults.theme.frontend
|
||||
return
|
||||
}
|
||||
if (themeEntry && allSucceeded) {
|
||||
const res = await updateOption.mutateAsync({
|
||||
key: themeEntry[0],
|
||||
value: normalizeValue(themeEntry[1]),
|
||||
})
|
||||
if (res.success) {
|
||||
// 当前路由在另一套前端中并不存在,主题切换成功后重置到首页以避免 404。
|
||||
// 延时用于让表单脏状态先清除(移除 beforeunload 拦截)并展示成功提示后再刷新;
|
||||
// 使用 replace 让已失效的路由不进入历史,防止返回按钮再次触发 404。
|
||||
setTimeout(() => {
|
||||
window.location.replace('/')
|
||||
}, 600)
|
||||
} else {
|
||||
// Theme update failed; revert to the last saved value.
|
||||
_data.theme.frontend = normalizedDefaults.theme.frontend
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user