feat(路由): 重构未完成表单弹框逻辑并优化导航行为
将重复的未完成表单确认弹框逻辑提取到独立工具模块 使用location.replace替代href避免浏览器历史记录问题 优化取消操作后的跳转行为,删除cookie后跳转至首页
Showing
4 changed files
with
96 additions
and
41 deletions
| ... | @@ -9,9 +9,9 @@ import { createRouter, createWebHashHistory } from 'vue-router'; | ... | @@ -9,9 +9,9 @@ import { createRouter, createWebHashHistory } from 'vue-router'; |
| 9 | import RootRoute from './route.js'; | 9 | import RootRoute from './route.js'; |
| 10 | import asyncRoutesArr from "./mock/routes" | 10 | import asyncRoutesArr from "./mock/routes" |
| 11 | import generateRoutes from './utils/generateRoute' | 11 | import generateRoutes from './utils/generateRoute' |
| 12 | -import { showConfirmDialog, Loading } from "vant"; | 12 | +import { Loading } from "vant"; |
| 13 | import Cookies from 'js-cookie'; | 13 | import Cookies from 'js-cookie'; |
| 14 | -import { styleColor } from "@/constant.js"; | 14 | +import { showUnfinishedFormDialog } from '@/utils/dialogControl.js'; |
| 15 | import { getCycleListAPI } from '@/api/cycle'; | 15 | import { getCycleListAPI } from '@/api/cycle'; |
| 16 | 16 | ||
| 17 | // TAG: 路由配置表 | 17 | // TAG: 路由配置表 |
| ... | @@ -130,20 +130,17 @@ router.beforeEach((to, from, next) => { | ... | @@ -130,20 +130,17 @@ router.beforeEach((to, from, next) => { |
| 130 | if (to.query.page_type === 'add' || to.query.page_type === undefined) { | 130 | if (to.query.page_type === 'add' || to.query.page_type === undefined) { |
| 131 | const existingCookie = Cookies.get(to.query.code); | 131 | const existingCookie = Cookies.get(to.query.code); |
| 132 | if (existingCookie && to.query.force_back !== '1') { | 132 | if (existingCookie && to.query.force_back !== '1') { |
| 133 | - showConfirmDialog({ | 133 | + showUnfinishedFormDialog( |
| 134 | - title: '温馨提示', | 134 | + () => { |
| 135 | - message: '您还未完成的表单,是否继续?', | 135 | + // 用户选择继续,跳转到目标页面 |
| 136 | - confirmButtonColor: styleColor.baseColor, | ||
| 137 | - cancelButtonText: '删除', | ||
| 138 | - closeOnPopstate: false, | ||
| 139 | - }) | ||
| 140 | - .then(() => { | ||
| 141 | next(); | 136 | next(); |
| 142 | - }) | 137 | + }, |
| 143 | - .catch(() => { | 138 | + () => { |
| 139 | + // 用户选择删除,删除cookie并跳转 | ||
| 144 | Cookies.remove(to.query.code); | 140 | Cookies.remove(to.query.code); |
| 145 | next(); | 141 | next(); |
| 146 | - }); | 142 | + } |
| 143 | + ); | ||
| 147 | } else { | 144 | } else { |
| 148 | next(); | 145 | next(); |
| 149 | } | 146 | } |
| ... | @@ -181,21 +178,17 @@ router.beforeEach((to, from, next) => { | ... | @@ -181,21 +178,17 @@ router.beforeEach((to, from, next) => { |
| 181 | if (to.query.page_type === 'add' || to.query.page_type === undefined) { | 178 | if (to.query.page_type === 'add' || to.query.page_type === undefined) { |
| 182 | const existingCookie = Cookies.get(to.query.code); | 179 | const existingCookie = Cookies.get(to.query.code); |
| 183 | if (existingCookie && to.query.force_back !== '1') { | 180 | if (existingCookie && to.query.force_back !== '1') { |
| 184 | - // TAG: 只能在进入路由之前判断,不然很多组件数据不渲染 | 181 | + showUnfinishedFormDialog( |
| 185 | - showConfirmDialog({ | 182 | + () => { |
| 186 | - title: '温馨提示', | 183 | + // 用户选择继续,跳转到目标页面 |
| 187 | - message: '您还未完成的表单,是否继续?', | ||
| 188 | - confirmButtonColor: styleColor.baseColor, | ||
| 189 | - cancelButtonText: '删除', | ||
| 190 | - closeOnPopstate: false, | ||
| 191 | - }) | ||
| 192 | - .then(() => { // 通过后把数据绑定上去 | ||
| 193 | next(); | 184 | next(); |
| 194 | - }) | 185 | + }, |
| 195 | - .catch(() => { // 删除cookie | 186 | + () => { |
| 187 | + // 用户选择删除,删除cookie并跳转 | ||
| 196 | Cookies.remove(to.query.code); | 188 | Cookies.remove(to.query.code); |
| 197 | next(); | 189 | next(); |
| 198 | - }); | 190 | + } |
| 191 | + ); | ||
| 199 | } else { | 192 | } else { |
| 200 | next(); | 193 | next(); |
| 201 | } | 194 | } | ... | ... |
src/utils/dialogControl.js
0 → 100644
| 1 | +import { showConfirmDialog } from 'vant'; | ||
| 2 | +import { styleColor } from '@/constant.js'; | ||
| 3 | + | ||
| 4 | +// 弹框显示状态管理 | ||
| 5 | +const DIALOG_SHOWN_KEY = 'unfinished_form_dialog_shown'; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 检查弹框是否已经显示过 | ||
| 9 | + * @returns {boolean} 是否已显示过 | ||
| 10 | + */ | ||
| 11 | +export function hasDialogShown() { | ||
| 12 | + return sessionStorage.getItem(DIALOG_SHOWN_KEY) === 'true'; | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * 标记弹框已显示 | ||
| 17 | + */ | ||
| 18 | +export function markDialogShown() { | ||
| 19 | + sessionStorage.setItem(DIALOG_SHOWN_KEY, 'true'); | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * 重置弹框状态(用于新的会话) | ||
| 24 | + */ | ||
| 25 | +export function resetDialogState() { | ||
| 26 | + sessionStorage.removeItem(DIALOG_SHOWN_KEY); | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * 显示未完成表单确认弹框(带全局控制) | ||
| 31 | + * @param {Function} onConfirm - 确认回调 | ||
| 32 | + * @param {Function} onCancel - 取消回调 | ||
| 33 | + * @returns {Promise|null} 如果已显示过则返回null,否则返回弹框Promise | ||
| 34 | + */ | ||
| 35 | +export function showUnfinishedFormDialog(onConfirm, onCancel) { | ||
| 36 | + // 如果已经显示过,直接执行确认回调 | ||
| 37 | + if (hasDialogShown()) { | ||
| 38 | + if (onConfirm) { | ||
| 39 | + onConfirm(); | ||
| 40 | + } | ||
| 41 | + return null; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + // 标记为已显示 | ||
| 45 | + markDialogShown(); | ||
| 46 | + | ||
| 47 | + // 显示弹框 | ||
| 48 | + return showConfirmDialog({ | ||
| 49 | + title: '温馨提示', | ||
| 50 | + message: '您还未完成的表单,是否继续?', | ||
| 51 | + confirmButtonColor: styleColor.baseColor, | ||
| 52 | + cancelButtonText: '删除', | ||
| 53 | + closeOnPopstate: false, | ||
| 54 | + }) | ||
| 55 | + .then(() => { | ||
| 56 | + if (onConfirm) { | ||
| 57 | + onConfirm(); | ||
| 58 | + } | ||
| 59 | + }) | ||
| 60 | + .catch(() => { | ||
| 61 | + if (onCancel) { | ||
| 62 | + onCancel(); | ||
| 63 | + } | ||
| 64 | + }); | ||
| 65 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -25,8 +25,10 @@ onMounted(() => { | ... | @@ -25,8 +25,10 @@ onMounted(() => { |
| 25 | let raw_url = encodeURIComponent(location.origin + location.pathname + $route.query.href); // 未授权的地址 | 25 | let raw_url = encodeURIComponent(location.origin + location.pathname + $route.query.href); // 未授权的地址 |
| 26 | // TAG: 开发环境测试数据 | 26 | // TAG: 开发环境测试数据 |
| 27 | const short_url = `/srv/?f=custom_form&a=openid&res=${raw_url}&form_code=${$route.query.code}`; | 27 | const short_url = `/srv/?f=custom_form&a=openid&res=${raw_url}&form_code=${$route.query.code}`; |
| 28 | - location.href = import.meta.env.DEV | 28 | + // 使用 replace 方法替代 href,避免在浏览器历史中留下记录 |
| 29 | + // 这样用户点击后退按钮时不会回到授权页面 | ||
| 30 | + window.location.replace(import.meta.env.DEV | ||
| 29 | ? `${short_url}&openid=${import.meta.env.VITE_OPENID}` | 31 | ? `${short_url}&openid=${import.meta.env.VITE_OPENID}` |
| 30 | - : `${short_url}`; | 32 | + : `${short_url}`); |
| 31 | }) | 33 | }) |
| 32 | </script> | 34 | </script> | ... | ... |
| ... | @@ -39,7 +39,7 @@ import { ref, onMounted, nextTick, onUnmounted } from 'vue'; | ... | @@ -39,7 +39,7 @@ import { ref, onMounted, nextTick, onUnmounted } from 'vue'; |
| 39 | import { useRouter, useRoute } from 'vue-router'; | 39 | import { useRouter, useRoute } from 'vue-router'; |
| 40 | import { getCycleListAPI } from '@/api/cycle'; | 40 | import { getCycleListAPI } from '@/api/cycle'; |
| 41 | import { styleColor } from '@/constant.js'; | 41 | import { styleColor } from '@/constant.js'; |
| 42 | -import { showConfirmDialog } from 'vant'; | 42 | +import { showUnfinishedFormDialog } from '@/utils/dialogControl.js'; |
| 43 | import Cookies from 'js-cookie'; | 43 | import Cookies from 'js-cookie'; |
| 44 | 44 | ||
| 45 | const $router = useRouter(); | 45 | const $router = useRouter(); |
| ... | @@ -216,22 +216,17 @@ const checkUnfinishedForm = (route) => { | ... | @@ -216,22 +216,17 @@ const checkUnfinishedForm = (route) => { |
| 216 | const existingCookie = Cookies.get(route.query.code); | 216 | const existingCookie = Cookies.get(route.query.code); |
| 217 | if (existingCookie && route.query.force_back !== '1') { | 217 | if (existingCookie && route.query.force_back !== '1') { |
| 218 | // 显示确认对话框 | 218 | // 显示确认对话框 |
| 219 | - showConfirmDialog({ | 219 | + showUnfinishedFormDialog( |
| 220 | - title: '温馨提示', | 220 | + () => { |
| 221 | - message: '您还未完成的表单,是否继续?', | ||
| 222 | - confirmButtonColor: styleColor.baseColor, | ||
| 223 | - cancelButtonText: '删除', | ||
| 224 | - closeOnPopstate: false, | ||
| 225 | - }) | ||
| 226 | - .then(() => { | ||
| 227 | // 用户选择继续,跳转到目标页面 | 221 | // 用户选择继续,跳转到目标页面 |
| 228 | $router.replace(route); | 222 | $router.replace(route); |
| 229 | - }) | 223 | + }, |
| 230 | - .catch(() => { | 224 | + () => { |
| 231 | - // 用户选择删除,清除cookie后跳转 | 225 | + // 用户选择删除,删除cookie并跳转到首页 |
| 232 | Cookies.remove(route.query.code); | 226 | Cookies.remove(route.query.code); |
| 233 | - $router.replace(route); | 227 | + $router.replace({ path: '/', query: { x_cycle: selectedCycle.value, cycle_selected: '1' } }); |
| 234 | - }); | 228 | + } |
| 229 | + ); | ||
| 235 | } else { | 230 | } else { |
| 236 | // 没有未完成的表单,直接跳转 | 231 | // 没有未完成的表单,直接跳转 |
| 237 | $router.replace(route); | 232 | $router.replace(route); | ... | ... |
-
Please register or login to post a comment