vuex模块化 登录,oauth,agentSign模块
This commit is contained in:
		| @@ -1,6 +1,116 @@ | |||||||
| import http from "./http"; | import http from "./http"; | ||||||
| import Vue from "vue"; | 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) { |       for (const key in user) { | ||||||
|         Vue.set(state, key, user[key]) |         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) { |     initWaterMarker(state) { | ||||||
|       const waterMarked = document.querySelector('#waterMarker') |       const waterMarked = document.querySelector('#waterMarker') | ||||||
|       if (!waterMarked && state.user?.name) { |       if (!waterMarked && state?.name) { | ||||||
|         const waterMarker = document.createElement('div') |         const waterMarker = document.createElement('div') | ||||||
|         waterMarker.id = 'waterMarker' |         waterMarker.id = 'waterMarker' | ||||||
|         waterMarker.style.position = 'absolute' |         waterMarker.style.position = 'absolute' | ||||||
| @@ -63,7 +146,7 @@ export const waterMarker = { | |||||||
|           markerItem.style.height = '80px' |           markerItem.style.height = '80px' | ||||||
|           markerItem.style.transform = 'rotate(-20deg)' |           markerItem.style.transform = 'rotate(-20deg)' | ||||||
|           markerItem.style.flexShrink = '0' |           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) |           waterMarker.appendChild(markerItem) | ||||||
|         } |         } | ||||||
|         document.querySelector('uni-page-body')?.appendChild(waterMarker) |         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}) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| /** | /** | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								src/main.js
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/main.js
									
									
									
									
									
								
							| @@ -34,20 +34,9 @@ const app = new Vue({ | |||||||
|   store, |   store, | ||||||
|   ...App |   ...App | ||||||
| }); | }); | ||||||
| app.$mount(); | let params = {} | ||||||
| store.dispatch("agentSign").then(config => { | if (sessionStorage.getItem("prj")?.indexOf("saas") > -1) { | ||||||
|   const init = (c = 0) => { |   params = {action: "/app/wxcptp/portal/agentSign", corpId: "ww596787bb70f08288"} | ||||||
|     if (config) { |  | ||||||
|       store.commit("getConfig", {...config, latlng: [config.lat, config.lng]}) |  | ||||||
|       // app.$mount(); |  | ||||||
|     } else { |  | ||||||
|       if (c < 5) { |  | ||||||
|         setTimeout(() => { |  | ||||||
|           init(++c) |  | ||||||
|         }, 300) |  | ||||||
| } | } | ||||||
|     } | store.dispatch("agentSign", params).finally(() => app.$mount()) | ||||||
|   } |  | ||||||
|   init() |  | ||||||
| }) |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ export default { | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|     ...mapActions(['getToken']), |     ...mapActions(['getToken','getAccount']), | ||||||
|     ...mapMutations(['login', 'logout']), |     ...mapMutations(['login', 'logout']), | ||||||
|     handleLogin() { |     handleLogin() { | ||||||
|       this.$refs.loginForm.validate(v => { |       this.$refs.loginForm.validate(v => { | ||||||
| @@ -59,7 +59,11 @@ export default { | |||||||
|             corpId = 'ww2a667717a70164f1' |             corpId = 'ww2a667717a70164f1' | ||||||
|             module = 'wangge' |             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({}) |             this.target ? uni.reLaunch({url: this.target}) : uni.navigateBack({}) | ||||||
|           }).catch(() => 0) |           }).catch(() => 0) | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -2,16 +2,13 @@ import Vue from 'vue' | |||||||
| import Vuex from 'vuex' | import Vuex from 'vuex' | ||||||
| import perState from 'vuex-persistedstate' | import perState from 'vuex-persistedstate' | ||||||
| import http from '../common/axios' | import http from '../common/axios' | ||||||
| import CryptoJS from '../utils/crypto-js' |  | ||||||
| import * as modules from "../common/modules"; | import * as modules from "../common/modules"; | ||||||
|  |  | ||||||
| Vue.use(Vuex) | Vue.use(Vuex) | ||||||
| let agentSignURL = "", apiList = [] |  | ||||||
| const store = new Vuex.Store({ | const store = new Vuex.Store({ | ||||||
|   state: { |   state: { | ||||||
|     token: "", |     token: "", | ||||||
|     openUser: {}, |     openUser: {}, | ||||||
|     config: {}, |  | ||||||
|     apps: [] |     apps: [] | ||||||
|   }, |   }, | ||||||
|   mutations: { |   mutations: { | ||||||
| @@ -29,9 +26,6 @@ const store = new Vuex.Store({ | |||||||
|     setOpenUser(state, user) { |     setOpenUser(state, user) { | ||||||
|       state.openUser = user |       state.openUser = user | ||||||
|     }, |     }, | ||||||
|     getConfig(state, params) { |  | ||||||
|       state.config = params |  | ||||||
|     }, |  | ||||||
|     bindAccount(state, params) { |     bindAccount(state, params) { | ||||||
|       //具备解决二次登录,绑定手机,token等问题 |       //具备解决二次登录,绑定手机,token等问题 | ||||||
|       // http.post("/admin/user/cpBindByPhone", params, { |       // http.post("/admin/user/cpBindByPhone", params, { | ||||||
| @@ -45,72 +39,9 @@ const store = new Vuex.Store({ | |||||||
|           params?.then(res) |           params?.then(res) | ||||||
|         } else alert(res) |         } else alert(res) | ||||||
|       }).catch(err => alert(err)) |       }).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: { |   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) { |     getUserInfo(state, code) { | ||||||
|       if (code) { |       if (code) { | ||||||
|         return http.post("/app/wxcp/portal/getUserInfo", null, { |         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, |   modules, | ||||||
|   plugins: [perState({ |   plugins: [perState({ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user