router.js
6.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
* @Date: 2022-05-26 13:57:28
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-09 10:29:55
* @FilePath: /data-table/src/router.js
* @Description: 文件描述
*/
import { createRouter, createWebHashHistory } from 'vue-router';
import RootRoute from './route.js';
import asyncRoutesArr from "./mock/routes"
import generateRoutes from './utils/generateRoute'
import { showConfirmDialog, Loading } from "vant";
import Cookies from 'js-cookie';
import { styleColor } from "@/constant.js";
import { getCycleListAPI } from '@/api/cycle';
// TAG: 路由配置表
/**
* 把项目独有的路由配置到相应的路径,默认路由文件只放公用部分
* 但是 vue 文件内容还是要事先准备好
*/
const modules = import.meta.globEager('@/router/routes/modules/**/*.js'); // Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
const routeModuleList = [];
Object.keys(modules).forEach((key) => {
const mod = modules[key].default || {};
const modList = Array.isArray(mod) ? [...mod] : [mod];
routeModuleList.push(...modList);
});
// 创建路由实例并传递 `routes` 配置
const router = createRouter({
history: createWebHashHistory('/index.html'),
routes: [...RootRoute, ...routeModuleList]
});
// TAG: 动态生成路由
/**
* generateRoute 负责把后台返回数据拼接成项目需要的路由结构,动态添加到路由表里面
*/
/**
* 检查是否需要周期选择
* @param {Object} to 目标路由
* @returns {Promise<boolean>} 是否需要周期选择
*/
const checkCycleSelection = (to) => {
// 如果已经在周期选择页面,不需要再检查
if (to.path === '/cycle-selection') {
return Promise.resolve(false);
}
// 只有在page_type=add或者没有page_type参数时才进行周期判断
if (to.query.page_type && to.query.page_type !== 'add') {
return Promise.resolve(false);
}
// 如果没有表单代码,不需要周期选择
if (!to.query.code) {
return Promise.resolve(false);
}
// 如果用户已经选择过周期,不需要再选择
if (to.query.cycle_selected === '1') {
return Promise.resolve(false);
}
// 如果是预览模式,不需要周期选择
if (to.query.model === 'preview') {
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) => {
// 使用404为中转页面,避免动态路由没有渲染出来,控制台报警告问题
if (to.path == '/404' && to.redirectedFrom != undefined) {
// 模拟异步操作
setTimeout(() => {
if (!asyncRoutesArr.length) return; // 没有动态路由避免报错
const arr = generateRoutes(asyncRoutesArr); // 在路由守卫处生成,避免有子路由时刷新白屏问题。
arr.forEach(item => {
router.addRoute(item) // 新增路由
})
// 重写被404覆盖路由信息
next({ ...to.redirectedFrom, replace: true });
}, 1000);
} else {
// 先进行同步检查,避免异步问题
// 如果已经在周期选择页面,直接通过
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
sessionStorage.setItem('cycle_target_route', JSON.stringify({
path: to.path,
query: to.query,
params: to.params
}));
// 直接跳转,不使用next
router.push({
path: '/cycle-selection',
query: to.query // 保留所有原始查询参数
});
return; // 有周期选择需求时,直接返回,不执行后续表单检查
}
// 只有在不需要周期选择时,才执行表单检查逻辑
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: '您还未完成的表单,是否继续?',
confirmButtonColor: styleColor.baseColor,
cancelButtonText: '删除',
closeOnPopstate: false,
})
.then(() => { // 通过后把数据绑定上去
next();
})
.catch(() => { // 删除cookie
Cookies.remove(to.query.code);
next();
});
} else {
next();
}
} else {
next();
}
}).catch(error => {
console.error('周期选择检查失败:', error);
// 检查失败时,继续执行表单检查逻辑
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') {
showConfirmDialog({
title: '温馨提示',
message: '您还未完成的表单,是否继续?',
confirmButtonColor: styleColor.baseColor,
cancelButtonText: '删除',
closeOnPopstate: false,
})
.then(() => {
next();
})
.catch(() => {
Cookies.remove(to.query.code);
next();
});
} else {
next();
}
} else {
next();
}
});
}
})
router.afterEach(() => {
// console.warn(to);
// console.warn(wx);
// share(to)
})
export default router;