index.html | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
package.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/App.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/api/system/user/index.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/assets/ddlogin.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/permission.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/router/index.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/dingdingLogin copy.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/dingdingLogin.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/login.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
vite.config.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
index.html
@@ -1,217 +1,221 @@ <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="renderer" content="webkit" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> <link rel="icon" href="/favicon.ico" /> <title>跨网文件同步系统</title> <!--[if lt IE 11 <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="renderer" content="webkit" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> <link rel="icon" href="/favicon.ico" /> <title>跨网文件同步系统</title> <!--[if lt IE 11 ]><script> window.location.href='/html/ie.html'; </script><! [endif]--> <style> html, body, #app { height: 100%; margin: 0px; padding: 0px; <style> html, body, #app { height: 100%; margin: 0px; padding: 0px; } .chromeframe { margin: 0.2em 0; background: #ccc; color: #000; padding: 0.2em 0; } #loader-wrapper { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 999999; } #loader { display: block; position: relative; left: 50%; top: 50%; width: 150px; height: 150px; margin: -75px 0 0 -75px; border-radius: 50%; border: 3px solid transparent; border-top-color: #FFF; -webkit-animation: spin 2s linear infinite; -ms-animation: spin 2s linear infinite; -moz-animation: spin 2s linear infinite; -o-animation: spin 2s linear infinite; animation: spin 2s linear infinite; z-index: 1001; } #loader:before { content: ""; position: absolute; top: 5px; left: 5px; right: 5px; bottom: 5px; border-radius: 50%; border: 3px solid transparent; border-top-color: #FFF; -webkit-animation: spin 3s linear infinite; -moz-animation: spin 3s linear infinite; -o-animation: spin 3s linear infinite; -ms-animation: spin 3s linear infinite; animation: spin 3s linear infinite; } #loader:after { content: ""; position: absolute; top: 15px; left: 15px; right: 15px; bottom: 15px; border-radius: 50%; border: 3px solid transparent; border-top-color: #FFF; -moz-animation: spin 1.5s linear infinite; -o-animation: spin 1.5s linear infinite; -ms-animation: spin 1.5s linear infinite; -webkit-animation: spin 1.5s linear infinite; animation: spin 1.5s linear infinite; } @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); -ms-transform: rotate(0deg); transform: rotate(0deg); } .chromeframe { margin: 0.2em 0; background: #ccc; color: #000; padding: 0.2em 0; 100% { -webkit-transform: rotate(360deg); -ms-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes spin { 0% { -webkit-transform: rotate(0deg); -ms-transform: rotate(0deg); transform: rotate(0deg); } #loader-wrapper { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 999999; 100% { -webkit-transform: rotate(360deg); -ms-transform: rotate(360deg); transform: rotate(360deg); } #loader { display: block; position: relative; left: 50%; top: 50%; width: 150px; height: 150px; margin: -75px 0 0 -75px; border-radius: 50%; border: 3px solid transparent; border-top-color: #FFF; -webkit-animation: spin 2s linear infinite; -ms-animation: spin 2s linear infinite; -moz-animation: spin 2s linear infinite; -o-animation: spin 2s linear infinite; animation: spin 2s linear infinite; z-index: 1001; } #loader:before { content: ""; position: absolute; top: 5px; left: 5px; right: 5px; bottom: 5px; border-radius: 50%; border: 3px solid transparent; border-top-color: #FFF; -webkit-animation: spin 3s linear infinite; -moz-animation: spin 3s linear infinite; -o-animation: spin 3s linear infinite; -ms-animation: spin 3s linear infinite; animation: spin 3s linear infinite; } #loader:after { content: ""; position: absolute; top: 15px; left: 15px; right: 15px; bottom: 15px; border-radius: 50%; border: 3px solid transparent; border-top-color: #FFF; -moz-animation: spin 1.5s linear infinite; -o-animation: spin 1.5s linear infinite; -ms-animation: spin 1.5s linear infinite; -webkit-animation: spin 1.5s linear infinite; animation: spin 1.5s linear infinite; } } @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); -ms-transform: rotate(0deg); transform: rotate(0deg); } #loader-wrapper .loader-section { position: fixed; top: 0; width: 51%; height: 100%; background: #23b385; z-index: 1000; -webkit-transform: translateX(0); -ms-transform: translateX(0); transform: translateX(0); } 100% { -webkit-transform: rotate(360deg); -ms-transform: rotate(360deg); transform: rotate(360deg); } } #loader-wrapper .loader-section.section-left { left: 0; } @keyframes spin { 0% { -webkit-transform: rotate(0deg); -ms-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); -ms-transform: rotate(360deg); transform: rotate(360deg); } } #loader-wrapper .loader-section.section-right { right: 0; } #loader-wrapper .loader-section { position: fixed; top: 0; width: 51%; height: 100%; background: #23b385; z-index: 1000; -webkit-transform: translateX(0); -ms-transform: translateX(0); transform: translateX(0); } .loaded #loader-wrapper .loader-section.section-left { -webkit-transform: translateX(-100%); -ms-transform: translateX(-100%); transform: translateX(-100%); -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); } #loader-wrapper .loader-section.section-left { left: 0; } .loaded #loader-wrapper .loader-section.section-right { -webkit-transform: translateX(100%); -ms-transform: translateX(100%); transform: translateX(100%); -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); } #loader-wrapper .loader-section.section-right { right: 0; } .loaded #loader { opacity: 0; -webkit-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } .loaded #loader-wrapper { visibility: hidden; -webkit-transform: translateY(-100%); -ms-transform: translateY(-100%); transform: translateY(-100%); -webkit-transition: all 0.3s 1s ease-out; transition: all 0.3s 1s ease-out; } .loaded #loader-wrapper .loader-section.section-left { -webkit-transform: translateX(-100%); -ms-transform: translateX(-100%); transform: translateX(-100%); -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); } .no-js #loader-wrapper { display: none; } .loaded #loader-wrapper .loader-section.section-right { -webkit-transform: translateX(100%); -ms-transform: translateX(100%); transform: translateX(100%); -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); } .no-js h1 { color: #222222; } .loaded #loader { opacity: 0; -webkit-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } #loader-wrapper .load_title { font-family: 'Open Sans'; color: #FFF; font-size: 19px; width: 100%; text-align: center; z-index: 9999999999999; position: absolute; top: 60%; opacity: 1; line-height: 30px; } .loaded #loader-wrapper { visibility: hidden; -webkit-transform: translateY(-100%); -ms-transform: translateY(-100%); transform: translateY(-100%); -webkit-transition: all 0.3s 1s ease-out; transition: all 0.3s 1s ease-out; } #loader-wrapper .load_title span { font-weight: normal; font-style: italic; font-size: 13px; color: #FFF; opacity: 0.5; } </style> </head> <script src="./src/assets/ddlogin.js"></script> <!-- <script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script> --> .no-js #loader-wrapper { display: none; } .no-js h1 { color: #222222; } #loader-wrapper .load_title { font-family: 'Open Sans'; color: #FFF; font-size: 19px; width: 100%; text-align: center; z-index: 9999999999999; position: absolute; top: 60%; opacity: 1; line-height: 30px; } #loader-wrapper .load_title span { font-weight: normal; font-style: italic; font-size: 13px; color: #FFF; opacity: 0.5; } </style> </head> <body> <div id="app"> <div id="loader-wrapper"> <div id="loader"></div> <div class="loader-section section-left"></div> <div class="loader-section section-right"></div> <div class="load_title">正在加载文件系统资源,请稍后</div> </div> <body> <div id="app"> <div id="loader-wrapper"> <div id="loader"></div> <div class="loader-section section-left"></div> <div class="loader-section section-right"></div> <div class="load_title">正在加载文件系统资源,请稍后</div> </div> <script type="module" src="/src/main.ts"></script> </body> </html> </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) { isRelogin.show = true; // 判断当前用户是否已拉取完user_info信息 // if (useUserStore().roles.length === 0) { isRelogin.show = true; // // 判断当前用户是否已拉取完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 { next(); } // 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), '') }