466 lines
20 KiB
JavaScript
466 lines
20 KiB
JavaScript
import http from "./http";
|
||
import Vue from "vue";
|
||
import CryptoJS from "./crypto-js";
|
||
import qs from 'query-string'
|
||
import dayjs from "./monent";
|
||
|
||
/**
|
||
* 用户登录信息和方法
|
||
*/
|
||
export const user = {
|
||
state: () => ({
|
||
token: "",
|
||
expiredTime: ""
|
||
}),
|
||
mutations: {
|
||
setToken(state, token) {
|
||
state.token = token
|
||
},
|
||
setExpired(state, time) {
|
||
state.expiredTime = time
|
||
},
|
||
setUser(state, user) {
|
||
for (const key in user) {
|
||
Vue.set(state, key, user[key])
|
||
}
|
||
},
|
||
initWaterMarker(state) {
|
||
const waterMarked = document.querySelector('#waterMarker')
|
||
if (!waterMarked && state?.name) {
|
||
const waterMarker = document.createElement('div')
|
||
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'
|
||
for (let i = 0; i < 200; i++) {
|
||
const 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?.name + state?.phone?.slice(-4) || "未授权"
|
||
waterMarker.appendChild(markerItem)
|
||
}
|
||
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({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, code} = params, action = "/auth/oauth/token"
|
||
if (!!code) {
|
||
action = "/auth/wechatcp/token"
|
||
}
|
||
return http.post(action, params, {
|
||
withoutToken: true,
|
||
module,
|
||
params: {
|
||
...params, grant_type: 'password',
|
||
password: encryptByDES(params.password)
|
||
},
|
||
headers: {
|
||
Authorization: "Basic d2VjaGF0OndlY2hhdA=="
|
||
}
|
||
}).then(res => {
|
||
if (res?.access_token) {
|
||
const token = [res?.token_type, res?.access_token].join(" ").trim()
|
||
commit("setToken", token)
|
||
commit("setExpired", dayjs().add(res.expires_in - 600,'s').unix())
|
||
return token
|
||
} else return Promise.reject(res.msg)
|
||
})
|
||
},
|
||
getWechatToken({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, action = "/auth/wechat-mp/token"
|
||
return http.post(action, params, {
|
||
withoutToken: true,
|
||
throttle: 500,
|
||
module,
|
||
params: {
|
||
...params, grant_type: 'password',
|
||
password: encryptByDES(params.password)
|
||
},
|
||
headers: {
|
||
Authorization: "Basic d3htcDp3eG1w"
|
||
}
|
||
}).then(res => {
|
||
if (res?.access_token) {
|
||
const token = [res?.token_type, res?.access_token].join(" ").trim()
|
||
commit("setToken", token)
|
||
return token
|
||
} else return Promise.reject(res.msg)
|
||
})
|
||
},
|
||
getAccount({dispatch, commit}, config) {
|
||
//获取企业微信后台账号信息
|
||
return http.post("/admin/user/detail-phone", null, config).then(res => {
|
||
if (res?.data) {
|
||
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,
|
||
isSign
|
||
} = res.data,
|
||
gridExtra = {isSign}
|
||
return commit("setUser", {girdId, girdMemberId, girdName, girdCheckType, gridInfo, gridExtra})
|
||
}
|
||
}).catch(() => 0)
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* 企微jssdk功能
|
||
*/
|
||
let timer = {}
|
||
/**
|
||
* 微信oauth2跳转链接
|
||
* https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&agentid=AGENTID#wechat_redirect
|
||
* @param params
|
||
*/
|
||
const oauth2Weixin = params => {
|
||
const redirect = qs.parseUrl(location.href)
|
||
delete redirect.query.code
|
||
delete redirect.query.state
|
||
return qs.stringifyUrl({
|
||
url: "https://open.weixin.qq.com/connect/oauth2/authorize",
|
||
query: {
|
||
response_type: 'code',
|
||
redirect_uri: qs.stringifyUrl(redirect),
|
||
...params
|
||
},
|
||
fragmentIdentifier: "wechat_redirect"
|
||
})
|
||
}
|
||
export const wxwork = {
|
||
state: () => ({
|
||
agentSignURL: "",
|
||
apiList: [],
|
||
config: {}
|
||
}),
|
||
mutations: {
|
||
setConfig(state, config) {
|
||
state.config = config
|
||
},
|
||
setAgentSignURL(state, url) {
|
||
state.agentSignURL = url
|
||
},
|
||
setApiList(state, list) {
|
||
state.apiList = list
|
||
},
|
||
},
|
||
actions: {
|
||
agentSign({state, commit}, params = {}) {
|
||
//授权jssdk在url上使用,并获取corpId
|
||
let url = window.location.href
|
||
if (state.agentSignURL == url && state.config.corpId) {
|
||
return Promise.resolve()
|
||
} else {
|
||
commit("setAgentSignURL", url)
|
||
commit("setApiList", [])
|
||
let action = "/app/wxcp/portal/agentSign"
|
||
if (!!params?.action) {
|
||
action = params.action
|
||
delete params.action
|
||
} else if (!!params?.suiteId) {
|
||
action = "/app/wxcptp/portal/agentSign"
|
||
}
|
||
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
|
||
}
|
||
commit("setConfig", config)
|
||
return config
|
||
}
|
||
}).catch(err => {
|
||
console.error(err)
|
||
})
|
||
}
|
||
},
|
||
getCode({state, dispatch}, params) {
|
||
const excute = (tryAgentSign = false) => {
|
||
if (!params?.appid) {
|
||
let {corpid: corpId, suiteId, agentid} = state.config, scope = "snsapi_privateinfo"
|
||
if (/AppForm/.test(location.pathname)) {
|
||
scope = "snsapi_base"
|
||
} else if (suiteId) {
|
||
corpId = suiteId
|
||
scope = "snsapi_privateinfo"
|
||
}
|
||
params = {appid: corpId, agentid, scope}
|
||
return new Promise((resolve, reject) => {
|
||
if (corpId && scope) {
|
||
const oauthURL = oauth2Weixin(params)
|
||
location.replace(oauthURL)
|
||
} else if (!tryAgentSign && corpId) {
|
||
dispatch("agentSign", {corpId, suiteId}).then(() => excute(true)).then(() => resolve())
|
||
} else reject("URL缺少必要参数(corpId)")
|
||
})
|
||
} else new Promise(() => {
|
||
const oauthURL = oauth2Weixin(params)
|
||
location.replace(oauthURL)
|
||
})
|
||
}
|
||
return excute()
|
||
},
|
||
injectJWeixin({state, commit, rootState}, apis) {
|
||
const inject = (jsApiList) => new Promise((resolve, reject) => {
|
||
jsApiList = jsApiList || []
|
||
if (timer.injectJWeixin) {//节流设置,500ms内的多次请求合并到一处
|
||
clearTimeout(timer.injectJWeixin)
|
||
jsApiList = [...new Set([...state.apiList, ...jsApiList])]
|
||
commit("setApiList", jsApiList)
|
||
}
|
||
timer.injectJWeixin = setTimeout(() => {
|
||
const sdk = wx?.agentConfig ? wx : jWeixin
|
||
console.log("agentConfig配置:")
|
||
console.log({...state.config, jsApiList})
|
||
sdk?.agentConfig({
|
||
...state.config, jsApiList,
|
||
success: res => resolve(res),
|
||
fail: err => {
|
||
console.error(err)
|
||
reject(err)
|
||
}
|
||
})
|
||
}, 500)
|
||
})
|
||
return inject([apis].flat().filter(Boolean))
|
||
},
|
||
injectSDK({dispatch, state}, apis) {
|
||
const {corpId, suiteId} = state.config
|
||
return dispatch('agentSign', {corpId, suiteId}).then(() => dispatch("injectJWeixin", [apis].flat()))
|
||
},
|
||
previewFile({dispatch}, op) {
|
||
if (window.navigator.userAgent.indexOf("Windows NT") > -1) {
|
||
uni.showToast({
|
||
title: "企业微信暂不支持PC端的预览文件!",
|
||
icon: 'none'
|
||
})
|
||
} else {
|
||
dispatch("injectSDK", "previewFile").then(() => {
|
||
setTimeout(() => {
|
||
let sdk = typeof wx?.invoke == 'function' ? wx : jWeixin
|
||
sdk?.invoke('previewFile', {...op}, res => {
|
||
console.log(res)
|
||
})
|
||
}, 500)
|
||
})
|
||
}
|
||
},
|
||
closeAgent({dispatch}) {
|
||
dispatch("injectSDK", "closeWindow").then(() => {
|
||
setTimeout(() => {
|
||
let sdk = typeof wx?.closeWindow == 'function' ? wx : jWeixin
|
||
sdk?.closeWindow()
|
||
}, 500)
|
||
})
|
||
},
|
||
selectEnterpriseContact({dispatch}, params) {
|
||
return new Promise((resolve, reject) => {
|
||
dispatch("injectSDK", "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({dispatch}, params) {
|
||
return new Promise((resolve, reject) => {
|
||
dispatch("injectSDK", "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')
|
||
})
|
||
})
|
||
},
|
||
initOpenData({dispatch, commit, state}, params = {}) {
|
||
const loadSdk = (count = 0) => {
|
||
if (!!window?.WWOpenData) {
|
||
const canvas = params?.canvas
|
||
if (canvas) delete params.canvas
|
||
if (timer.initOpenData) {
|
||
clearTimeout(timer.initOpenData)
|
||
}
|
||
const init = () => canvas ? dispatch('initCanvas') : dispatch('bindElements')
|
||
timer.initOpenData = setTimeout(() => {
|
||
window?.WWOpenData?.checkSession({
|
||
success: () => init(),
|
||
fail: () => {
|
||
dispatch("injectSDK", "initWwOpenData").then(() => init())
|
||
}
|
||
})
|
||
}, 500)
|
||
} else if (count > 10) {
|
||
console.log("无法获取WWOpenData")
|
||
} else {
|
||
setTimeout(() => {
|
||
loadSdk(++count)
|
||
}, 200)
|
||
}
|
||
}
|
||
dispatch("injectSDK", "initWwOpenData").then(() => loadSdk())
|
||
},
|
||
bindElements() {
|
||
const nodes = document.querySelectorAll('.AiOpenData')
|
||
window.WWOpenData?.bindAll(nodes)
|
||
},
|
||
initCanvas() {
|
||
window.WWOpenData?.initCanvas()
|
||
},
|
||
transCanvas(store, items) {
|
||
return new Promise((resolve, reject) => {
|
||
window.WWOpenData?.prefetch({items}, (err, data) => {
|
||
err ? reject(err) : resolve(data)
|
||
})
|
||
})
|
||
},
|
||
shareToExternalChat({dispatch}, params) {
|
||
return new Promise(resolve => {
|
||
dispatch("injectSDK", "shareToExternalChat").then(() => window?.wx?.invoke("shareToExternalChat", {...params}, resolve) || console.error("jssdk未成功加载!"))
|
||
})
|
||
}
|
||
}
|
||
}
|