统一门户所有应用页面,点击跳转对应业务系统,实现业务系统免登录

//获取所有业务系统项(获取并存储到仓库)
//用于页面展示
let appSubjectVoList = ref<any>([])
appSubjectVoList.value = userStore.getAppSubjectVoList || []
//登陆后获取ticket 存储
const ticket = userStore.getTicket || ''
//当前项目编码
const PATH_URL = import.meta.env.VITE_APP_BASE_URL
//当前路由
const webclientHost = window.location.protocol + '//' + window.location.host
//token及用户信息皆为登录时获取存储到仓库
//点击业务系统图标跳转,item就是appSubjectVoList的每一项
const jumpApp = (item) => {let data = {appCode: item.appCode,appName: item.appName,parentCode: item.parentCode,securityNetworkUrl: item.securityNetworkUrl,securityNetworkUrlConnected: appAvailability.value[item.appCode], // 使用检测结果schoolNetworkUrl: item.schoolNetworkUrl,schoolNetworkUrlConnected: true,webClientHost: webclientHost,ticket: ticket,token: userStore.getToken,account: userStore.getUserInfo?.account,appType: 0,useType: item.useType}postAndRedirect(`${PATH_URL}/uil/redirect`, data)
}//由后端重定向跳转
/*** 以POST方式提交数据并处理接口重定向* 接口重定向后会在新窗口打开目标页面* @param {string} apiUrl - 后端接口地址(会重定向的接口)* @param {object} postData - 需要传递的POST参数*/
async function postAndRedirect(apiUrl, postData) {try {const response = await fetch(apiUrl, {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify(postData),redirect: 'manual'})if (response.status === 302) {const redirectUrl = response.headers.get('Location')window.open(redirectUrl, '_blank')} else {const data = await response.json()if (data.data && data.code == 200) {window.open(data.data, '_blank')}if (data.code == 401) {userStore.logout()}}} catch (error) {console.error('Error:', error)}
}

业务系统接收处理页面

  1. 新建 UILLogin 页面(@/views/Login/UILLogin.vue),作为接收并处理 Ticket 的转换页面
  • 根据项目 Code 获取对应的 applicationId(用于菜单获取)。
  • 接收统一门户跳转时传递的参数:appCode、ticket、uilBackendUrl 和 grantId,存入 uilLogindata 对象。
  • 调用业务系统提供的 Token 换取接口(uilLogin),传入 uilLogindata。若接口调用成功,则执行与常规登录相同的后续流程(如获取用户信息、权限菜单等并存储);若失败,则拦截并跳转至登录页。
  • 若统一门户跳转时指定了目标模块(redirect 参数),则登录成功后跳转至该模块;否则跳转至菜单首项。
  • <script setup lang="ts">
    import { computed, reactive, ref } from 'vue'
    import { useRouter, useRoute } from 'vue-router'
    import { uilLogin } from '@/api/login'
    import { useAppStore } from '@/store/modules/app'
    import { usePermissionStore } from '@/store/modules/permission'
    import { useUserStore } from '@/store/modules/user'
    import type { RouteRecordRaw } from 'vue-router'
    import { userDetail, menuAccountTree } from '@/api/login'
    import { processMenuData } from '@/utils/tree'
    import { ElMessage, ElScrollbar } from 'element-plus'
    import { applicationInfo } from '@/api/sys/index'const { addRoute, push } = useRouter()
    const appStore = useAppStore()
    const permissionStore = usePermissionStore()
    const route = useRoute()
    const userStore = useUserStore()
    const redirect = ref('')
    let uilLogindata = reactive({appCode: '',ticket: '',uilBackendUrl: '',grantId: ''
    })
    if (route.query?.ticket && typeof route.query.ticket === 'string') {uilLogindata.ticket = route.query.ticket
    }
    if (route.query?.appCode && typeof route.query.appCode === 'string') {uilLogindata.appCode = route.query.appCode
    }
    if (route.query?.uilBackendUrl && typeof route.query.uilBackendUrl === 'string') {uilLogindata.uilBackendUrl = route.query.uilBackendUrl
    }
    if (route.query?.redirect && typeof route.query.redirect === 'string') {redirect.value = route.query.redirect
    }
    if (route.query?.grantId && typeof route.query.grantId === 'string') {uilLogindata.grantId = route.query.grantId
    }
    //更改为项目code~~~~~~~~~~~~~~~~~~~~~~~~~
    const BASE_PATH = import.meta.env.VITE_BASE_PATH
    // 根据需求 获取applicationId
    const getapplicationId = () => {applicationInfo(BASE_PATH).then((res) => {if (res.code == 200) {appStore.setSysInfo(res.data)// ticket登录~~~~~~~~~~~~~~~~~~~~~~~~if (uilLogindata.ticket) {uilLogin(uilLogindata).then(async (res) => {if (res.code == 200) {userStore.setToken(res.data.tokenValue)userStore.setTokenKey(res.data.tokenName)if (appStore.getDynamicRouter) {getUser()} else {await permissionStore.generateRoutes('static').catch(() => {})permissionStore.getAddRouters.forEach((route) => {addRoute(route as RouteRecordRaw) // 动态添加可访问路由表})permissionStore.setIsAddRouters(true)// 有指定页面跳转指定页面~~~~~~~~~~~~~~~~~~~~~~~~if (redirect.value) {push(`/${redirect.value}`)} else {push({ path: permissionStore.addRouters[0].path })}}} else {push('/login')}}).catch(() => {push('/login')})} else {// 没有ticket回到登录页push('/login')}} else {ElMessage.error('网络异常,请返回重新跳转!')}})
    }
    getapplicationId()
    const application = computed(() => appStore.getSysInfo)
    // 获取角色信息
    const getUser = async () => {const resmenu = await menuAccountTree({ applicationId: application.value.id })resmenu.data = processMenuData(resmenu.data, true, true)const res = await userDetail()res.data.menus = resmenu.data// console.log(res, 'res')if (res) {if (!res.data.menus || !res.data.menus.length) {ElMessage({type: 'error',message: '用户没有权限'})userStore.logout()return}userStore.setUserInfo(res.data)const routers: any[] = res.data.menus || []// console.log(routers, 'routers')userStore.setRoleRouters(routers)appStore.getDynamicRouter && appStore.getServerDynamicRouter? await permissionStore.generateRoutes('server', routers).catch(() => {}): await permissionStore.generateRoutes('frontEnd', routers).catch(() => {})console.log(permissionStore.getAddRouters, 'permissionStore.getAddRouters')permissionStore.getAddRouters.forEach((route) => {addRoute(route as RouteRecordRaw) // 动态添加可访问路由表})permissionStore.setIsAddRouters(true)// 有指定页面跳转指定页面~~~~~~~~~~~~~~~~~~~~~~~~if (redirect.value) {push(`/${redirect.value}`)} else {push({ path: permissionStore.addRouters[0].path })}}
    }
    </script>
    <template><div><ElScrollbar class="h-full"><divclass="lt-sm:p-10px dark:bg-[var(--login-bg-color)] mx-auto h-100vh flex justify-center items-center">跳转中...</div></ElScrollbar></div>
    </template>
    <style lang="less" scoped></style>
  • 在路由配置(router.ts)中添加 /uil-login 页面,确保该页面可被访问。
 {path: '/uil-login',component: () => import('@/views/Login/UILLogin.vue'),name: 'uilLogin',meta: {hidden: true,title: 'UIL登录',noTagsView: true}},
  • 将 /uil-login 加入免重定向白名单(NO_REDIRECT_WHITE_LIST),避免在该页面触发登录重定向逻辑。
export const NO_REDIRECT_WHITE_LIST = ['/login', '/uis-login', '/uploadPage', '/uil-login']

在 @/api/login.ts 中新增 uilLogin 后端 Token 换取接口。

// uil免登录
export const uilLogin = (data): Promise<IResponse> => {return request.post({ url: `/uil/login`, data })
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96951.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96951.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/96951.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

卓伊凡的开源战略与PHP-SG16加密技术深度解析-sg加密技术详解-卓伊凡

卓伊凡的开源战略与PHP-SG16加密技术深度解析-sg加密技术详解-卓伊凡引言&#xff1a;在理想与现实间寻求平衡的开源之路近日&#xff0c;技术创业者卓伊凡先生宣布了一项重大决策&#xff1a;将于明日将其公司旗下的优雅草商城、项目管理系统等众多成熟商业产品正式开源。这一…

回溯 算法常见面试问题

1. 全排列(无重复元素) 核心思想:交换法避免额外空间 def permute(nums):def backtrack(first=0):if first == len(nums):res.append(nums.copy())returnfor i in range(first, len(nums)):nums[first], nums[i] = nums[i], nums[first]backtrack(first + 1)nums[first], …

营销专业人员核心能力构建与发展路径

CDA数据分析师证书含金量高&#xff0c;适应了未来数字化经济和AI发展趋势&#xff0c;难度不高&#xff0c;行业认可度高&#xff0c;对于找工作很有帮助。一、营销人员五维能力模型能力维度核心技能要素工具与方法论产出成果数据驱动决策指标监控、归因分析、效果优化Google …

Android系统学习2——Android.Utils.Log模块讨论

Android系统学习2——Android.Utils.Log模块讨论 ​ 打日志是一个很好的习惯&#xff0c;有的时候我们可以通过这里排查我们的程序的问题。在这里&#xff0c;我们可以从Android的日志机制入手讨论我们的Log模块。 android.util.Log 类的作用 Android 中最常用的日志工具是 and…

使用 YAML 文件,如何优雅地删除 k8s 资源?

在 Kubernetes 中&#xff0c;删除资源是日常运维中不可避免的操作。如果你习惯了使用 kubectl create 和 kubectl apply 来创建和更新资源&#xff0c;那么你可能也会想知道如何用同样基于文件的方式来删除它们。 虽然你总是可以用 kubectl delete deployment <name> 这…

如何将游戏和软件移动到另一个驱动器或外部磁盘中

您的C盘存储空间是否不足&#xff0c;或者您不小心在错误的驱动器中安装了游戏或应用程序。那么使用这个简单的技巧&#xff0c;您可以轻松的将游戏或应用程序移动到另一个分区或磁盘中。1、找到准备移动的软件&#xff0c;选择路径并复制&#xff1a;2、打开记事本&#xff0c…

赋能汽车电子智造:全星QMS打造品质检验、稽核与客诉管理闭环​——全星质量管理软件系统

全星QMS&#xff1a;驱动汽车电子质量卓越与商业成功的核心引擎 在智能汽车时代&#xff0c;汽车电子的质量已成为产品安全、性能与品牌信誉的核心。面对复杂的供应链、严苛的IATF 16949/ISO 26262标准及降本增效的压力&#xff0c;您的企业需要一位数字化战略伙伴。全星质量管…

【数据结构C语言】顺序表

1. 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串...线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线…

AI 学习路径-记录分享

目录推荐学习资源延申阅读推荐学习资源 3Blue1Brown的个人空间-3Blue1Brown个人主页-哔哩哔哩视频 这个简短的课程有助于了解AI的本质&#xff0c;迈入学习AI的第一步。 欢迎加入 &#x1f917; AI Agents 课程 - Hugging Face Agents Course AI Agent&#xff0c;当前火爆…

Windows Server 2019 上安装 Ubuntu 20.04 的几种方式

docker desktop不支持Windows server 2019&#xff0c;所以Windows Server 2019 上安装 Ubuntu 20.04 变成一种可行的途径。记录一下其中可用的几种方式&#xff1a;&#x1f5c2; 常见安装方式对比方式原理难度适用场景优点缺点Hyper‑V 虚拟机&#xff08;推荐&#xff09;利…

当Trae遇上高德MCP:一次国庆武汉之旅的AI技术实践

当Trae遇上高德MCP&#xff1a;一次国庆武汉之旅的AI技术实践 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff0c;每一个特性都是我…

设计模式:抽象工厂模式

简介 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种封装一组具有共同主题或相关依赖关系的独立工厂的方式,而无需指定它们的具体类。核心思想是创建一系列相关或相互依赖的对象家族(产品族),可以将客户端与具体产品的创建过程解耦,使得客…

知行——同为科技24周年庆典

在宜人的金秋时节&#xff0c;北京同为科技有限公司于2025年8月23日&#xff0c;天津基地与江西同时隆重举办了以“知行”为主题的周年庆祝活动&#xff0c;回顾企业24年来的奋斗历程&#xff0c;凝聚“同为人”力量&#xff0c;展望更加光明的未来。当天&#xff0c;创始人周慧…

RK android14 定制ES8388音频编解码器双MIC双OUT(1)

文章目录 前言 一、适配内容概述 二、适配步骤 1. HAL层配置修改 1.1 添加声卡名称识别 (`audio_hw.c`) 1.2 注册声卡路由配置 (`config_list.h`) 1.3 定义路由配置表 (`es8388_config.h`) 2. 内核设备树修改 2.1 禁用默认声卡 2.2 配置ES8388声卡节点 2.3 配置I2C和Codec节点 …

Oracle跟踪及分析方法

1、SQL_TRACE 通过设置 SQL_TRACE 可以启用或禁用 SQL 跟踪工具&#xff0c;设置 SQL_TRACE 为 true 可以收集信息用于性能优化或问题诊断&#xff1b; 特别注意&#xff1a; 全局启用 SQL 跟踪可能会对性能产生严重影响。 可以使用 ALTER SESSION 跟踪特定会话。 Oracle 已…

第三阶段数据库-9:循环,编号,游标,分页

1_sql中的循环&#xff0c;编号&#xff08;1&#xff09;sql 中没有for循环&#xff0c;只有while循环&#xff0c;begin end 中间的就是while执行的语句&#xff0c;相当于{}declare i int; set i1; --begin end 中间的就是while执行的语句&#xff0c;相当于{} while(i<…

Redis高级篇:在Nginx、Redis、Tomcat(JVM)各环节添加缓存以实现多级缓存

摘要&#xff1a;多级缓存通过在 Nginx、Redis、Tomcat&#xff08;JVM&#xff09;各环节添加缓存&#xff0c;解决传统缓存中 Tomcat 瓶颈与 Redis 失效冲击数据库问题。利用 Caffeine 实现 JVM 缓存&#xff0c;OpenResty 结合 Lua 处理 Nginx 层逻辑&#xff0c;通过 Redis…

9 设计网络爬虫

前言 我们重点讨论网络爬虫的设计&#xff0c; 这也是一个有趣且经典的系统设计面试问题。 爬虫开发的复杂性取决于我们想要支持的爬虫规模。它可以是一个小的学校项目&#xff0c;只需要几小时就可以完成&#xff0c;也可以是一个需要专业开发团队持续优化的巨型项目。因此&…

面试:计算机网络

一、网络分层与URL流程 1. 模型掌握TCP/IP四层模型&#xff1a;层级功能 & 协议应用层提供应用接口&#xff08;HTTP、DNS、FTP&#xff09;传输层端到端传输&#xff08;TCP可靠、UDP快速&#xff09;网络层路由与寻址&#xff08;IP、ICMP&#xff09;网络接口层链路传输…

lanczos算法的核心——Ritz向量的计算(主要思想为反向映射)

在 Lanczos 算法中&#xff0c;“将得到的特征向量映射回原始空间&#xff08;即乘以V&#xff09;得到的近似特征向量” 这一步&#xff0c;通常是指在三对角矩阵&#xff08;T&#xff09;的特征向量求解完成后&#xff0c;将其转换回原始矩阵&#xff08;A&#xff09;的特征…