hookehuyr

feat(router): 优化周期选择和未完成表单检查逻辑

重构路由守卫中的周期选择检查逻辑,改为同步+异步结合的方式
添加未完成表单检查功能,在跳转前提示用户继续或删除
将表单检查逻辑提取为公共函数 checkUnfinishedForm
1 /* 1 /*
2 * @Date: 2022-05-26 13:57:28 2 * @Date: 2022-05-26 13:57:28
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-09-08 15:52:35 4 + * @LastEditTime: 2025-09-09 10:29:55
5 * @FilePath: /data-table/src/router.js 5 * @FilePath: /data-table/src/router.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -43,40 +43,41 @@ const router = createRouter({ ...@@ -43,40 +43,41 @@ const router = createRouter({
43 * @param {Object} to 目标路由 43 * @param {Object} to 目标路由
44 * @returns {Promise<boolean>} 是否需要周期选择 44 * @returns {Promise<boolean>} 是否需要周期选择
45 */ 45 */
46 -const checkCycleSelection = async (to) => { 46 +const checkCycleSelection = (to) => {
47 // 如果已经在周期选择页面,不需要再检查 47 // 如果已经在周期选择页面,不需要再检查
48 if (to.path === '/cycle-selection') { 48 if (to.path === '/cycle-selection') {
49 - return false; 49 + return Promise.resolve(false);
50 } 50 }
51 - 51 +
52 // 只有在page_type=add或者没有page_type参数时才进行周期判断 52 // 只有在page_type=add或者没有page_type参数时才进行周期判断
53 if (to.query.page_type && to.query.page_type !== 'add') { 53 if (to.query.page_type && to.query.page_type !== 'add') {
54 - return false; 54 + return Promise.resolve(false);
55 } 55 }
56 - 56 +
57 // 如果没有表单代码,不需要周期选择 57 // 如果没有表单代码,不需要周期选择
58 if (!to.query.code) { 58 if (!to.query.code) {
59 - return false; 59 + return Promise.resolve(false);
60 } 60 }
61 - 61 +
62 // 如果用户已经选择过周期,不需要再选择 62 // 如果用户已经选择过周期,不需要再选择
63 if (to.query.cycle_selected === '1') { 63 if (to.query.cycle_selected === '1') {
64 - return false; 64 + return Promise.resolve(false);
65 } 65 }
66 - 66 +
67 // 如果是预览模式,不需要周期选择 67 // 如果是预览模式,不需要周期选择
68 if (to.query.model === 'preview') { 68 if (to.query.model === 'preview') {
69 - return false; 69 + return Promise.resolve(false);
70 - }
71 -
72 - try {
73 - const { data } = await getCycleListAPI({ form_code: to.query.code });
74 - // 如果需要周期选择且有周期列表
75 - return data.is_cycle && data.cycle_list && data.cycle_list.length > 0;
76 - } catch (error) {
77 - console.error('检查周期选择失败:', error);
78 - return false;
79 } 70 }
71 +
72 + return getCycleListAPI({ form_code: to.query.code })
73 + .then(({ data }) => {
74 + // 如果需要周期选择且有周期列表
75 + return data.is_cycle && data.cycle_list && data.cycle_list.length > 0;
76 + })
77 + .catch(error => {
78 + console.error('检查周期选择失败:', error);
79 + return false;
80 + });
80 }; 81 };
81 82
82 router.beforeEach((to, from, next) => { 83 router.beforeEach((to, from, next) => {
...@@ -93,7 +94,32 @@ router.beforeEach((to, from, next) => { ...@@ -93,7 +94,32 @@ router.beforeEach((to, from, next) => {
93 next({ ...to.redirectedFrom, replace: true }); 94 next({ ...to.redirectedFrom, replace: true });
94 }, 1000); 95 }, 1000);
95 } else { 96 } else {
96 - // 检查是否需要周期选择 - 使用Promise.then避免async/await 97 + // 先进行同步检查,避免异步问题
98 + // 如果已经在周期选择页面,直接通过
99 + if (to.path === '/cycle-selection') {
100 + next();
101 + return;
102 + }
103 +
104 + // 如果用户已经选择过周期,直接通过
105 + if (to.query.cycle_selected === '1') {
106 + next();
107 + return;
108 + }
109 +
110 + // 如果不是新增状态或预览模式,直接通过
111 + if ((to.query.page_type && to.query.page_type !== 'add') || to.query.model === 'preview') {
112 + next();
113 + return;
114 + }
115 +
116 + // 如果没有表单代码,直接通过
117 + if (!to.query.code) {
118 + next();
119 + return;
120 + }
121 +
122 + // 异步检查周期选择
97 checkCycleSelection(to).then(needsCycleSelection => { 123 checkCycleSelection(to).then(needsCycleSelection => {
98 if (needsCycleSelection) { 124 if (needsCycleSelection) {
99 // 保存目标路由到sessionStorage 125 // 保存目标路由到sessionStorage
...@@ -102,16 +128,16 @@ router.beforeEach((to, from, next) => { ...@@ -102,16 +128,16 @@ router.beforeEach((to, from, next) => {
102 query: to.query, 128 query: to.query,
103 params: to.params 129 params: to.params
104 })); 130 }));
105 - // 跳转到周期选择页面,保留所有原始参数 131 + // 直接跳转,不使用next
106 - next({ 132 + router.push({
107 path: '/cycle-selection', 133 path: '/cycle-selection',
108 query: to.query // 保留所有原始查询参数 134 query: to.query // 保留所有原始查询参数
109 }); 135 });
110 - return; 136 + return; // 有周期选择需求时,直接返回,不执行后续表单检查
111 } 137 }
112 - 138 +
113 - // 继续原有的表单检查逻辑 139 + // 只有在不需要周期选择时,才执行表单检查逻辑
114 - if (to.query.page_type === 'add' || to.query.page_type === undefined) { // 表单为新增状态, 检查是否有未完成的表单信息 140 + if (to.query.page_type === 'add' || to.query.page_type === undefined) {
115 const existingCookie = Cookies.get(to.query.code); 141 const existingCookie = Cookies.get(to.query.code);
116 if (existingCookie && to.query.force_back !== '1') { 142 if (existingCookie && to.query.force_back !== '1') {
117 // TAG: 只能在进入路由之前判断,不然很多组件数据不渲染 143 // TAG: 只能在进入路由之前判断,不然很多组件数据不渲染
...@@ -133,15 +159,14 @@ router.beforeEach((to, from, next) => { ...@@ -133,15 +159,14 @@ router.beforeEach((to, from, next) => {
133 next(); 159 next();
134 } 160 }
135 } else { 161 } else {
136 - next() 162 + next();
137 } 163 }
138 }).catch(error => { 164 }).catch(error => {
139 console.error('周期选择检查失败:', error); 165 console.error('周期选择检查失败:', error);
140 - // 出错时继续正常流程 166 + // 检查失败时,继续执行表单检查逻辑
141 - if (to.query.page_type === 'add' || to.query.page_type === undefined) { // 表单为新增状态, 检查是否有未完成的表单信息 167 + if (to.query.page_type === 'add' || to.query.page_type === undefined) {
142 const existingCookie = Cookies.get(to.query.code); 168 const existingCookie = Cookies.get(to.query.code);
143 if (existingCookie && to.query.force_back !== '1') { 169 if (existingCookie && to.query.force_back !== '1') {
144 - // TAG: 只能在进入路由之前判断,不然很多组件数据不渲染
145 showConfirmDialog({ 170 showConfirmDialog({
146 title: '温馨提示', 171 title: '温馨提示',
147 message: '您还未完成的表单,是否继续?', 172 message: '您还未完成的表单,是否继续?',
...@@ -149,10 +174,10 @@ router.beforeEach((to, from, next) => { ...@@ -149,10 +174,10 @@ router.beforeEach((to, from, next) => {
149 cancelButtonText: '删除', 174 cancelButtonText: '删除',
150 closeOnPopstate: false, 175 closeOnPopstate: false,
151 }) 176 })
152 - .then(() => { // 通过后把数据绑定上去 177 + .then(() => {
153 next(); 178 next();
154 }) 179 })
155 - .catch(() => { // 删除cookie 180 + .catch(() => {
156 Cookies.remove(to.query.code); 181 Cookies.remove(to.query.code);
157 next(); 182 next();
158 }); 183 });
...@@ -160,7 +185,7 @@ router.beforeEach((to, from, next) => { ...@@ -160,7 +185,7 @@ router.beforeEach((to, from, next) => {
160 next(); 185 next();
161 } 186 }
162 } else { 187 } else {
163 - next() 188 + next();
164 } 189 }
165 }); 190 });
166 } 191 }
......
...@@ -38,6 +38,8 @@ import { ref, onMounted, nextTick } from 'vue'; ...@@ -38,6 +38,8 @@ import { ref, onMounted, nextTick } from 'vue';
38 import { useRouter, useRoute } from 'vue-router'; 38 import { useRouter, useRoute } from 'vue-router';
39 import { getCycleListAPI } from '@/api/cycle'; 39 import { getCycleListAPI } from '@/api/cycle';
40 import { styleColor } from '@/constant.js'; 40 import { styleColor } from '@/constant.js';
41 +import { showConfirmDialog } from 'vant';
42 +import Cookies from 'js-cookie';
41 43
42 const $router = useRouter(); 44 const $router = useRouter();
43 const $route = useRoute(); 45 const $route = useRoute();
...@@ -94,11 +96,13 @@ const getCycleList = async (form_code) => { ...@@ -94,11 +96,13 @@ const getCycleList = async (form_code) => {
94 // 计算高度 96 // 计算高度
95 calculatePopupContentHeight(); 97 calculatePopupContentHeight();
96 } else { 98 } else {
97 - // 如果不需要周期选择,直接跳转到目标页面 99 + // 如果不需要周期选择,检查未完成表单后跳转到目标页面
98 const targetRoute = sessionStorage.getItem('cycle_target_route'); 100 const targetRoute = sessionStorage.getItem('cycle_target_route');
99 if (targetRoute) { 101 if (targetRoute) {
100 sessionStorage.removeItem('cycle_target_route'); 102 sessionStorage.removeItem('cycle_target_route');
101 - $router.replace(JSON.parse(targetRoute)); 103 + const route = JSON.parse(targetRoute);
104 + // 检查是否需要显示未完成表单弹框
105 + checkUnfinishedForm(route);
102 } else { 106 } else {
103 $router.replace('/'); 107 $router.replace('/');
104 } 108 }
...@@ -125,8 +129,9 @@ const confirmCycleSelection = () => { ...@@ -125,8 +129,9 @@ const confirmCycleSelection = () => {
125 }; 129 };
126 // 清除临时存储 130 // 清除临时存储
127 sessionStorage.removeItem('cycle_target_route'); 131 sessionStorage.removeItem('cycle_target_route');
128 - // 跳转到目标页面 132 +
129 - $router.replace(route); 133 + // 检查是否需要显示未完成表单弹框
134 + checkUnfinishedForm(route);
130 } else { 135 } else {
131 // 如果没有目标路由,跳转到首页 136 // 如果没有目标路由,跳转到首页
132 $router.replace({ 137 $router.replace({
...@@ -140,6 +145,43 @@ const confirmCycleSelection = () => { ...@@ -140,6 +145,43 @@ const confirmCycleSelection = () => {
140 } 145 }
141 }; 146 };
142 147
148 +/**
149 + * 检查未完成的表单信息
150 + * @param {Object} route 目标路由对象
151 + */
152 +const checkUnfinishedForm = (route) => {
153 + // 只在新增状态时检查
154 + if (route.query.page_type === 'add' || route.query.page_type === undefined) {
155 + console.warn('表单为新增状态, 检查是否有未完成的表单信息');
156 + const existingCookie = Cookies.get(route.query.code);
157 + if (existingCookie && route.query.force_back !== '1') {
158 + // 显示确认对话框
159 + showConfirmDialog({
160 + title: '温馨提示',
161 + message: '您还未完成的表单,是否继续?',
162 + confirmButtonColor: styleColor.baseColor,
163 + cancelButtonText: '删除',
164 + closeOnPopstate: false,
165 + })
166 + .then(() => {
167 + // 用户选择继续,跳转到目标页面
168 + $router.replace(route);
169 + })
170 + .catch(() => {
171 + // 用户选择删除,清除cookie后跳转
172 + Cookies.remove(route.query.code);
173 + $router.replace(route);
174 + });
175 + } else {
176 + // 没有未完成的表单,直接跳转
177 + $router.replace(route);
178 + }
179 + } else {
180 + // 不是新增状态,直接跳转
181 + $router.replace(route);
182 + }
183 +};
184 +
143 onMounted(() => { 185 onMounted(() => {
144 const form_code = $route.query.code; 186 const form_code = $route.query.code;
145 if (form_code) { 187 if (form_code) {
......