Files
dvcp_v2_wxcp_app/library/common/modules.js
2024-10-31 14:34:57 +08:00

466 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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未成功加载!"))
})
}
}
}