hookehuyr

feat(路由): 重构未完成表单弹框逻辑并优化导航行为

将重复的未完成表单确认弹框逻辑提取到独立工具模块
使用location.replace替代href避免浏览器历史记录问题
优化取消操作后的跳转行为,删除cookie后跳转至首页
...@@ -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 }
......
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);
......