router.js 5.76 KB
/*
 * @Date: 2022-05-26 13:57:28
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-09-08 15:52:35
 * @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 = async (to) => {
  // 如果已经在周期选择页面,不需要再检查
  if (to.path === '/cycle-selection') {
    return false;
  }
  
  // 只有在page_type=add或者没有page_type参数时才进行周期判断
  if (to.query.page_type && to.query.page_type !== 'add') {
    return false;
  }
  
  // 如果没有表单代码,不需要周期选择
  if (!to.query.code) {
    return false;
  }
  
  // 如果用户已经选择过周期,不需要再选择
  if (to.query.cycle_selected === '1') {
    return 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;
  }
};

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 {
    // 检查是否需要周期选择 - 使用Promise.then避免async/await
    checkCycleSelection(to).then(needsCycleSelection => {
      if (needsCycleSelection) {
        // 保存目标路由到sessionStorage
        sessionStorage.setItem('cycle_target_route', JSON.stringify({
          path: to.path,
          query: to.query,
          params: to.params
        }));
        // 跳转到周期选择页面
        next({
          path: '/cycle-selection',
          query: { code: to.query.code }
        });
        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') {
          // TAG: 只能在进入路由之前判断,不然很多组件数据不渲染
          showConfirmDialog({
            title: '温馨提示',
            message: '您还未完成的表单,是否继续?',
            confirmButtonColor: styleColor.baseColor,
            cancelButtonText: '删除',
            closeOnPopstate: false,
          })
            .then(() => { // 通过后把数据绑定上去
              next();
            })
            .catch(() => { // 删除cookie
              Cookies.remove(to.query.code);
              next();
            });
        } else {
          next();
        }
      } else {
        next()
      }
    });
  }
})

router.afterEach(() => {
  // console.warn(to);
  // console.warn(wx);
  // share(to)
})

export default router;