|
|
@@ -1,4 +1,5 @@
|
|
|
import { createApp } from "vue";
|
|
|
+import Cookies from "js-cookie";
|
|
|
import ElementPlus from "element-plus";
|
|
|
import "element-plus/dist/index.css";
|
|
|
import "element-plus/theme-chalk/display.css";
|
|
|
@@ -10,16 +11,17 @@ import "vxe-table/lib/style.css";
|
|
|
import utils from "@/utils/index";
|
|
|
import dictUtils from "@/utils/dictUtils";
|
|
|
import httpRequest from "@/utils/httpRequest";
|
|
|
-import commonJS from '@/utils/common';
|
|
|
+import commonJS from "@/utils/common";
|
|
|
import validator from "@/utils/validator";
|
|
|
-import validate from '@/utils/validate'
|
|
|
-import validatorXG from '@/utils/validatorXG'
|
|
|
-import validateXG from '@/utils/validateXG'
|
|
|
+import validate from "@/utils/validate";
|
|
|
+import validatorXG from "@/utils/validatorXG";
|
|
|
+import validateXG from "@/utils/validateXG";
|
|
|
import components from "./components";
|
|
|
import i18n from "./i18n";
|
|
|
import router from "./router";
|
|
|
import store from "./store";
|
|
|
import App from "./App.vue";
|
|
|
+import config from "@/config";
|
|
|
import lodash from "lodash/object";
|
|
|
import VueClipboard from "vue-clipboard2";
|
|
|
import VueCookies from "vue-cookies";
|
|
|
@@ -31,6 +33,8 @@ import FormMaking from "jeeplus-form-v3";
|
|
|
import "jeeplus-form-v3/dist/index.css";
|
|
|
|
|
|
import tool from "@/utils/tool";
|
|
|
+import { bootstrapOidcSession } from "@/auth/oidcBootstrap";
|
|
|
+import { isOidcRequired, logoutFromIdentityProvider } from "@/auth/keycloak";
|
|
|
|
|
|
const app = createApp(App);
|
|
|
import "moment/locale/zh-cn";
|
|
|
@@ -47,9 +51,9 @@ app.config.globalProperties.recover = utils.recover;
|
|
|
app.config.globalProperties.recoverNotNull = utils.recoverNotNull;
|
|
|
app.config.globalProperties.pickProperties = utils.pickProperties;
|
|
|
app.config.globalProperties.validator = validator;
|
|
|
-app.config.globalProperties.validate = validate
|
|
|
-app.config.globalProperties.validatorXG = validatorXG
|
|
|
-app.config.globalProperties.validateXG = validateXG
|
|
|
+app.config.globalProperties.validate = validate;
|
|
|
+app.config.globalProperties.validatorXG = validatorXG;
|
|
|
+app.config.globalProperties.validateXG = validateXG;
|
|
|
app.config.globalProperties.moment = moment;
|
|
|
app.config.globalProperties.lodash = lodash;
|
|
|
app.config.globalProperties.deepClone = utils.deepClone;
|
|
|
@@ -58,31 +62,94 @@ app.config.globalProperties.$http = httpRequest; // ajax请求方法
|
|
|
app.config.globalProperties.commonJS = commonJS; // ajax请求方法
|
|
|
app.config.globalProperties.$cookies = VueCookies;
|
|
|
|
|
|
-app.use(store);
|
|
|
-app.use(router);
|
|
|
-app.use(ElementPlus, { locale });
|
|
|
-app.use(i18n);
|
|
|
-app.use(components);
|
|
|
+async function startApplication() {
|
|
|
+ // The router is installed only after the OIDC exchange and menu bootstrap,
|
|
|
+ // so its first navigation sees the existing local token and dynamic menus.
|
|
|
+ await bootstrapOidcSession();
|
|
|
|
|
|
-// app.use(FormMaking)
|
|
|
+ app.use(store);
|
|
|
+ app.use(router);
|
|
|
+ app.use(ElementPlus, { locale });
|
|
|
+ app.use(i18n);
|
|
|
+ app.use(components);
|
|
|
|
|
|
-app.use(FormMaking, {
|
|
|
- locale:
|
|
|
- tool.data.get("APP_LANG") === "zh"
|
|
|
- ? "zh-cn"
|
|
|
- : tool.data.get("APP_LANG") || "zh-cn",
|
|
|
-});
|
|
|
-app.use(JeeplusDevtools);
|
|
|
-app.use(JeeplusFlow);
|
|
|
-app.use(VueClipboard);
|
|
|
-app.use(VueCookies);
|
|
|
-
|
|
|
-VXETable.setup({
|
|
|
- // 对组件内置的提示语进行国际化翻译
|
|
|
- i18n: (key, args) => i18n.global.t(key, args),
|
|
|
-});
|
|
|
+ // app.use(FormMaking)
|
|
|
+ app.use(FormMaking, {
|
|
|
+ locale:
|
|
|
+ tool.data.get("APP_LANG") === "zh"
|
|
|
+ ? "zh-cn"
|
|
|
+ : tool.data.get("APP_LANG") || "zh-cn",
|
|
|
+ });
|
|
|
+ app.use(JeeplusDevtools);
|
|
|
+ app.use(JeeplusFlow);
|
|
|
+ app.use(VueClipboard);
|
|
|
+ app.use(VueCookies);
|
|
|
|
|
|
-app.use(VXETable);
|
|
|
+ VXETable.setup({
|
|
|
+ // 对组件内置的提示语进行国际化翻译
|
|
|
+ i18n: (key, args) => i18n.global.t(key, args),
|
|
|
+ });
|
|
|
+ app.use(VXETable);
|
|
|
+ app.mount("#app");
|
|
|
+}
|
|
|
|
|
|
-//挂载app
|
|
|
-app.mount("#app");
|
|
|
+startApplication().catch(async (error) => {
|
|
|
+ Cookies.remove(config.TOKEN);
|
|
|
+ tool.data.remove(config.TOKEN);
|
|
|
+ tool.data.remove("AUTH_SOURCE");
|
|
|
+ tool.data.remove("USER_INFO");
|
|
|
+ tool.data.remove("MENU");
|
|
|
+ tool.data.remove("PERMISSIONS");
|
|
|
+ if (!isOidcRequired) {
|
|
|
+ try {
|
|
|
+ const redirected = await logoutFromIdentityProvider();
|
|
|
+ if (redirected) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } catch (logoutError) {
|
|
|
+ console.error("登录失败后,Keycloak注销失败", logoutError);
|
|
|
+ }
|
|
|
+ window.location.replace(
|
|
|
+ `${window.location.origin}${window.location.pathname}#/login`
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const root = document.getElementById("app");
|
|
|
+ if (root) {
|
|
|
+ root.replaceChildren();
|
|
|
+ const panel = document.createElement("div");
|
|
|
+ panel.style.cssText =
|
|
|
+ "max-width:720px;margin:80px auto;padding:24px;font-family:sans-serif";
|
|
|
+ const title = document.createElement("h2");
|
|
|
+ title.textContent = "单点登录失败";
|
|
|
+ const detail = document.createElement("p");
|
|
|
+ detail.textContent = String(
|
|
|
+ error && error.message ? error.message : error
|
|
|
+ );
|
|
|
+ const hint = document.createElement("p");
|
|
|
+ hint.textContent =
|
|
|
+ "当前统一认证账号在该租户中不存在或不可用,请退出后换用当前租户账号。";
|
|
|
+ const returnButton = document.createElement("button");
|
|
|
+ returnButton.type = "button";
|
|
|
+ returnButton.textContent = "退出统一认证并返回登录页";
|
|
|
+ returnButton.style.cssText =
|
|
|
+ "margin-top:16px;padding:10px 18px;border:0;border-radius:4px;background:#1890ff;color:#fff;cursor:pointer";
|
|
|
+ returnButton.addEventListener("click", async () => {
|
|
|
+ returnButton.disabled = true;
|
|
|
+ returnButton.textContent = "正在退出统一认证…";
|
|
|
+ try {
|
|
|
+ const redirected = await logoutFromIdentityProvider();
|
|
|
+ if (redirected) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } catch (logoutError) {
|
|
|
+ console.error("退出登录失败", logoutError);
|
|
|
+ }
|
|
|
+ window.location.replace(
|
|
|
+ `${window.location.origin}${window.location.pathname}#/login`
|
|
|
+ );
|
|
|
+ });
|
|
|
+ panel.append(title, detail, hint, returnButton);
|
|
|
+ root.append(panel);
|
|
|
+ }
|
|
|
+});
|