394 lines
13 KiB
JavaScript
394 lines
13 KiB
JavaScript
import Vue from 'vue'
|
||
import Vuex from 'vuex'
|
||
import perState from 'vuex-persistedstate'
|
||
import http from '../common/axios'
|
||
import CryptoJS from '../utils/crypto-js'
|
||
|
||
Vue.use(Vuex)
|
||
let agentSignURL = "", apiList = []
|
||
const store = new Vuex.Store({
|
||
state: {
|
||
token: "",
|
||
corpId: "",
|
||
openUser: {},
|
||
user: {},
|
||
config: {}
|
||
},
|
||
mutations: {
|
||
login(state, token) {
|
||
state.token = token
|
||
},
|
||
logout(state) {
|
||
state.token = ""
|
||
state.openUser = {}
|
||
},
|
||
setUser(state, user) {
|
||
state.user = user
|
||
},
|
||
setOpenUser(state, user) {
|
||
state.openUser = user
|
||
},
|
||
getConfig(state, params) {
|
||
state.config = params
|
||
},
|
||
bindAccount(state, params) {
|
||
//具备解决二次登录,绑定手机,token等问题
|
||
// http.post("/admin/user/cpBindByPhone", params, {
|
||
http.post("/auth/wechatcp/token", {customerLogin: 1, ...params}, {
|
||
headers: {
|
||
Authorization: "Basic d2VjaGF0OndlY2hhdA=="
|
||
},
|
||
withoutToken: true
|
||
}).then(res => {
|
||
if (res?.access_token) {
|
||
params?.then(res)
|
||
} else alert(res)
|
||
}).catch(err => alert(err))
|
||
},
|
||
setDicts(state, payload) {
|
||
if (payload) {
|
||
payload.map(p => {
|
||
if (state.dicts.some(d => d.key == p.key)) {
|
||
const index = state.dicts.findIndex(d => d.key == p.key)
|
||
state.dicts.splice(index, 1)
|
||
state.dicts.push(p)
|
||
} else {
|
||
state.dicts.push(p)
|
||
}
|
||
})
|
||
}
|
||
},
|
||
redirectCode(state, url = location.href) {
|
||
let REDIRECT_URI = encodeURIComponent(url),
|
||
corpid = state.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.corpId
|
||
redirectTo(corpid)
|
||
})
|
||
}
|
||
},
|
||
initWaterMarker(state) {
|
||
const waterMarked = document.querySelector('#waterMarker')
|
||
if (!waterMarked && state.user?.name) {
|
||
const waterMarker = document.createElement('div')
|
||
for (let i = 0; i < 200; i++) {
|
||
let markerItem = document.createElement('div')
|
||
markerItem.style.fontSize = '14px'
|
||
markerItem.style.padding = '30px'
|
||
markerItem.style.height = '80px'
|
||
markerItem.style.transform = 'rotate(-20deg)'
|
||
markerItem.style.flexShrink = '0'
|
||
markerItem.innerText = state.user?.name + state.user?.phone?.slice(-4) || "未授权"
|
||
|
||
waterMarker.appendChild(markerItem)
|
||
}
|
||
if (waterMarker) {
|
||
waterMarker.id = 'waterMarker'
|
||
waterMarker.style.position = 'absolute'
|
||
waterMarker.style.display = 'flex'
|
||
waterMarker.style.flexWrap = 'wrap'
|
||
waterMarker.style.overflow = 'hidden'
|
||
waterMarker.style.justifyContent = 'space-between'
|
||
waterMarker.style.alignContent = 'flex-start'
|
||
waterMarker.style.zIndex = '2'
|
||
waterMarker.style.top = '0'
|
||
waterMarker.style.color = 'rgba(153,153,153,.2)'
|
||
waterMarker.style.width = '100%'
|
||
waterMarker.style.height = '100%'
|
||
waterMarker.style.pointerEvents = 'none'
|
||
document.querySelector('uni-page-body')?.appendChild(waterMarker)
|
||
}
|
||
}
|
||
// canvas 方案
|
||
// const HiDPICanvas = (w, h, ratio) => {
|
||
// const PIXEL_RATIO = () => {
|
||
// const c = document.createElement("canvas"),
|
||
// ctx = c.getContext("2d"),
|
||
// dpr = window.devicePixelRatio || 1,
|
||
// bsr = ctx['webkitBackingStorePixelRatio'] ||
|
||
// ctx['mozBackingStorePixelRatio'] ||
|
||
// ctx['msBackingStorePixelRatio'] ||
|
||
// ctx['oBackingStorePixelRatio'] ||
|
||
// ctx['backingStorePixelRatio'] || 1;
|
||
//
|
||
// return dpr / bsr;
|
||
// }
|
||
// if (!ratio) {
|
||
// ratio = PIXEL_RATIO();
|
||
// }
|
||
// const can = document.createElement("canvas");
|
||
// can.width = w * ratio;
|
||
// can.height = h * ratio;
|
||
// can.style.width = w + "px";
|
||
// can.style.height = h + "px";
|
||
// can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
|
||
// return can
|
||
// }
|
||
// if (!waterMarked && state.user?.name) {
|
||
// const canvas = HiDPICanvas(100, 40)
|
||
// canvas.style.display = 'none';
|
||
// let ctx = canvas.getContext("2d")
|
||
// ctx.rotate(-20 * Math.PI / 180);
|
||
// ctx.fillStyle = 'rgba(153,153,153,.3)';
|
||
// ctx.textAlign = 'left';
|
||
// ctx.textBaseline = 'middle';
|
||
// ctx.font = "lighter 7px 'Microsoft YaHei UI',sans-serif"
|
||
// ctx.fillText(state.user?.name + state.user?.phone?.slice(-4) || "未授权", 0, 30);
|
||
// const waterMarker = document.createElement('div')
|
||
// if (waterMarker) {
|
||
// waterMarker.id = 'waterMarker'
|
||
// waterMarker.style.position = 'absolute'
|
||
// waterMarker.style.zIndex = '2'
|
||
// waterMarker.style.top = '0'
|
||
// waterMarker.style.width = '100%'
|
||
// waterMarker.style.height = '100%'
|
||
// waterMarker.style.pointerEvents = 'none'
|
||
// waterMarker.style.backgroundImage = "url(" + canvas.toDataURL("image/png") + ")"
|
||
// document.querySelector('uni-page-body').appendChild(waterMarker)
|
||
// }
|
||
// }
|
||
}
|
||
},
|
||
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();
|
||
}
|
||
}
|
||
return new Promise((resolve, reject) => {
|
||
http.post("/auth/oauth/token", null, {
|
||
withoutToken: true,
|
||
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())
|
||
state.dispatch("getAccount")
|
||
resolve()
|
||
}
|
||
}).catch(err => {
|
||
uni.showToast({title: err, icon: 'none'})
|
||
reject()
|
||
})
|
||
})
|
||
},
|
||
getCode(store, url) {
|
||
if (store.state.config?.corpid) {
|
||
store.commit('redirectCode', url)
|
||
} else {
|
||
store.dispatch('agentSign').then(() => {
|
||
store.commit('redirectCode', url)
|
||
})
|
||
}
|
||
},
|
||
getAccount(state) {
|
||
//获取企业微信后台账号信息
|
||
return http.post("/admin/user/detail-phone").then(res => {
|
||
if (res?.code == 0) {
|
||
state.commit('setUser', res.data)
|
||
this.$action.getGridInfo()
|
||
}
|
||
})
|
||
},
|
||
getUserInfo(state, code) {
|
||
if (code) {
|
||
return http.post("/app/wxcp/portal/getUserInfo", null, {
|
||
params: {code}, withoutToken: true
|
||
}).then(res => {
|
||
if (res?.code == 0) {
|
||
state.commit("setOpenUser", res.data)
|
||
}
|
||
})
|
||
} else {
|
||
return http.post("/app/wxcp/wxuser/getUserInfoByToken")
|
||
.then(res => {
|
||
if (res?.code == 0) {
|
||
state.commit("setOpenUser", res.data)
|
||
}
|
||
})
|
||
}
|
||
},
|
||
agentSign(state, params) {
|
||
let url = window.location.href
|
||
if (agentSignURL == url) {
|
||
return Promise.resolve()
|
||
} else {
|
||
agentSignURL = url
|
||
if (sessionStorage.getItem("prj")?.indexOf("saas") > -1) {
|
||
params = {...params, corpId: "ww596787bb70f08288"}
|
||
}
|
||
return http.post("/app/wxcp/portal/agentSign", 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)
|
||
})
|
||
}
|
||
},
|
||
injectJWeixin(state, ops) {
|
||
const inject = (jsApiList, config = state.state.config) => new Promise((resolve, reject) => {
|
||
setTimeout(() => {
|
||
let sdk = wx?.agentConfig ? wx : jWeixin
|
||
sdk?.agentConfig({
|
||
...config, jsApiList,
|
||
success: res => resolve(res),
|
||
fail: err => {
|
||
console.error(err)
|
||
reject(err)
|
||
}
|
||
})
|
||
}, 500)
|
||
})
|
||
return new Promise((resolve, reject) => {
|
||
state.dispatch("agentSign").then(config => {
|
||
if (typeof ops == "object") {
|
||
ops?.map(api => {
|
||
if (!apiList?.includes(api)) apiList.push(api)
|
||
})
|
||
} else {
|
||
if (!apiList?.includes(ops)) apiList.push(ops)
|
||
}
|
||
inject(apiList, config).then(r => resolve(r)).catch(err => reject(err))
|
||
})
|
||
})
|
||
},
|
||
wxInvoke(state, op) {
|
||
setTimeout(() => {
|
||
let sdk = typeof wx?.invoke == 'function' ? wx : jWeixin
|
||
sdk?.invoke(op?.[0], op?.[1], op?.[2])
|
||
}, 500)
|
||
},
|
||
previewFile(state, op) {
|
||
if (window.navigator.userAgent.indexOf("Windows NT") > -1) {
|
||
uni.showToast({
|
||
title: "企业微信暂不支持PC端的预览文件!",
|
||
icon: 'none'
|
||
})
|
||
} else {
|
||
state.dispatch("injectJWeixin", "previewFile").then(() => {
|
||
setTimeout(() => {
|
||
let sdk = typeof wx?.invoke == 'function' ? wx : jWeixin
|
||
sdk?.invoke('previewFile', {...op}, res => {
|
||
console.log(res)
|
||
})
|
||
}, 500)
|
||
})
|
||
}
|
||
},
|
||
closeAgent(state) {
|
||
state.dispatch("injectJWeixin", "closeWindow").then(() => {
|
||
setTimeout(() => {
|
||
let sdk = typeof wx?.closeWindow == 'function' ? wx : jWeixin
|
||
sdk?.closeWindow()
|
||
}, 500)
|
||
})
|
||
},
|
||
selectEnterpriseContact(state, params) {
|
||
return new Promise((resolve, reject) => {
|
||
state.dispatch("injectJWeixin", "selectEnterpriseContact").then(() => {
|
||
setTimeout(() => {
|
||
let sdk = typeof wx?.invoke == 'function' ? wx : jWeixin
|
||
sdk?.invoke("selectEnterpriseContact", {
|
||
fromDepartmentId: -1,
|
||
mode: "multi",
|
||
type: ["user"],
|
||
...params
|
||
}, res => {
|
||
if (res.err_msg == "selectEnterpriseContact:ok") {
|
||
if (typeof res.result == 'string') {
|
||
res.result = JSON.parse(res.result)
|
||
}
|
||
resolve(res.result)
|
||
} else {
|
||
reject(res)
|
||
}
|
||
})
|
||
}, 500)
|
||
})
|
||
})
|
||
},
|
||
selectPrivilegedContact(state, params) {
|
||
return new Promise((resolve, reject) => {
|
||
state.dispatch("injectJWeixin", "selectPrivilegedContact").then(() => {
|
||
setTimeout(() => {
|
||
let sdk = typeof wx?.invoke == 'function' ? wx : jWeixin
|
||
sdk?.invoke("selectPrivilegedContact", {
|
||
fromDepartmentId: -1,
|
||
mode: "multi",
|
||
...params
|
||
}, res => {
|
||
if (res.err_msg == "selectPrivilegedContact:ok") {
|
||
if (typeof res.result == 'string') {
|
||
res.result = JSON.parse(res.result)
|
||
}
|
||
resolve(res.result)
|
||
} else {
|
||
reject(res)
|
||
}
|
||
})
|
||
}, 300)
|
||
}).catch(() => {
|
||
reject('error')
|
||
})
|
||
})
|
||
},
|
||
},
|
||
getters: {
|
||
getDict: state => key => {
|
||
if (key && state.dicts.length > 0) {
|
||
return state.dicts.find(e => e.key == key)
|
||
}
|
||
return null
|
||
}
|
||
},
|
||
plugins: [perState({
|
||
storage: {
|
||
getItem: key => uni.getStorageSync(key),
|
||
setItem: (key, value) => uni.setStorageSync(key, value),
|
||
removeItem: key => uni.removeStorageSync(key)
|
||
}
|
||
})]
|
||
})
|
||
|
||
export default store
|