WXL (wul)
昨天 feb5a669dced68415bc7e32f237f77bf9842fe8b
src/views/loginSSO.vue
@@ -11,13 +11,14 @@
      <div v-else class="loading-content">
        <i class="el-icon-loading"></i>
        <p>单点登录中,请稍候...</p>
        <p class="loading-detail">{{ loadingDetail }}</p>
      </div>
    </div>
  </div>
</template>
<script>
import { setToken } from "@/utils/auth";
import { setToken, removeToken } from "@/utils/auth";
export default {
  name: "SSORedirect",
@@ -25,90 +26,205 @@
    return {
      errorMessage: "",
      loading: true,
      loadingDetail: "正在处理SSO令牌...",
    };
  },
  created() {
    this.handleSSORedirect();
  },
  methods: {
    // 匹配orgid
    // 匹配orgid - 优化为对象映射
    mateOrgid(orgid) {
      if (orgid == "30001002") {
        localStorage.setItem("orgname", "浙江省立同德医院翠苑院区");
        localStorage.setItem("ZuHuID", "1400361376454545408");
        localStorage.setItem("deptCode", "1017");
      } else if (orgid == "30001003") {
        localStorage.setItem("orgname", "浙江省立同德医院之江院区");
        localStorage.setItem("ZuHuID", "1400360867068907520");
        localStorage.setItem("deptCode", "01040201");
      } else if (orgid == "30001004") {
        localStorage.setItem("orgname", "浙江省立同德医院闲林院区");
        localStorage.setItem("ZuHuID", "1429338802177000002");
        localStorage.setItem("deptCode", "");
      } else if (orgid == "30001005") {
        localStorage.setItem("orgname", "浙江省立同德医院天目山路院区");
        localStorage.setItem("ZuHuID", "1429338802177000003");
        localStorage.setItem("deptCode", "");
      } else if (orgid == "30001006") {
        localStorage.setItem("orgname", "浙江省立同德医院青山湖院区");
        localStorage.setItem("ZuHuID", "1429338802177000004");
        localStorage.setItem("deptCode", "");
      } else if (orgid == "30001007") {
        localStorage.setItem("orgname", "测试院区");
        localStorage.setItem("ZuHuID", "1429338802177000005");
        localStorage.setItem("deptCode", "");
      const orgMap = {
        "30001002": {
          orgname: "省立同德翠苑院区",
          ZuHuID: "1400361376454545408",
          deptCode: "1017",
        },
        "30001003": {
          orgname: "省立同德之江院区",
          ZuHuID: "1400360867068907520",
          deptCode: "01040201",
        },
        "30001004": {
          orgname: "省立同德闲林院区",
          ZuHuID: "1429338802177000002",
          deptCode: "",
        },
        "30001005": {
          orgname: "省立同德天目山路院区",
          ZuHuID: "1429338802177000003",
          deptCode: "",
        },
        "30001006": {
          orgname: "省立同德青山湖院区",
          ZuHuID: "1429338802177000004",
          deptCode: "",
        },
        "30001007": {
          orgname: "测试院区",
          ZuHuID: "1429338802177000005",
          deptCode: "",
        },
      };
      const orgInfo = orgMap[orgid];
      if (orgInfo) {
        localStorage.setItem("orgname", orgInfo.orgname);
        localStorage.setItem("ZuHuID", orgInfo.ZuHuID);
        localStorage.setItem("deptCode", orgInfo.deptCode);
        return orgInfo;
      }
      return null;
    },
    // 清理旧系统的本地存储
    clearOldSystemData() {
      // 清理可能冲突的旧系统数据
      const oldKeys = ["old-token", "old-user-info", "old-session"];
      oldKeys.forEach((key) => {
        localStorage.removeItem(key);
        sessionStorage.removeItem(key);
      });
      // 清理特定前缀的存储
      Object.keys(localStorage).forEach((key) => {
        if (key.startsWith("old-system-") || key.startsWith("legacy-")) {
          localStorage.removeItem(key);
        }
      });
    },
    // 获取默认重定向路径
    getDefaultRedirectPath() {
      try {
        const roles = this.$store.state.user?.roles || [];
        const username = this.$store.state.user?.name || "";
        if (roles.includes("admin") || username === "admin") {
          return "/index";
        }
        return "/followvisit/discharge";
      } catch (error) {
        console.warn("获取默认重定向路径失败:", error);
        return "/followvisit/discharge";
      }
    },
    // 验证SSO参数
    validateSSOParams(params) {
      const { token, orgid } = params;
      if (!token) {
        throw new Error("缺少认证令牌(token)");
      }
      if (!orgid) {
        console.warn("SSO登录缺少orgid参数");
      }
      // 验证token格式(简单验证)
      if (token.length < 10) {
        throw new Error("令牌格式无效");
      }
      return true;
    },
    // 主处理函数
    async handleSSORedirect() {
      try {
        console.log(11);
        // 从URL参数中获取token和机构信息
        let { token, orgid, orgname, ZuHuID, deptCode, redirect } =
          this.$route.query;
        // token =
        //   "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6Ijc5MWVkODNlLWE2MWYtNDI2MS05ZDZlLTNhOTVjYTU2YjZhMiJ9.q6jrRj8fwtb3FOqqwaxIFDr824hf85DW8heCj4qWYgRE55Pn0vkmcujFsYMrz9qqo047Gl7lv3rnok8pk7SKYQ"; // 验证必要参数
        // orgid = "30001002";
        if (!token) {
          throw new Error("缺少认证令牌(token)");
        }
        this.mateOrgid(orgid);
        console.log("SSO重定向开始处理...");
        // 1. 获取URL参数
        const params = this.$route.query;
        console.log("SSO参数:", params);
        // 2. 验证必要参数
        this.validateSSOParams(params);
        this.loadingDetail = "验证令牌中...";
        // 3. 清理旧系统数据
        this.clearOldSystemData();
        const { token, orgid, orgname, ZuHuID, deptCode, redirect } = params;
        // 4. 存储token
        setToken(token);
        this.$store.commit("SET_TOKEN", token);
        this.loadingDetail = "设置用户令牌...";
        // 存储机构信息到localStorage
        // 5. 处理机构信息
        if (orgid) {
          // 优先使用mateOrgid映射
          const orgInfo = this.mateOrgid(orgid);
          if (!orgInfo) {
            // 如果没有映射,使用传入的参数
            if (orgname) localStorage.setItem("orgname", orgname);
            if (ZuHuID) localStorage.setItem("ZuHuID", ZuHuID);
            if (deptCode) localStorage.setItem("deptCode", deptCode);
          }
          localStorage.setItem("orgid", orgid);
          this.$store.dispatch("UpdateOrgId", orgid);
        }
        if (orgname) localStorage.setItem("orgname", orgname);
        if (ZuHuID) localStorage.setItem("ZuHuID", ZuHuID);
        if (deptCode) localStorage.setItem("deptCode", deptCode);
        // 获取用户信息
        await this.$store.dispatch("GetInfo");
        // 确定重定向路径
        let redirectPath = "/index";
        if (redirect) {
          redirectPath = decodeURIComponent(redirect);
        } else {
          // 根据用户角色决定默认跳转页面
          const roles = this.$store.state.user.roles;
          const username = this.$store.state.user.name;
          if (roles.includes("admin") || username === "admin") {
            redirectPath = "/index";
          } else {
            redirectPath = "/followvisit/discharge";
          if (this.$store.dispatch && typeof this.$store.dispatch === "function") {
            await this.$store.dispatch("UpdateOrgId", orgid);
          }
        }
        this.loadingDetail = "设置机构信息...";
        // 跳转到目标页面
        this.$router.replace({ path: redirectPath });
        // 6. 获取用户信息
        if (this.$store.dispatch && typeof this.$store.dispatch === "function") {
          await this.$store.dispatch("GetInfo");
        }
        this.loadingDetail = "获取用户信息...";
        // 7. 处理重定向路径
        let redirectPath = "/followvisit/discharge";
        if (redirect) {
          // 解码传入的重定向路径
          try {
            redirectPath = decodeURIComponent(redirect);
            console.log("使用传入的重定向路径:", redirectPath);
          } catch (e) {
            console.error("解码重定向路径失败:", e);
            redirectPath = this.getDefaultRedirectPath();
          }
        } else {
          redirectPath = this.getDefaultRedirectPath();
        }
        // 8. 移除URL中的token参数(安全考虑)
        this.$router.replace({ query: {} });
        // 9. 延迟跳转,确保状态已更新
        setTimeout(() => {
          this.loadingDetail = "跳转到目标页面...";
          console.log("准备跳转到:", redirectPath);
          // ✅ 使用 push 而不是 replace,保留历史记录
          this.$router.push({ path: redirectPath }).then(() => {
            console.log("SSO登录成功,跳转完成");
          }).catch((error) => {
            console.error("路由跳转失败:", error);
            // 回退到默认页面
            this.$router.push({ path: "/followvisit/discharge" });
          });
        }, 500);
      } catch (error) {
        console.error("SSO登录失败:", error);
        this.errorMessage = `单点登录失败: ${error.message || "未知错误"}`;
        this.loading = false;
        // 清理token
        removeToken();
        this.$store.commit("SET_TOKEN", "");
        // 显示错误详情(开发环境)
        if (process.env.NODE_ENV === "development") {
          this.errorMessage += ` (详情: ${error.toString()})`;
        }
        // 5秒后跳转到普通登录页
        setTimeout(() => {
@@ -126,29 +242,73 @@
  justify-content: center;
  align-items: center;
  height: 100vh;
  min-height: 500px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  background-color: #f5f7fa;
  padding: 20px;
  box-sizing: border-box;
}
.loading-container {
  text-align: center;
  padding: 20px;
  background: white;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 40px 60px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  min-width: 400px;
  max-width: 500px;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}
.loading-content {
  padding: 20px;
  padding: 30px 20px;
}
.el-icon-loading {
  font-size: 40px;
  font-size: 60px;
  color: #409eff;
  margin-bottom: 10px;
  margin-bottom: 20px;
  animation: spin 1.5s linear infinite;
}
p {
@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
.loading-content p {
  margin: 0;
  color: #606266;
  font-size: 16px;
  line-height: 1.6;
}
.loading-detail {
  margin-top: 10px !important;
  font-size: 14px !important;
  color: #909399 !important;
  opacity: 0.8;
}
/* 响应式设计 */
@media (max-width: 768px) {
  .sso-redirect {
    padding: 10px;
  }
  .loading-container {
    padding: 30px 20px;
    min-width: 300px;
    max-width: 90vw;
  }
  .el-icon-loading {
    font-size: 50px;
  }
  .loading-content p {
    font-size: 15px;
  }
}
</style>