Commit c0e42bfb by peakchao Committed by GitHub

fix(theme): 切换前端主题后重置到首页,避免路由 404 (#5612)

* fix(theme): 切换前端主题后重置到首页,避免路由 404
经典前端与新版前端的路由路径不同,切换主题后停留在原路径会导致 404:
- 经典前端切换到新版前端时跳转首页,不再原地刷新当前路径
- 新版前端保存时若前端主题发生变化,保存成功后跳转首页

Fixes #4947

* fix: 更新前端切换提示信息,修正页面跳转逻辑
parent 35074345
...@@ -301,9 +301,12 @@ const OtherSetting = () => { ...@@ -301,9 +301,12 @@ const OtherSetting = () => {
showError(message); showError(message);
return; return;
} }
showSuccess(t('已切换到新版前端,正在刷新页面')); showSuccess(t('已切换到新版前端,正在跳转首页'));
setTimeout(() => { setTimeout(() => {
window.location.reload(); // 新版前端的路由与经典前端不同,原地刷新当前路径会 404,
// 因此切换后重置到首页,由后端按新主题返回对应前端。
// 使用 replace 避免在历史中留下已失效的路由,防止返回时再次 404。
window.location.replace('/');
}, 600); }, 600);
} catch (error) { } catch (error) {
console.error('切换新版前端失败', error); console.error('切换新版前端失败', error);
......
...@@ -1361,7 +1361,7 @@ ...@@ -1361,7 +1361,7 @@
"已发起支付": "Payment initiated", "已发起支付": "Payment initiated",
"已发送到 Fluent": "Sent to Fluent", "已发送到 Fluent": "Sent to Fluent",
"已取消 Passkey 注册": "Passkey registration cancelled", "已取消 Passkey 注册": "Passkey registration cancelled",
"已切换到新版前端,正在刷新页面": "Switched to the new frontend, refreshing page", "已切换到新版前端,正在跳转首页": "Switched to the new frontend, redirecting to home",
"已同步到渠道": "Synced to Channel", "已同步到渠道": "Synced to Channel",
"已启用": "Enabled", "已启用": "Enabled",
"已启用 Passkey,无需密码即可登录": "Passkey enabled, login without password", "已启用 Passkey,无需密码即可登录": "Passkey enabled, login without password",
......
...@@ -1362,7 +1362,7 @@ ...@@ -1362,7 +1362,7 @@
"已发起支付": "Paiement initié", "已发起支付": "Paiement initié",
"已发送到 Fluent": "Envoyé à Fluent", "已发送到 Fluent": "Envoyé à Fluent",
"已取消 Passkey 注册": "Enregistrement du Passkey annulé", "已取消 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", "已同步到渠道": "Synced to Channel",
"已启用": "Activé", "已启用": "Activé",
"已启用 Passkey,无需密码即可登录": "Passkey activé. Connexion sans mot de passe disponible.", "已启用 Passkey,无需密码即可登录": "Passkey activé. Connexion sans mot de passe disponible.",
......
...@@ -1341,7 +1341,7 @@ ...@@ -1341,7 +1341,7 @@
"已发起支付": "支払いを開始しました", "已发起支付": "支払いを開始しました",
"已发送到 Fluent": "Fluentに送信されました", "已发送到 Fluent": "Fluentに送信されました",
"已取消 Passkey 注册": "Passkeyの登録がキャンセルされました", "已取消 Passkey 注册": "Passkeyの登録がキャンセルされました",
"已切换到新版前端,正在刷新页面": "新しいフロントエンドに切り替えました。ページを更新しています", "已切换到新版前端,正在跳转首页": "新しいフロントエンドに切り替えました。ホームに移動しています",
"已同步到渠道": "Synced to Channel", "已同步到渠道": "Synced to Channel",
"已启用": "有効", "已启用": "有効",
"已启用 Passkey,无需密码即可登录": "Passkeyが有効になり、パスワードなしでログインできます", "已启用 Passkey,无需密码即可登录": "Passkeyが有効になり、パスワードなしでログインできます",
......
...@@ -1375,7 +1375,7 @@ ...@@ -1375,7 +1375,7 @@
"已发起支付": "Оплата инициирована", "已发起支付": "Оплата инициирована",
"已发送到 Fluent": "Отправлено в Fluent", "已发送到 Fluent": "Отправлено в Fluent",
"已取消 Passkey 注册": "Регистрация Passkey отменена", "已取消 Passkey 注册": "Регистрация Passkey отменена",
"已切换到新版前端,正在刷新页面": "Переключено на новый интерфейс, страница обновляется", "已切换到新版前端,正在跳转首页": "Переключено на новый интерфейс, переход на главную",
"已同步到渠道": "Synced to Channel", "已同步到渠道": "Synced to Channel",
"已启用": "Включено", "已启用": "Включено",
"已启用 Passkey,无需密码即可登录": "Passkey включен, вход без пароля", "已启用 Passkey,无需密码即可登录": "Passkey включен, вход без пароля",
......
...@@ -1342,7 +1342,7 @@ ...@@ -1342,7 +1342,7 @@
"已发起支付": "Đã khởi tạo thanh toán", "已发起支付": "Đã khởi tạo thanh toán",
"已发送到 Fluent": "Đã gửi đến Fluent", "已发送到 Fluent": "Đã gửi đến Fluent",
"已取消 Passkey 注册": "Đã hủy đăng ký Passkey", "已取消 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", "已同步到渠道": "Synced to Channel",
"已启用": "Đã bật", "已启用": "Đã bật",
"已启用 Passkey,无需密码即可登录": "Đã bật Passkey, đăng nhập không cần mật khẩu", "已启用 Passkey,无需密码即可登录": "Đã bật Passkey, đăng nhập không cần mật khẩu",
......
...@@ -1311,7 +1311,7 @@ ...@@ -1311,7 +1311,7 @@
"已停止批量测试": "已停止批量测试", "已停止批量测试": "已停止批量测试",
"已关闭后续提醒": "已关闭后续提醒", "已关闭后续提醒": "已关闭后续提醒",
"已分配内存": "已分配内存", "已分配内存": "已分配内存",
"已切换到新版前端,正在刷新页面": "已切换到新版前端,正在刷新页面", "已切换到新版前端,正在跳转首页": "已切换到新版前端,正在跳转首页",
"已切换为Assistant角色": "已切换为Assistant角色", "已切换为Assistant角色": "已切换为Assistant角色",
"已切换为System角色": "已切换为System角色", "已切换为System角色": "已切换为System角色",
"已切换至最优倍率视图,每个模型使用其最低倍率分组": "已切换至最优倍率视图,每个模型使用其最低倍率分组", "已切换至最优倍率视图,每个模型使用其最低倍率分组": "已切换至最优倍率视图,每个模型使用其最低倍率分组",
......
...@@ -1338,7 +1338,7 @@ ...@@ -1338,7 +1338,7 @@
"已发起支付": "已發起支付", "已发起支付": "已發起支付",
"已发送到 Fluent": "已發送到 Fluent", "已发送到 Fluent": "已發送到 Fluent",
"已取消 Passkey 注册": "已取消 Passkey 註冊", "已取消 Passkey 注册": "已取消 Passkey 註冊",
"已切换到新版前端,正在刷新页面": "已切換到新版前端,正在重新整理頁面", "已切换到新版前端,正在跳转首页": "已切換到新版前端,正在跳轉首頁",
"已同步到渠道": "已同步到管道", "已同步到渠道": "已同步到管道",
"已启用": "已啟用", "已启用": "已啟用",
"已启用 Passkey,无需密码即可登录": "已啟用 Passkey,無需密碼即可登錄", "已启用 Passkey,无需密码即可登录": "已啟用 Passkey,無需密碼即可登錄",
......
...@@ -909,7 +909,7 @@ ...@@ -909,7 +909,7 @@
"已删除消息及其回复": "已删除消息及其回复", "已删除消息及其回复": "已删除消息及其回复",
"已发送到 Fluent": "已发送到 Fluent", "已发送到 Fluent": "已发送到 Fluent",
"已取消 Passkey 注册": "已取消 Passkey 注册", "已取消 Passkey 注册": "已取消 Passkey 注册",
"已切换到新版前端,正在刷新页面": "已切换到新版前端,正在刷新页面", "已切换到新版前端,正在跳转首页": "已切换到新版前端,正在跳转首页",
"已同步到渠道": "已同步到渠道", "已同步到渠道": "已同步到渠道",
"已启用": "已启用", "已启用": "已启用",
"已启用 Passkey,无需密码即可登录": "已启用 Passkey,无需密码即可登录", "已启用 Passkey,无需密码即可登录": "已启用 Passkey,无需密码即可登录",
......
...@@ -126,15 +126,48 @@ export function SystemInfoSection({ defaultValues }: SystemInfoSectionProps) { ...@@ -126,15 +126,48 @@ export function SystemInfoSection({ defaultValues }: SystemInfoSectionProps) {
>, >,
defaultValues: normalizedDefaults, defaultValues: normalizedDefaults,
onSubmit: async (_data, changedFields) => { 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) let v = normalizeValue(value)
if (key === 'ServerAddress') { if (key === 'ServerAddress') {
v = v.replace(/\/+$/, '') v = v.replace(/\/+$/, '')
} }
await updateOption.mutateAsync({ const res = await updateOption.mutateAsync({
key, key,
value: v, 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
}
} }
}, },
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment