zhanghua
2024-11-04 b83cb8d8fa9dcd7c7c865446121d989fbc312a8e
钉钉登录
8个文件已修改
3个文件已添加
328 ■■■■ 已修改文件
index.html 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/user/index.ts 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/ddlogin.js 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/permission.ts 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dingdingLogin copy.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dingdingLogin.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
index.html
@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
@@ -202,6 +203,8 @@
      }
    </style>
  </head>
<script src="./src/assets/ddlogin.js"></script>
<!-- <script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script> -->
  <body>
    <div id="app">
@@ -214,4 +217,5 @@
    </div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>
package.json
@@ -41,6 +41,7 @@
    "vue": "3.2.45",
    "vue-cropper": "1.0.3",
    "vue-i18n": "9.2.2",
    "vue-lsp": "^1.0.3",
    "vue-router": "4.1.4",
    "vue-types": "^5.0.3"
  },
src/App.vue
@@ -6,26 +6,20 @@
<script setup lang="ts">
import axios from 'axios';
import useSettingsStore from '@/store/modules/settings'
import { handleThemeStyle } from '@/utils/theme'
import useSettingsStore from '@/store/modules/settings';
import { handleThemeStyle } from '@/utils/theme';
import useAppStore from '@/store/modules/app';
import { createUser } from "@/api/system/oss";
import { setToken } from "@/utils/auth";
import usePermissionStore from "@/store/modules/permission";
import { isHttp } from "@/utils/validate";
import { createUser } from '@/api/system/oss';
import { setToken, removeToken } from '@/utils/auth';
import usePermissionStore from '@/store/modules/permission';
import { isHttp } from '@/utils/validate';
const appStore = useAppStore();
const size = computed(() => appStore.size as any);
onMounted(async () => {
  await nextTick(() => {
    // 初始化主题样式
    handleThemeStyle(useSettingsStore().theme)
  })
})
    handleThemeStyle(useSettingsStore().theme);
  });
});
</script>
src/api/system/user/index.ts
@@ -195,7 +195,13 @@
    method: 'get'
  });
};
export const dingdingLogin=(data: any ): AxiosPromise<String> => {
  return request({
    url: '/auth/dingdingLogin',
    method: 'get',
    params: data
  })
}
export default {
  listUser,
  getUser,
@@ -211,5 +217,6 @@
  getAuthRole,
  updateAuthRole,
  deptTreeSelect,
  listUserByDeptId
  listUserByDeptId,
  dingdingLogin
};
src/assets/ddlogin.js
New file
@@ -0,0 +1,73 @@
! function (e) {
  var t = {};
  function r(n) {
    if (t[n]) return t[n].exports;
    var o = t[n] = {
      i: n,
      l: !1,
      exports: {}
    };
    return e[n].call(o.exports, o, o.exports, r), o.l = !0, o.exports
  }
  r.m = e, r.c = t, r.d = function (e, t, n) {
    r.o(e, t) || Object.defineProperty(e, t, {
      enumerable: !0,
      get: n
    })
  }, r.r = function (e) {
    "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
      value: "Module"
    }), Object.defineProperty(e, "__esModule", {
      value: !0
    })
  }, r.t = function (e, t) {
    if (1 & t && (e = r(e)), 8 & t) return e;
    if (4 & t && "object" == typeof e && e && e.__esModule) return e;
    var n = Object.create(null);
    if (r.r(n), Object.defineProperty(n, "default", {
        enumerable: !0,
        value: e
      }), 2 & t && "string" != typeof e)
      for (var o in e) r.d(n, o, function (t) {
        return e[t]
      }.bind(null, o));
    return n
  }, r.n = function (e) {
    var t = e && e.__esModule ? function () {
      return e.default
    } : function () {
      return e
    };
    return r.d(t, "a", t), t
  }, r.o = function (e, t) {
    return Object.prototype.hasOwnProperty.call(e, t)
  }, r.p = "", r(r.s = 1382)
}({
  1382: function (e, t) {
    var r = function (e, t) {
      var r = e.match(new RegExp("[?&]" + t + "=([^&]+)"));
      return r ? r[1] : null
    };
    window.DTFrameLogin = function (e, t, n, o) {
      var i, u = e.id && document.getElementById(e.id) || null,
        c = document.createElement("iframe");
      t.client_id && t.redirect_uri && t.response_type && t.scope ? u ? (u.innerHTML = "", u.appendChild(c), c && c.contentWindow && c.contentWindow.postMessage && window.addEventListener ? (c.src = "https://" + ((i = t).isPre ? "pre-login" : "login") + ".dingtalk.com/oauth2/auth?iframe=true&redirect_uri=" + i.redirect_uri + "&response_type=" + i.response_type + "&client_id=" + i.client_id + "&scope=" + i.scope + (i.prompt ? "&prompt=" + i.prompt : "") + (i.state ? "&state=" + i.state : "") + (i.org_type ? "&org_type=" + i.org_type : "") + (i.corpId ? "&corpId=" + i.corpId : "") + (i.exclusiveLogin ? "&exclusiveLogin=" + i.exclusiveLogin : "") + (i.exclusiveCorpId ? "&exclusiveCorpId=" + i.exclusiveCorpId : ""), c.width = "" + (e.width || 300), c.height = "" + (e.height || 300), c.frameBorder = "0", c.scrolling = "no", window.addEventListener("message", (function (e) {
        var t = e.data,
          i = e.origin;
        if (/login\.dingtalk\.com/.test(i) && t)
          if (t.success && t.redirectUrl) {
            var u = t.redirectUrl,
              c = r(u, "authCode") || "",
              d = r(u, "state") || "",
              s = r(u, "error") || "";
            c ? n && n({
              redirectUrl: u,
              authCode: c,
              state: d
            }) : o && o(s)
          } else o && o(t.errorMsg)
      }))) : o && o("Browser not support")) : o && o("Element not found") : o && o("Missing parameters")
    }
  }
});
src/permission.ts
@@ -9,43 +9,46 @@
import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission';
import { ElMessage } from "element-plus";
import { fa } from 'element-plus/es/locale';
NProgress.configure({ showSpinner: false });
const whiteList = ['/login', '/register', '/social-callback'];
router.beforeEach(async (to, from, next) => {
  NProgress.start();
  if (getToken()) {
  if (judge(getToken())) {
    console.log('判断当前用户是否已拉取完user_info信息');
    to.meta.title && useSettingsStore().setTitle(to.meta.title as string);
    /* has token*/
    if (to.path === '/login') {
      next({ path: '/' });
      NProgress.done();
    } else {
      if (useUserStore().roles.length === 0) {
      // if (useUserStore().roles.length === 0) {
        isRelogin.show = true;
        // 判断当前用户是否已拉取完user_info信息
      //   // 判断当前用户是否已拉取完user_info信息
        const [err] = await tos(useUserStore().getInfo());
        if (err) {
          await useUserStore().logout();
          ElMessage.error(err);
          next({ path: '/' });
        } else {
          isRelogin.show = false;
          const accessRoutes = await usePermissionStore().generateRoutes();
          // 根据roles权限生成可访问的路由表
          accessRoutes.forEach((route) => {
            if (!isHttp(route.path)) {
              router.addRoute(route); // 动态添加可访问路由表
            }
          });
          next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
        }
      } else {
      //   const [err] = await tos(useUserStore().getInfo());
      //   if (err) {
      //     await useUserStore().logout();
      //     ElMessage.error(err);
      //     next({ path: '/' });
      //   } else {
      //     isRelogin.show = false;
      //     const accessRoutes = await usePermissionStore().generateRoutes();
      //     // 根据roles权限生成可访问的路由表
      //     accessRoutes.forEach((route) => {
      //       if (!isHttp(route.path)) {
      //         router.addRoute(route); // 动态添加可访问路由表
      //       }
      //     });
      // next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
      // }
      // } else {
        next();
      }
      // }
    }
  } else {
    // 没有token
@@ -63,3 +66,15 @@
router.afterEach(() => {
  NProgress.done();
});
const judge = (token: string) => {
  if (token) {
    var data = JSON.parse(token)
    if (data != null) {
      if (data.expirse != null && new Date().getTime() - data.expirse < 60 * 60 * 1000) {
        return true
      }
    }
  }
  return false
}
src/router/index.ts
@@ -44,7 +44,12 @@
  },
  {
    path: '/login',
    component: () => import('@/views/login.vue'),
    component: () => import('@/views/dingdingLogin.vue'),
    hidden: true
  },
  {
    path: '/dingdingLogin',
    component: () => import('@/views/dingdingLogin.vue'),
    hidden: true
  },
  {
src/views/dingdingLogin copy.vue
New file
@@ -0,0 +1,70 @@
<template>
  <div id="content" class="content">
    <div>
      <div style="text-align:center">钉钉扫码登录</div>
      <div id="self_defined_element" class="self-defined-classname"></div>
    </div>
  </div>
</template>
<script setup name="Oss" lang="ts">
import { useRoute } from 'vue-router';
import { dingdingLogin } from '@/api/system/user';
const getUserDate = async (code: string) => {
  // await dingdingLogin({
  //   authCode: code
  // }).then((res: any) => {
  //   this.$router.push('/student');
  // });
};
onMounted(() => {
  const route = useRoute();
  let code = route.query.code;
  if (code) {
    getUserDate(code);
  } else {
    // STEP3:在需要的时候,调用 window.DTFrameLogin 方法构造登录二维码,并处理登录成功或失败的回调。
    window.DTFrameLogin(
      {
        id: 'self_defined_element',
        width: 300,
        height: 300
      },
      {
        redirect_uri: encodeURIComponent('https://f060-183-223-248-101.ngrok-free.app/auth/dingdingLogin'),
        client_id: 'dingl5dxahaj3uzfug66',
        scope: 'openid',
        response_type: 'code',
        state: 'STATE',
        prompt: 'consent'
      },
      (loginResult: any) => {
        console.log('loginResult:' + loginResult);
        debugger;
        const { redirectUrl, authCode, state } = loginResult;
        // 这里可以直接进行重定向
        window.location.href = redirectUrl;
        // 也可以在不跳转页面的情况下,使用code进行授权
        console.log(authCode);
      },
      (errorMsg: any) => {
        // 这里一般需要展示登录失败的具体原因,可以使用toast等轻提示
        console.error(`errorMsg of errorCbk: ${errorMsg}`);
      }
    );
  }
});
</script>
<style lang="scss" scoped>
.content {
  display: flex;
  align-items: center;
  justify-content: center;
}
.self-defined-classname {
  // width: 300px;
  // height: 300px;
}
</style>
src/views/dingdingLogin.vue
New file
@@ -0,0 +1,77 @@
<template>
  <div id="content" class="content">
    <!-- <div>
      <div style="text-align:center">钉钉扫码登录</div>
      <div id="self_defined_element" class="self-defined-classname"></div>
    </div> -->
  </div>
</template>
<script setup name="Oss" lang="ts">
import { useRoute } from 'vue-router';
import { dingdingLogin } from '@/api/system/user';
import { setToken } from '@/utils/auth';
const getUserDate = async (authCode: string, code: string) => {
  await dingdingLogin({
    authCode: authCode,
    code: code
  }).then((res: any) => {
    var data = { value: 'admin', expirse: new Date().getTime() };
    setToken(JSON.stringify(data));
    window.location.href = '/index';
  });
};
onMounted(() => {
  const router = useRoute();
  let code = router.query.code;
  let authCode = router.query.authCode;
  if (code) {
    getUserDate(authCode, code);
  } else {
    window.location.href =
      'https://login.dingtalk.com/oauth2/auth?redirect_uri=http://127.0.0.1:81/login&response_type=code&client_id=dingl5dxahaj3uzfug66&scope=oD9LphDV7Ge4vGgnIiS3WIwiEiE&state=dddd&prompt=consent';
    // // STEP3:在需要的时候,调用 window.DTFrameLogin 方法构造登录二维码,并处理登录成功或失败的回调。
    // window.DTFrameLogin(
    //   {
    //     id: 'self_defined_element',
    //     width: 300,
    //     height: 300
    //   },
    //   {
    //     redirect_uri: encodeURIComponent('http://127.0.0.1:8080/auth/dingdingLogin'),
    //     client_id: 'dingl5dxahaj3uzfug66',
    //     scope: 'openid',
    //     response_type: 'code',
    //     state: 'STATE',
    //     prompt: 'consent'
    //   },
    //   (loginResult: any) => {
    //     console.log('loginResult:' + loginResult);
    //     const { redirectUrl, authCode, state } = loginResult;
    //     // 这里可以直接进行重定向
    //     window.location.href = redirectUrl;
    //     // 也可以在不跳转页面的情况下,使用code进行授权
    //     console.log(authCode);
    //   },
    //   (errorMsg: any) => {
    //     // 这里一般需要展示登录失败的具体原因,可以使用toast等轻提示
    //     console.error(`errorMsg of errorCbk: ${errorMsg}`);
    //   }
    // );
  }
});
</script>
<style lang="scss" scoped>
.content {
  display: flex;
  align-items: center;
  justify-content: center;
}
.self-defined-classname {
  // width: 300px;
  // height: 300px;
}
</style>
src/views/login.vue
@@ -253,7 +253,7 @@
  // } catch (error) {
  //   console.log(error);
  // }
  router.push('index')
  // router.push('index')
});
</script>
vite.config.ts
@@ -40,7 +40,7 @@
        [env.VITE_APP_BASE_API]: {
          // target: 'http://162.14.79.111:2023',
          // target: 'http://172.35.50.34:8080',
          target: 'http://192.168.3.228:8080',
          target: 'http://127.0.0.1:8080',
          changeOrigin: true,
          rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
        }