hookehuyr

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

重构路由守卫中的周期选择检查逻辑,改为同步+异步结合的方式
添加未完成表单检查功能,在跳转前提示用户继续或删除
将表单检查逻辑提取为公共函数 checkUnfinishedForm
/*
* @Date: 2022-05-26 13:57:28
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-08 15:52:35
* @LastEditTime: 2025-09-09 10:29:55
* @FilePath: /data-table/src/router.js
* @Description: 文件描述
*/
......@@ -43,40 +43,41 @@ const router = createRouter({
* @param {Object} to 目标路由
* @returns {Promise<boolean>} 是否需要周期选择
*/
const checkCycleSelection = async (to) => {
const checkCycleSelection = (to) => {
// 如果已经在周期选择页面,不需要再检查
if (to.path === '/cycle-selection') {
return false;
return Promise.resolve(false);
}
// 只有在page_type=add或者没有page_type参数时才进行周期判断
if (to.query.page_type && to.query.page_type !== 'add') {
return false;
return Promise.resolve(false);
}
// 如果没有表单代码,不需要周期选择
if (!to.query.code) {
return false;
return Promise.resolve(false);
}
// 如果用户已经选择过周期,不需要再选择
if (to.query.cycle_selected === '1') {
return false;
return Promise.resolve(false);
}
// 如果是预览模式,不需要周期选择
if (to.query.model === 'preview') {
return false;
}
try {
const { data } = await getCycleListAPI({ form_code: to.query.code });
// 如果需要周期选择且有周期列表
return data.is_cycle && data.cycle_list && data.cycle_list.length > 0;
} catch (error) {
console.error('检查周期选择失败:', error);
return false;
return Promise.resolve(false);
}
return getCycleListAPI({ form_code: to.query.code })
.then(({ data }) => {
// 如果需要周期选择且有周期列表
return data.is_cycle && data.cycle_list && data.cycle_list.length > 0;
})
.catch(error => {
console.error('检查周期选择失败:', error);
return false;
});
};
router.beforeEach((to, from, next) => {
......@@ -93,7 +94,32 @@ router.beforeEach((to, from, next) => {
next({ ...to.redirectedFrom, replace: true });
}, 1000);
} else {
// 检查是否需要周期选择 - 使用Promise.then避免async/await
// 先进行同步检查,避免异步问题
// 如果已经在周期选择页面,直接通过
if (to.path === '/cycle-selection') {
next();
return;
}
// 如果用户已经选择过周期,直接通过
if (to.query.cycle_selected === '1') {
next();
return;
}
// 如果不是新增状态或预览模式,直接通过
if ((to.query.page_type && to.query.page_type !== 'add') || to.query.model === 'preview') {
next();
return;
}
// 如果没有表单代码,直接通过
if (!to.query.code) {
next();
return;
}
// 异步检查周期选择
checkCycleSelection(to).then(needsCycleSelection => {
if (needsCycleSelection) {
// 保存目标路由到sessionStorage
......@@ -102,16 +128,16 @@ router.beforeEach((to, from, next) => {
query: to.query,
params: to.params
}));
// 跳转到周期选择页面,保留所有原始参数
next({
// 直接跳转,不使用next
router.push({
path: '/cycle-selection',
query: to.query // 保留所有原始查询参数
});
return;
return; // 有周期选择需求时,直接返回,不执行后续表单检查
}
// 继续原有的表单检查逻辑
if (to.query.page_type === 'add' || to.query.page_type === undefined) { // 表单为新增状态, 检查是否有未完成的表单信息
// 只有在不需要周期选择时,才执行表单检查逻辑
if (to.query.page_type === 'add' || to.query.page_type === undefined) {
const existingCookie = Cookies.get(to.query.code);
if (existingCookie && to.query.force_back !== '1') {
// TAG: 只能在进入路由之前判断,不然很多组件数据不渲染
......@@ -133,15 +159,14 @@ router.beforeEach((to, from, next) => {
next();
}
} else {
next()
next();
}
}).catch(error => {
console.error('周期选择检查失败:', error);
// 出错时继续正常流程
if (to.query.page_type === 'add' || to.query.page_type === undefined) { // 表单为新增状态, 检查是否有未完成的表单信息
// 检查失败时,继续执行表单检查逻辑
if (to.query.page_type === 'add' || to.query.page_type === undefined) {
const existingCookie = Cookies.get(to.query.code);
if (existingCookie && to.query.force_back !== '1') {
// TAG: 只能在进入路由之前判断,不然很多组件数据不渲染
showConfirmDialog({
title: '温馨提示',
message: '您还未完成的表单,是否继续?',
......@@ -149,10 +174,10 @@ router.beforeEach((to, from, next) => {
cancelButtonText: '删除',
closeOnPopstate: false,
})
.then(() => { // 通过后把数据绑定上去
.then(() => {
next();
})
.catch(() => { // 删除cookie
.catch(() => {
Cookies.remove(to.query.code);
next();
});
......@@ -160,7 +185,7 @@ router.beforeEach((to, from, next) => {
next();
}
} else {
next()
next();
}
});
}
......
......@@ -38,6 +38,8 @@ import { ref, onMounted, nextTick } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { getCycleListAPI } from '@/api/cycle';
import { styleColor } from '@/constant.js';
import { showConfirmDialog } from 'vant';
import Cookies from 'js-cookie';
const $router = useRouter();
const $route = useRoute();
......@@ -94,11 +96,13 @@ const getCycleList = async (form_code) => {
// 计算高度
calculatePopupContentHeight();
} else {
// 如果不需要周期选择,直接跳转到目标页面
// 如果不需要周期选择,检查未完成表单后跳转到目标页面
const targetRoute = sessionStorage.getItem('cycle_target_route');
if (targetRoute) {
sessionStorage.removeItem('cycle_target_route');
$router.replace(JSON.parse(targetRoute));
const route = JSON.parse(targetRoute);
// 检查是否需要显示未完成表单弹框
checkUnfinishedForm(route);
} else {
$router.replace('/');
}
......@@ -125,8 +129,9 @@ const confirmCycleSelection = () => {
};
// 清除临时存储
sessionStorage.removeItem('cycle_target_route');
// 跳转到目标页面
$router.replace(route);
// 检查是否需要显示未完成表单弹框
checkUnfinishedForm(route);
} else {
// 如果没有目标路由,跳转到首页
$router.replace({
......@@ -140,6 +145,43 @@ const confirmCycleSelection = () => {
}
};
/**
* 检查未完成的表单信息
* @param {Object} route 目标路由对象
*/
const checkUnfinishedForm = (route) => {
// 只在新增状态时检查
if (route.query.page_type === 'add' || route.query.page_type === undefined) {
console.warn('表单为新增状态, 检查是否有未完成的表单信息');
const existingCookie = Cookies.get(route.query.code);
if (existingCookie && route.query.force_back !== '1') {
// 显示确认对话框
showConfirmDialog({
title: '温馨提示',
message: '您还未完成的表单,是否继续?',
confirmButtonColor: styleColor.baseColor,
cancelButtonText: '删除',
closeOnPopstate: false,
})
.then(() => {
// 用户选择继续,跳转到目标页面
$router.replace(route);
})
.catch(() => {
// 用户选择删除,清除cookie后跳转
Cookies.remove(route.query.code);
$router.replace(route);
});
} else {
// 没有未完成的表单,直接跳转
$router.replace(route);
}
} else {
// 不是新增状态,直接跳转
$router.replace(route);
}
};
onMounted(() => {
const form_code = $route.query.code;
if (form_code) {
......