vuex模块化 登录,oauth,agentSign模块

This commit is contained in:
aixianling
2022-06-13 17:21:40 +08:00
parent 0b157621ca
commit 4520a74627
4 changed files with 144 additions and 153 deletions

View File

@@ -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})
}
})
}
} }
} }
/** /**

View File

@@ -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]}) store.dispatch("agentSign", params).finally(() => app.$mount())
// app.$mount();
} else {
if (c < 5) {
setTimeout(() => {
init(++c)
}, 300)
}
}
}
init()
})

View File

@@ -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)
} }

View File

@@ -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({