Appearance
单点登录
OA 单点登录 SRM 并跳转至各模块审批详情页面
TIP
项目开发通常需要对接 OA 等第三方系统,并实现单点登录并跳转至各模块审批详情页的需求
- 代码实现
- 约定 url 跳转地址格式, 比如:
https://ai-cs.51qqt.com/user/login?redirect=/srm/bpm/before/2018150243634462721&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50Ijoia0FWSTMxTDFuUkNmcWtPalowODgwMWVnbGVJL3k2Q0lvWkI5SUlKcFd2L3ZiTGgwRFR2M3dLZ3Y2bWJoSVN6WFZJbkRIUm1PeGFJcnAvZ2JKVVpnd1E9PSIsImV4cCI6MTc3NjY4MDIzMX0.6aZhOK8ZcMGBjl4-UbWYeNFsdPSkjYmIapJowfJW5SQ - 本地路由,用一个中间页面作数据处理,如上述的
/srm/bpm/before/:id, 根据路由动态id, 获取表头数据后跳转页面等操作; - 组装实现业务跳转逻辑代码
vue
<script lang="ts" setup>
//...
const resetStore = () => {
nextTick(() => {
// 清空各模块列表页当前行缓存数据
pageStore.$reset();
// 清空当前登录人动态授权信息
userStore.$reset();
// 清空动态路由权限
permissionStore.$reset();
// 清空tabs
tabsStore.$reset();
});
};
const loginByToken = () => {
let token = route.query?.token;
if (token) {
resetStore(); // 需要清除 token 缓存
loginLoading.value = true;
Request.registerModuleAction("LoginModule/loginByToken", {
token: token,
}).then((res) => {
loginLoading.value = false;
if (res && res.success) {
onLginFinish(res);
} else {
Message.error(res.message);
router.replace({ path: "/user/login" });
}
});
}
};
//...
</script>ts
export const ssoRouter = {
path: "/srm/bpm/before/:id",
route: "1",
meta: {
keepAlive: false,
title: "待办审批跳转",
titleI18nKey: "",
},
name: "srm-bpm-before",
component: () => import("@views/srm/bpm/task/before.vue"),
};vue
<!--
* @Author: wangxin
* @Description: 单点登录审批跳转
-->
<template>
<div class="ToDoBefore">
<a-spin :spinning="loading">
<div class="container">
<div class="wrapper">
<div class="content">
<div class="info">
<QSymbolIcon class="icon" type="icon-Q-success" :size="380" />
<div class="tip">
<h5 class="ant-typography" v-if="loading">
<span class="ant-typography ant-typography-danger">
{{
srmI18n(
"i18n_alert_ELuKsVRS_67b8860f",
"页面加载中,请稍后"
)
}}...
</span>
</h5>
</div>
</div>
</div>
</div>
</div>
</a-spin>
</div>
</template>
<script setup lang="ts">
import { ref, watch } from "vue";
import { useRoute } from "vue-router";
import qqtApi from "@qqt-product/api";
// 国际化
import { srmI18n } from "@/utils/srmI18n";
import { QSymbolIcon } from "@qqt-product/icons";
import type {
GlobalPageLayoutTypes,
GlobalListPageLayoutTypes,
} from "@qqt-product/ui";
import useJumpDetailHook from "@/views/srm/bpm/hook/useJumpDetailHook";
// 工具函数及types
import qqtUtils from "@qqt-product/utils";
const { delay } = qqtUtils;
const route = useRoute();
const Request: qqtApi.Request = qqtApi.useHttp();
const useJumpDetail = useJumpDetailHook();
const listLayoutRef = ref<any>({});
const loading = ref<boolean>(true);
const jumpToDetail = (row) => {
delay(() => {
useJumpDetail.jumpDetail(
{ row } as GlobalListPageLayoutTypes.ListOptionsEventParams,
listLayoutRef,
false
);
}, 300);
};
const fetchData = (id: string) => {
if (!id) {
return;
}
// 代办审批列表查询
const url = "/workflow/task/todo/list";
// 已办审批列表查询
const historyUrl = "/workflow/task/history/list";
const params = {
id: id,
order: "desc",
column: "id",
pageNo: 1,
pageSize: 20,
};
Request.get({ url, params }).then((res) => {
if (res.success) {
const records = res.result
.records as GlobalPageLayoutTypes.RecordString[];
if (records.length) {
jumpToDetail(records[0]);
} else {
Request.get({ url: historyUrl, params }).then((subRes) => {
const records = subRes.result
.records as GlobalPageLayoutTypes.RecordString[];
if (records.length) {
jumpToDetail(records[0]);
}
});
}
}
});
};
// watch the params of the route to fetch the data again
watch(
() => route.params.id,
(id) => fetchData(id as string),
{ immediate: true }
);
</script>
<style lang="less" scoped>
.ToDoBefore {
.container {
background-color: #eff2f5;
padding: 12px;
height: 100vh;
}
.wrapper {
position: relative;
border-radius: 12px;
background: #fff;
width: calc(100vw - 24px);
height: calc(100vh - 24px);
min-width: 1000px;
}
.content {
position: absolute;
left: 50%;
top: 30%;
transform: translate(-50%, -30%);
}
.info {
display: flex;
flex-direction: column;
}
.tip {
text-align: center;
}
}
</style>示例
