From de28fd4ca4f041706fb90c1201acfb29f2679e06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= Date: Wed, 12 Oct 2022 19:00:26 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=89=8D=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E8=81=94=E8=B0=83=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yi-sqlsugar-dev.db | Bin 221184 -> 221184 bytes Yi.Vue3.x.Vant/package-lock.json | 106 ++++++++++++-- Yi.Vue3.x.Vant/package.json | 4 +- Yi.Vue3.x.Vant/src/api/login.ts | 59 ++++++++ Yi.Vue3.x.Vant/src/main.ts | 3 + Yi.Vue3.x.Vant/src/permission.ts | 67 +++++++++ Yi.Vue3.x.Vant/src/store/index.ts | 4 + Yi.Vue3.x.Vant/src/store/modules/user.ts | 80 +++++++++++ Yi.Vue3.x.Vant/src/utils/auth.ts | 13 ++ Yi.Vue3.x.Vant/src/utils/myaxios.ts | 9 +- Yi.Vue3.x.Vant/src/view/login.vue | 129 +++++++++++++----- Yi.Vue3.x.Vant/src/view/main/recommend.vue | 3 +- Yi.Vue3.x.Vant/src/view/main/square.vue | 127 ++++++++++------- 13 files changed, 507 insertions(+), 97 deletions(-) create mode 100644 Yi.Vue3.x.Vant/src/api/login.ts create mode 100644 Yi.Vue3.x.Vant/src/permission.ts create mode 100644 Yi.Vue3.x.Vant/src/store/index.ts create mode 100644 Yi.Vue3.x.Vant/src/store/modules/user.ts create mode 100644 Yi.Vue3.x.Vant/src/utils/auth.ts diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db index 4a83f9c66c4d4ef1890cbe081dc0125dfcabeba2..75ca88740a27f0e864cdee7dfa9f3c27c6cbf92a 100644 GIT binary patch delta 2720 zcma);TWAzl7{_O4HoMvDj7m&%HJ7FrlT6Na&Y6vuM4?TK#8NF3iV_hW#nPgc7AZ8B zB4R0O9_+Nx7cU4F8ig1FZPhd{BG|0xn=dKxp_C$0=tG58`t9!7WF^xvdCLFHH^2GL z|NGAQc4Q_qGLt#e5Lp;++!|RJ9XdV~nHthBK92UKuW5d=FETRO+R~Nwhc_Fs;d{59 z=$6)>He!*QNB8*qvzFFZ68Vw#F-zO5#IY~7SlT8fj^2fLHY%~+hIck7@#04i)~iH& z7Q%8$M4CXjB{BD>GiGTL#4vny?r{ewp&m^=1mP%g?f$H#aU~}2z!Rp#)p_00s1jFh z!V{vz!~_Ve#P?UWSQ=8|@>zJ&qr}NmAnccwI)OlSEAjcy@KTo&pPinyw9e`IfAx;l zxrS(7Gru-b_I7qp=I_ku%uDI(>7A)RQe&yQfZRh_`$dq^JB@X zb5$~$pKP_pqqSbY68+vUpX1&7j90d$^DH6onyc`2X_s{+Kf64F? zh0z?NHbt1bju=gDvSJN|J$Xxe$`{*Z?_NwO!T$J^zGit^t8VCAr3FCh*qjrL9O-Qg zNbBg`=X+G3U|S&S3Ws?c0w~a`As#8K8OdP|Ruk+n;q?Y!pvglp+_ z*_@la6Ov2W7l1GuafunC9u1&eonJwXfP#S{5E9ZO0hB8@SCk8Mor@tG?s_>40{3c&yGzC(VGCDa0j2H3UzZ7 zK`v4VmwVj-loKd~qKp9wkv0`jB+k9A01C{G5MwGZ%mz~sIP7%>U|{NmVAhnn7qY={ z#R!RzL#FpM8y6z=sl-#w{MHoNd^VlwOn;SLoBAnrAem1*g`xjzVt8~gWyUg{vBF(l z4Toi{w&v0ORmWiZ!Cj3B`{eMx!~5W0TC?yQm+s&HT&!&3s_~V$PV8<|XqR^GkEsJOUfvX%>IjF(6~u9) zIeOlY_Zc`H+aI&4E>!J^{u4b9b9#4l?Yqs{*t&R6ZP_L8DEVNEKeOH79Wac+1Q;~Z zq0Eu*G-YG0h0xxTp%5CUx_{;k!)Yys!bw7m4>lHv?azdfS>GBkdMd)$p@u@(u4lsV ztUokhY^w-EJL^?`6(7ZVF~6lSDh|~xr*)6{-@R#UOD*O`==A;944g2Uv!8+=k&V-< zXY|3;B(i?ji>?h6_HJp-r5{9v-C0^wSrBNE#GkUw*|tCZ z%Oo!(!NQlwz(0fEfbS%b!N8yc#M(ft1ytzDw>?pgc`>5|7uR_P{yF^SeCPRic(r+^ z@rZHn;m+VX4^*?6Yx{XEW>ePfEDIPL_@}qnGdD0xuw9=4.4.4", + "vue": "^2.6.14 || ^3.2.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/vue-demi": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", + "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/postcss": { "version": "8.4.17", "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.17.tgz", @@ -1351,7 +1403,7 @@ "version": "4.8.4", "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1513,6 +1565,17 @@ "typescript": "*" } }, + "node_modules/vuex": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz", + "integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==", + "dependencies": { + "@vue/devtools-api": "^6.0.0-beta.11" + }, + "peerDependencies": { + "vue": "^3.0.2" + } + }, "node_modules/webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz", @@ -1748,9 +1811,9 @@ } }, "@vue/devtools-api": { - "version": "6.4.3", - "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.4.3.tgz", - "integrity": "sha512-9WCRwdROJvWcHAdyrR7SZMM/qUvllDZnpndHXokThkUsjnJ2xe4/pvsH9FZrxFe22L+JmDKczL79HjLJ7DK9rg==" + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.4.tgz", + "integrity": "sha512-Ku31WzpOV/8cruFaXaEZKF81WkNnvCSlBY4eOGtz5WMSdJvX1v1WWlSMGZeqUwPtQ27ZZz7B62erEMq8JDjcXw==" }, "@vue/reactivity": { "version": "3.2.40", @@ -2308,6 +2371,23 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pinia": { + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.23.tgz", + "integrity": "sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==", + "requires": { + "@vue/devtools-api": "^6.4.4", + "vue-demi": "*" + }, + "dependencies": { + "vue-demi": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", + "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "requires": {} + } + } + }, "postcss": { "version": "8.4.17", "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.17.tgz", @@ -2416,7 +2496,7 @@ "version": "4.8.4", "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true + "devOptional": true }, "unplugin": { "version": "0.9.6", @@ -2512,6 +2592,14 @@ "@volar/vue-typescript": "0.40.13" } }, + "vuex": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz", + "integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==", + "requires": { + "@vue/devtools-api": "^6.0.0-beta.11" + } + }, "webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz", diff --git a/Yi.Vue3.x.Vant/package.json b/Yi.Vue3.x.Vant/package.json index a715b5b4..1042a10b 100644 --- a/Yi.Vue3.x.Vant/package.json +++ b/Yi.Vue3.x.Vant/package.json @@ -11,9 +11,11 @@ "dependencies": { "axios": "^1.1.2", "json-bigint": "^1.0.0", + "pinia": "^2.0.23", "vant": "^3.6.3", "vue": "^3.2.37", - "vue-router": "^4.1.5" + "vue-router": "^4.1.5", + "vuex": "^4.0.2" }, "devDependencies": { "@types/json-bigint": "^1.0.1", diff --git a/Yi.Vue3.x.Vant/src/api/login.ts b/Yi.Vue3.x.Vant/src/api/login.ts new file mode 100644 index 00000000..0fdae247 --- /dev/null +++ b/Yi.Vue3.x.Vant/src/api/login.ts @@ -0,0 +1,59 @@ +import myaxios from '@/utils/myaxios.ts' + +// 登录方法 +export function login(username:string, password:string, code:string, uuid:string) { + const data = { + username, + password, + code, + uuid + } + return myaxios({ + url: '/account/login', + headers: { + isToken: false + }, + method: 'post', + data: data + }) +} + +// 注册方法 +export function register(data:any) { + return myaxios({ + url: '/register', + headers: { + isToken: false + }, + method: 'post', + data: data + }) +} + +// 获取用户详细信息 +export function getInfo() { + return myaxios({ + url: '/account/getUserAllInfo', + method: 'get' + }) +} + +// 退出方法 +export function logout() { + return myaxios({ + url: '/account/logout', + method: 'post' + }) +} + +// 获取验证码 +export function getCodeImg() { + return myaxios({ + url: '/account/captchaImage', + headers: { + isToken: false + }, + method: 'get', + timeout: 20000 + }) +} \ No newline at end of file diff --git a/Yi.Vue3.x.Vant/src/main.ts b/Yi.Vue3.x.Vant/src/main.ts index c67a29ae..4582cc72 100644 --- a/Yi.Vue3.x.Vant/src/main.ts +++ b/Yi.Vue3.x.Vant/src/main.ts @@ -2,8 +2,11 @@ import { createApp } from 'vue' import './style.css' import 'vant/es/image-preview/style'; import router from './router' +import store from './store' +import './permission' import App from './App.vue' const app=createApp(App) app.use(router) +app.use(store) app.mount('#app'); \ No newline at end of file diff --git a/Yi.Vue3.x.Vant/src/permission.ts b/Yi.Vue3.x.Vant/src/permission.ts new file mode 100644 index 00000000..596daa6c --- /dev/null +++ b/Yi.Vue3.x.Vant/src/permission.ts @@ -0,0 +1,67 @@ +import router from './router' +// import { ElMessage } from 'element-plus' +// import NProgress from 'nprogress' +// import 'nprogress/nprogress.css' +import { getToken } from '@/utils/auth' +// import { isHttp } from '@/utils/validate' +// import { isRelogin } from '@/utils/request' +import useUserStore from '@/store/modules/user' +// import useSettingsStore from '@/store/modules/settings' +// import usePermissionStore from '@/store/modules/permission' + +// NProgress.configure({ showSpinner: false }); + +const whiteList = ['/square', '/auth-redirect', '/bind', '/register']; + +router.beforeEach((to, from, next) => { + // NProgress.start() + if (getToken()) { + // to.meta.title && useSettingsStore().setTitle(to.meta.title) + /* has token*/ + if (to.path === '/square') { + next({ path: '/' }) + // NProgress.done() + } else { + useUserStore().getInfo(); + next() + // if (useUserStore().roles.length === 0) + // { + // // isRelogin.show = true + // // 判断当前用户是否已拉取完user_info信息 + // useUserStore().getInfo().then(() => { + // // isRelogin.show = false + // next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + // // usePermissionStore().generateRoutes().then(accessRoutes => { + // // // 根据roles权限生成可访问的路由表 + // // accessRoutes.forEach(route => { + // // if (!isHttp(route.path)) { + // // router.addRoute(route) // 动态添加可访问路由表 + // // } + // // }) + + // // }) + // }).catch(err => { + // useUserStore().logOut().then(() => { + // // ElMessage.error(err) + // next({ path: '/' }) + // }) + // }) + // } else { + // next() + // } + } + } else { + // 没有token + if (whiteList.indexOf(to.path) !== -1) { + // 在免登录白名单,直接进入 + next() + } else { + next(`/square?redirect=${to.fullPath}`) // 否则全部重定向到登录页 + // NProgress.done() + } + } +}) + +router.afterEach(() => { + // NProgress.done() +}) diff --git a/Yi.Vue3.x.Vant/src/store/index.ts b/Yi.Vue3.x.Vant/src/store/index.ts new file mode 100644 index 00000000..2e68d207 --- /dev/null +++ b/Yi.Vue3.x.Vant/src/store/index.ts @@ -0,0 +1,4 @@ +import { createPinia } from 'pinia' +const store = createPinia() + +export default store \ No newline at end of file diff --git a/Yi.Vue3.x.Vant/src/store/modules/user.ts b/Yi.Vue3.x.Vant/src/store/modules/user.ts new file mode 100644 index 00000000..fc5f83a6 --- /dev/null +++ b/Yi.Vue3.x.Vant/src/store/modules/user.ts @@ -0,0 +1,80 @@ +import { login, logout, getInfo } from '@/api/login' +import { getToken, setToken, removeToken } from '@/utils/auth' +// import defAva from '@/assets/images/profile.jpg' +import {defineStore} from 'pinia' +const useUserStore = defineStore( + 'user', + { + state: () => ({ + token: getToken(), + name: '', + avatar: '', + roles: [], + permissions: [] + }), + actions: { + // 登录 + login(userInfo) { + const username = userInfo.username.trim() + const password = userInfo.password + const code = userInfo.code + const uuid = userInfo.uuid + return new Promise((resolve, reject) => { + + login(username, password, code, uuid).then(res => { + setToken(res.data.token); + this.token = res.data.token; + resolve(); + }).catch(error => { + reject(error) + }) + }) + }, + // 获取用户信息 + getInfo() { + return new Promise((resolve, reject) => { + getInfo().then(response => { + const res=response.data; + const user = res.user + // const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar; + + if (res.roleCodes && res.roleCodes.length > 0) { // 验证返回的roles是否是一个非空数组 + this.roles = res.roleCodes + this.permissions = res.permissionCodes + // this.roles = ["admin"]; + // this.permissions=["*:*:*"] + + } else { + this.roles = ['ROLE_DEFAULT'] + } + // this.roles = ["admin"]; + // this.permissions=["*:*:*"] + this.name = user.userName + this.avatar = avatar; + resolve(res) + }).catch(error => { + reject(error) + }) + + + + }) + }, + // 退出系统 + logOut() { + return new Promise((resolve, reject) => { + logout(this.token).then(() => { + this.token = '' + this.roles = [] + this.permissions = [] + removeToken() + resolve() + }).catch(error => { + reject(error) + }) + }) + } + } + }) + +export default useUserStore diff --git a/Yi.Vue3.x.Vant/src/utils/auth.ts b/Yi.Vue3.x.Vant/src/utils/auth.ts new file mode 100644 index 00000000..64a302e3 --- /dev/null +++ b/Yi.Vue3.x.Vant/src/utils/auth.ts @@ -0,0 +1,13 @@ +const TokenKey = 'Admin-Token' + +export function getToken() { + return localStorage.getItem(TokenKey) +} + +export function setToken(token:string) { + return localStorage.setItem(TokenKey, token) +} + +export function removeToken() { + return localStorage.removeItem(TokenKey) +} diff --git a/Yi.Vue3.x.Vant/src/utils/myaxios.ts b/Yi.Vue3.x.Vant/src/utils/myaxios.ts index 71fc0de8..2da5e11c 100644 --- a/Yi.Vue3.x.Vant/src/utils/myaxios.ts +++ b/Yi.Vue3.x.Vant/src/utils/myaxios.ts @@ -2,6 +2,7 @@ import axios from 'axios' // import store from '../store/index' // import vm from '../main' import JsonBig from 'json-bigint' +import { getToken } from '@/utils/auth' // import VuetifyDialogPlugin from 'vuetify-dialog/nuxt/index'; const myaxios = axios.create({ // baseURL:'/'// @@ -20,8 +21,12 @@ const myaxios = axios.create({ }) // 请求拦截器 myaxios.interceptors.request.use(function(config) { - - // config.headers.Authorization = 'Bearer ' + store.state.user.token; + const isToken = (config.headers || {}).isToken === false + // 是否需要防止数据重复提交 + const isRepeatSubmit = (config.headers || {}).repeatSubmit === false + if (getToken() && !isToken) { + config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 + } // store.dispatch("openLoad"); return config; }, function(error) { diff --git a/Yi.Vue3.x.Vant/src/view/login.vue b/Yi.Vue3.x.Vant/src/view/login.vue index ce9dc851..7376c6de 100644 --- a/Yi.Vue3.x.Vant/src/view/login.vue +++ b/Yi.Vue3.x.Vant/src/view/login.vue @@ -1,35 +1,100 @@ - - \ No newline at end of file + top: 0; + left: 0; + right: 0; + bottom: 60%; + + } + .div-bottom{ + background-color: bisque; + position:absolute; + top: 25%; + left: 0; + right: 0; + bottom: 0; + border-radius: 3rem 3rem 0rem 0rem; + padding: 1rem 2rem 2rem 2rem; + + /* min-height: 70%; */ + } + .title{ + position: absolute; + top: 15%; + transform: translateX(-50%); + font-size: 1.8rem; + font-weight: bolder; + } + .subtitle + { + transform: translateX(-50%); + position: absolute; + top: 30%; + font-weight:lighter; + } + .van-field-username + { + margin-top:2rem; + } + .van-field-password + { + margin-top: 1rem; + } + h5{ + text-align: left; + font-size: 1.2rem; + font-weight: bolder; + } + .div-bottom .van-button + { + margin-top: 1rem; + width: 100%; + border-radius: 0.4rem; + } + .div-bottom p{ + text-align: center; + + }; + .row-bottom{ + + + } + \ No newline at end of file diff --git a/Yi.Vue3.x.Vant/src/view/main/recommend.vue b/Yi.Vue3.x.Vant/src/view/main/recommend.vue index 42413036..cd11abd6 100644 --- a/Yi.Vue3.x.Vant/src/view/main/recommend.vue +++ b/Yi.Vue3.x.Vant/src/view/main/recommend.vue @@ -1,5 +1,6 @@ \ No newline at end of file