vuex模块化 登录,oauth,agentSign模块
This commit is contained in:
		| @@ -1,6 +1,116 @@ | ||||
| import http from "./http"; | ||||
| import Vue from "vue"; | ||||
| import CryptoJS from "../utils/crypto-js"; | ||||
|  | ||||
| /** | ||||
|  * 登录方法 | ||||
|  */ | ||||
| export const config = { | ||||
|   state: () => ({}), | ||||
|   mutations: { | ||||
|     getConfig(state, params) { | ||||
|       for (const key in params) { | ||||
|         Vue.set(state, key, user[key]) | ||||
|       } | ||||
|     }, | ||||
|     clearConfig(state) { | ||||
|       for (const key in state) { | ||||
|         delete state[key] | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   actions: { | ||||
|     agentSign({state, commit}, params) { | ||||
|       //授权jssdk在url上使用,并获取corpId | ||||
|       let url = window.location.href | ||||
|       if (state.agentSignURL == url) { | ||||
|         return Promise.resolve() | ||||
|       } else { | ||||
|         commit("clearConfig") | ||||
|         commit("getConfig", {agentSignURL: url}) | ||||
|         let action = "/app/wxcp/portal/agentSign" | ||||
|         if (!!params.action) { | ||||
|           action = params.action | ||||
|           delete params.action | ||||
|         } | ||||
|         return http.post(action, null, { | ||||
|           withoutToken: true, | ||||
|           params: {...params, url} | ||||
|         }).then(res => { | ||||
|           if (res?.data) { | ||||
|             let config = { | ||||
|               ...params, | ||||
|               debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 | ||||
|               beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题 | ||||
|               corpid: res.data.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致 | ||||
|               agentid: res.data.agentId, // 必填,企业微信的应用id (e.g. 1000247) | ||||
|               timestamp: Number(res.data.timestamp), // 必填,生成签名的时间戳 | ||||
|               nonceStr: res.data.nonceStr, // 必填,生成签名的随机串 | ||||
|               signature: res.data.signature,// 必填,签名,见 附录-JS-SDK使用权限签名算法 | ||||
|               ...res.data, | ||||
|               agentSignURL: url | ||||
|             } | ||||
|             commit("getConfig", config) | ||||
|             return config | ||||
|           } | ||||
|         }).catch(err => { | ||||
|           console.error(err) | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|     getCode({state, dispatch}, tryAgentSign = false) { | ||||
|       let {corpId} = state.config, url = location.href, REDIRECT_URI = encodeURIComponent(url), scope = "snsapi_base" | ||||
|       if (/\/AppForm\//.test(location.search)) { | ||||
|         scope = "snsapi_userinfo" | ||||
|       } | ||||
|       return new Promise((resolve, reject) => { | ||||
|         if (corpId && scope) { | ||||
|           location.replace('https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE#wechat_redirect' | ||||
|           .replace(/APPID/g, cid) | ||||
|           .replace(/REDIRECT_URI/g, REDIRECT_URI) | ||||
|           .replace(/SCOPE/g, scope)) | ||||
|         } else if (!tryAgentSign) { | ||||
|           dispatch("agentSign").then(() => dispatch("getCode", true)) | ||||
|         } else reject("URL缺少必要参数(corpId)") | ||||
|       }) | ||||
|     }, | ||||
|     getToken({state, commit, dispatch}, params) { | ||||
|       const encryptByDES = password => { | ||||
|         let isIos = uni.getSystemInfoSync().system.toUpperCase == 'ios' | ||||
|         let key = "thanks,villcloud" | ||||
|         let iv = CryptoJS.enc.Latin1.parse(key) | ||||
|         let encrypted = CryptoJS.AES.encrypt(password, iv, { | ||||
|           iv: iv, | ||||
|           mode: CryptoJS.mode.CBC, | ||||
|           padding: CryptoJS.pad.ZeroPadding | ||||
|         }) | ||||
|         if (isIos) { | ||||
|           return encodeURIComponent(encrypted.toString()); | ||||
|         } else { | ||||
|           return encrypted.toString(); | ||||
|         } | ||||
|       } | ||||
|       let {module} = params | ||||
|       return http.post("/auth/oauth/token", null, { | ||||
|         withoutToken: true, | ||||
|         module, | ||||
|         params: { | ||||
|           ...params, grant_type: 'password', | ||||
|           password: encryptByDES(params.password) | ||||
|         }, | ||||
|         headers: { | ||||
|           Authorization: "Basic d2VjaGF0OndlY2hhdA==" | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res?.access_token) { | ||||
|           return [res?.token_type, res?.access_token].join(" ").trim() | ||||
|         } | ||||
|       }).catch(err => { | ||||
|         uni.showToast({title: err, icon: 'none'}) | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| /** | ||||
|  * 用户登录信息 | ||||
|  */ | ||||
| @@ -11,37 +121,10 @@ export const user = { | ||||
|       for (const key in user) { | ||||
|         Vue.set(state, key, user[key]) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   actions: { | ||||
|     getAccount({dispatch, commit}, config) { | ||||
|       //获取企业微信后台账号信息 | ||||
|       return http.post("/admin/user/detail-phone", null, config).then(res => { | ||||
|         if (res?.code == 0) { | ||||
|           commit('setUser', res.data) | ||||
|           return Promise.all([dispatch('getGridInfo', config)]) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     getGridInfo({commit}, config) { | ||||
|       //获取登录着网格员信息 | ||||
|       return http.post("/app/appgirdmemberinfo/checkLogOnUser", null, config).then(res => { | ||||
|         if (res?.data) { | ||||
|           let {girdId, girdMemberId, girdName, checkType: girdCheckType, appGirdInfo: gridInfo} = res.data | ||||
|           return commit("setUser", {girdId, girdMemberId, girdName, girdCheckType, gridInfo}) | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| /** | ||||
|  * 水印方法 | ||||
|  * */ | ||||
| export const waterMarker = { | ||||
|   mutations: { | ||||
|     initWaterMarker(state) { | ||||
|       const waterMarked = document.querySelector('#waterMarker') | ||||
|       if (!waterMarked && state.user?.name) { | ||||
|       if (!waterMarked && state?.name) { | ||||
|         const waterMarker = document.createElement('div') | ||||
|         waterMarker.id = 'waterMarker' | ||||
|         waterMarker.style.position = 'absolute' | ||||
| @@ -63,7 +146,7 @@ export const waterMarker = { | ||||
|           markerItem.style.height = '80px' | ||||
|           markerItem.style.transform = 'rotate(-20deg)' | ||||
|           markerItem.style.flexShrink = '0' | ||||
|           markerItem.innerText = state.user?.name + state.user?.phone?.slice(-4) || "未授权" | ||||
|           markerItem.innerText = state?.name + state?.phone?.slice(-4) || "未授权" | ||||
|           waterMarker.appendChild(markerItem) | ||||
|         } | ||||
|         document.querySelector('uni-page-body')?.appendChild(waterMarker) | ||||
| @@ -117,6 +200,26 @@ export const waterMarker = { | ||||
|       //     } | ||||
|       //   } | ||||
|     } | ||||
|   }, | ||||
|   actions: { | ||||
|     getAccount({dispatch, commit}, config) { | ||||
|       //获取企业微信后台账号信息 | ||||
|       return http.post("/admin/user/detail-phone", null, config).then(res => { | ||||
|         if (res?.code == 0) { | ||||
|           commit('setUser', res.data) | ||||
|           return Promise.all([dispatch('getGridInfo', config)]) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     getGridInfo({commit}, config) { | ||||
|       //获取登录着网格员信息 | ||||
|       return http.post("/app/appgirdmemberinfo/checkLogOnUser", null, config).then(res => { | ||||
|         if (res?.data) { | ||||
|           let {girdId, girdMemberId, girdName, checkType: girdCheckType, appGirdInfo: gridInfo} = res.data | ||||
|           return commit("setUser", {girdId, girdMemberId, girdName, girdCheckType, gridInfo}) | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| /** | ||||
|   | ||||
							
								
								
									
										21
									
								
								src/main.js
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/main.js
									
									
									
									
									
								
							| @@ -34,20 +34,9 @@ const app = new Vue({ | ||||
|   store, | ||||
|   ...App | ||||
| }); | ||||
| app.$mount(); | ||||
| store.dispatch("agentSign").then(config => { | ||||
|   const init = (c = 0) => { | ||||
|     if (config) { | ||||
|       store.commit("getConfig", {...config, latlng: [config.lat, config.lng]}) | ||||
|       // app.$mount(); | ||||
|     } else { | ||||
|       if (c < 5) { | ||||
|         setTimeout(() => { | ||||
|           init(++c) | ||||
|         }, 300) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   init() | ||||
| }) | ||||
| let params = {} | ||||
| if (sessionStorage.getItem("prj")?.indexOf("saas") > -1) { | ||||
|   params = {action: "/app/wxcptp/portal/agentSign", corpId: "ww596787bb70f08288"} | ||||
| } | ||||
| store.dispatch("agentSign", params).finally(() => app.$mount()) | ||||
|  | ||||
|   | ||||
| @@ -46,7 +46,7 @@ export default { | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions(['getToken']), | ||||
|     ...mapActions(['getToken','getAccount']), | ||||
|     ...mapMutations(['login', 'logout']), | ||||
|     handleLogin() { | ||||
|       this.$refs.loginForm.validate(v => { | ||||
| @@ -59,7 +59,11 @@ export default { | ||||
|             corpId = 'ww2a667717a70164f1' | ||||
|             module = 'wangge' | ||||
|           } | ||||
|           this.getToken({...this.form, module, corpId}).then(() => { | ||||
|           this.getToken({...this.form, module, corpId}).then(token => { | ||||
|             this.login(token) | ||||
|             if( module != 'AppCountryAlbum'){ | ||||
|               this.getAccount({module}) | ||||
|             } | ||||
|             this.target ? uni.reLaunch({url: this.target}) : uni.navigateBack({}) | ||||
|           }).catch(() => 0) | ||||
|         } | ||||
|   | ||||
| @@ -2,16 +2,13 @@ import Vue from 'vue' | ||||
| import Vuex from 'vuex' | ||||
| import perState from 'vuex-persistedstate' | ||||
| import http from '../common/axios' | ||||
| import CryptoJS from '../utils/crypto-js' | ||||
| import * as modules from "../common/modules"; | ||||
|  | ||||
| Vue.use(Vuex) | ||||
| let agentSignURL = "", apiList = [] | ||||
| const store = new Vuex.Store({ | ||||
|   state: { | ||||
|     token: "", | ||||
|     openUser: {}, | ||||
|     config: {}, | ||||
|     apps: [] | ||||
|   }, | ||||
|   mutations: { | ||||
| @@ -29,9 +26,6 @@ const store = new Vuex.Store({ | ||||
|     setOpenUser(state, user) { | ||||
|       state.openUser = user | ||||
|     }, | ||||
|     getConfig(state, params) { | ||||
|       state.config = params | ||||
|     }, | ||||
|     bindAccount(state, params) { | ||||
|       //具备解决二次登录,绑定手机,token等问题 | ||||
|       // http.post("/admin/user/cpBindByPhone", params, { | ||||
| @@ -45,72 +39,9 @@ const store = new Vuex.Store({ | ||||
|           params?.then(res) | ||||
|         } else alert(res) | ||||
|       }).catch(err => alert(err)) | ||||
|     }, | ||||
|     redirectCode(state, url = location.href) { | ||||
|       let REDIRECT_URI = encodeURIComponent(url), | ||||
|           corpid = state.config.corpid | ||||
|       const redirectTo = cid => { | ||||
|         location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base#wechat_redirect' | ||||
|         .replace(/CORPID/g, cid) | ||||
|         .replace(/REDIRECT_URI/g, REDIRECT_URI) | ||||
|       } | ||||
|       if (corpid) { | ||||
|         redirectTo(corpid) | ||||
|       } else { | ||||
|         store.dispatch("agentSign").then(() => { | ||||
|           corpid = state.config.corpid | ||||
|           redirectTo(corpid) | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     } | ||||
|   }, | ||||
|   actions: { | ||||
|     getToken(state, params) { | ||||
|       const encryptByDES = password => { | ||||
|         let isIos = uni.getSystemInfoSync().system.toUpperCase == 'ios' | ||||
|         let key = "thanks,villcloud" | ||||
|         let iv = CryptoJS.enc.Latin1.parse(key) | ||||
|         let encrypted = CryptoJS.AES.encrypt(password, iv, { | ||||
|           iv: iv, | ||||
|           mode: CryptoJS.mode.CBC, | ||||
|           padding: CryptoJS.pad.ZeroPadding | ||||
|         }) | ||||
|         if (isIos) { | ||||
|           return encodeURIComponent(encrypted.toString()); | ||||
|         } else { | ||||
|           return encrypted.toString(); | ||||
|         } | ||||
|       } | ||||
|       let {module} = params | ||||
|       return http.post("/auth/oauth/token", null, { | ||||
|         withoutToken: true, | ||||
|         module, | ||||
|         params: { | ||||
|           ...params, grant_type: 'password', | ||||
|           password: encryptByDES(params.password) | ||||
|         }, | ||||
|         headers: { | ||||
|           Authorization: "Basic d2VjaGF0OndlY2hhdA==" | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res?.access_token) { | ||||
|           state.commit("login", [res?.token_type, res?.access_token].join(" ").trim()) | ||||
|           return module != 'AppCountryAlbum' && state.dispatch("getAccount", {module}) | ||||
|         } | ||||
|       }).catch(err => { | ||||
|         uni.showToast({title: err, icon: 'none'}) | ||||
|       }) | ||||
|     }, | ||||
|     getCode(store, url) { | ||||
|       if (store.state.config?.corpid) { | ||||
|         store.commit('redirectCode', url) | ||||
|       } else { | ||||
|         store.dispatch('agentSign').then(() => { | ||||
|           store.commit('redirectCode', url) | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|     getUserInfo(state, code) { | ||||
|       if (code) { | ||||
|         return http.post("/app/wxcp/portal/getUserInfo", null, { | ||||
| @@ -129,42 +60,6 @@ const store = new Vuex.Store({ | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|     agentSign(state, params) { | ||||
|       let url = window.location.href | ||||
|       if (agentSignURL == url) { | ||||
|         return Promise.resolve() | ||||
|       } else { | ||||
|         agentSignURL = url | ||||
|         let action = "/app/wxcp/portal/agentSign" | ||||
|         if (sessionStorage.getItem("prj")?.indexOf("saas") > -1) { | ||||
|           params = {...params, corpId: "ww596787bb70f08288"} | ||||
|           action = "/app/wxcptp/portal/agentSign" | ||||
|         } | ||||
|         state.commit("getConfig", {}) | ||||
|         return http.post(action, null, { | ||||
|           withoutToken: true, | ||||
|           params: {...params, url} | ||||
|         }).then(res => { | ||||
|           if (res?.data) { | ||||
|             let config = { | ||||
|               ...params, | ||||
|               debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 | ||||
|               beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题 | ||||
|               corpid: res.data.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致 | ||||
|               agentid: res.data.agentId, // 必填,企业微信的应用id (e.g. 1000247) | ||||
|               timestamp: Number(res.data.timestamp), // 必填,生成签名的时间戳 | ||||
|               nonceStr: res.data.nonceStr, // 必填,生成签名的随机串 | ||||
|               signature: res.data.signature,// 必填,签名,见 附录-JS-SDK使用权限签名算法 | ||||
|               ...res.data, | ||||
|             } | ||||
|             state.commit("getConfig", config) | ||||
|             return config | ||||
|           } | ||||
|         }).catch(err => { | ||||
|           console.error(err) | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   modules, | ||||
|   plugins: [perState({ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user