mtl-js-sdk
Version:
ynf-fw-mtl-api
450 lines (406 loc) • 16.3 kB
JavaScript
import environment from './common/environment'
import syncMethod from './common/syncMethod'
import modulemapper from './common/modulemapper'
import global from './platforms/all-platform/global'
// 获取当前运行平台
let PLATFORM = environment.platform
const upesnVersion = environment.upesnVersion
const CALLBACK_TYPE_COMMON = 0
const CALLBACK_TYPE_EXTRA = 1
let platform = null
let _callbackCaches = {}
// 初始化易观SDK
// analysysInit()
if (PLATFORM == "wx") { platform = require("./platforms/wx/platform").default; }
if (PLATFORM == "h5") { platform = require("./platforms/h5/platform").default; }
if (PLATFORM == "upesn") { platform = require("./platforms/upesn/platform").default; }
if (PLATFORM == "APIIos") { platform = require("./platforms/APIIos/platform").default; }
if (PLATFORM == "APIAndroid") { platform = require("./platforms/APIAndroid/platform").default; }
if (PLATFORM == "dingtalk") { platform = require("./platforms/dingtalk/platform").default; }
if (PLATFORM == "upesnAndroid") { platform = require("./platforms/APIAndroid/platform").default; }
if (PLATFORM == "upesnIos") { platform = require("./platforms/APIIos/platform").default; }
if (PLATFORM == "tt") { platform = require("./platforms/tt/platform").default; }
if (PLATFORM == "APIHarmonyOS") { platform = require("./platforms/APIIos/platform").default; }
if (PLATFORM === "upesnIos") {
PLATFORM = "upesn"
} else if (PLATFORM === "upesnAndroid") {
PLATFORM = "upesn"
} else if (PLATFORM === "APIHarmonyOS") {
// 友空间旗舰版 走友空间公有云逻辑
PLATFORM = "upesn"
}
if (!platform) throw new Error("Failed to load " + PLATFORM + " platform")
let version = "6.4.10"
function compareVersion(newVersion) {
if (!window.mtl) return true;
const oldVersion = window.mtl.version
console.log("current mtl version = ", oldVersion)
console.log("new mtl version = ", newVersion)
if (!oldVersion) return true;
if (oldVersion === newVersion) return true;
const oldV = oldVersion.split(".").map((item) => parseInt(item));
const newV = newVersion.split(".").map((item) => parseInt(item));
const length = Math.min(oldV.length, newV.length);
for (let i = 0; i < length; i++) {
if (oldV[i] > newV[i]) {
return false;
} else if (oldV[i] < newV[i]) {
return true;
}
}
if (length === oldV.length) {
return true;
} else {
return false;
}
}
function extend({ strategy, module, symbolPath, proxy = platform.execProxy }, modulemapper) {
if (typeof symbolPath === "string" && symbolPath.length > 0) {
strategy = strategy || "c"
symbolPath = "mtl" + "." + symbolPath
} else {
if (strategy && strategy !== "m") {
console.log('symbolPath === null,strategy only "m"')
}
strategy = "m"
symbolPath = "mtl"
}
if (typeof proxy === "function") {
for (const key in module) {
if (module.hasOwnProperty(key)) {
const element = module[key]
if (typeof element === "function") {
module[key] = proxy(element)
}
}
}
}
modulemapper.addEntry(strategy, module, symbolPath)
modulemapper.mapModules(window)
modulemapper.reset()
}
/**
* 扩展js方法及js文件
* @param {string} module 函数体
* @param {string} symbolPath 命名空间
* @param {string} platform 平台名
* @param {object} modulemapper modulemapper模块
*/
function extendApi({ module, symbolPath, platform }) {
if (!platform || platform === "" || (platform && platform === mtl.platform)) {
const strategy = "e"
let symbol = "mtl"
if (typeof symbolPath === "string" && symbolPath.length > 0) {
symbol = "mtl" + "." + symbolPath
}
modulemapper.addEntry(strategy, module, symbol)
modulemapper.mapModules(window)
modulemapper.reset()
}
}
// 扩展平台
function addPlatform({ platform, condition }) {
if (condition && condition()) {
extendApi({
module: {
platform: platform,
},
})
}
}
function init() {
// 比较版本
if (!compareVersion(version)) {
console.log("The version does not need to be updated")
return window.mtl
}
let execProxy = platform.execProxy
let instance = {
version,
platform: PLATFORM,
isReady: false,
upesnVersion,
}
modulemapper.clobbers(instance, "mtl")
modulemapper.mapModules(window)
modulemapper.reset()
modulemapper.clobbers({ extend }, "MTL")
modulemapper.mapModules(window)
modulemapper.reset()
console.log("current platform is: ", PLATFORM)
platform.bootstrap(() => {
setTimeout(() => {
console.log("The platform initialization succeeded.")
window.mtl.isReady = true
window.dispatchEvent(new Event("MTLReady"))
if (mtl.platform === 'tt') {
mtl.initConfig(window.mtl$Auth)
}
// 动态获取扩展 js, 扩展脚本加载依赖 cookie!
// 在 Localstorage 中获取 serviceCode,
// getExtensionScript()
}, 0)
})
let obj = {
addPlatform: addPlatform,
extendApi: extendApi,
systemType: environment.systemType,
currentPlatform: environment.currentPlatform,
isTrustedPlatform: environment.isTrustedPlatform,
initMobileService: environment.initMobileService,
login: environment.login,
loginNew: environment.loginNew,
logout: environment.logout,
setContext: environment.setContext,
NAVITYPE: environment.NAVITYPE,
validateCodeLogin: environment.validateCodeLogin,
validateCodeLoginNew: environment.validateCodeLoginNew,
autoLogin: environment.autoLogin,
autoLoginNew: environment.autoLoginNew,
sendValidateCode: environment.sendValidateCode,
sendValidateCodeNew: environment.sendValidateCodeNew,
changeTenant: environment.changeTenant,
changeTenantNew: environment.changeTenantNew,
getAppList: environment.getAppList,
getAppListNew: environment.getAppListNew,
getEsnCode: environment.getEsnCode,
getEsnCodeNew: environment.getEsnCodeNew,
getYhtTokenWithCode: environment.getYhtTokenWithCode,
getYhtTokenWithCodeNew: environment.getYhtTokenWithCodeNew,
getBannerList: environment.getBannerList,
getBannerListNew: environment.getBannerListNew,
getBaseUserInfo: environment.getBaseUserInfo,
getIndependenceAppList: environment.getIndependenceAppList,
loadMtlCDNJs: environment.loadMtlCDNJs,
loginOfMiniProgram: environment.loginOfMiniProgram,
loginOfMiniProgramNew: environment.loginOfMiniProgramNew,
unBindUser: environment.unBindUser,
unBindUserNew: environment.unBindUserNew,
getExclusiveLanguage: environment.getExclusiveLanguage,
getStorageSync: syncMethod.getStorageSync,
getStorageParseSync: syncMethod.getStorageParseSync,
getStorageStringifySync: syncMethod.getStorageStringifySync,
...platform.exports,
getConfigSync: syncMethod.getConfigSync,
loadingExtensionScript
}
extend({
module: obj,
proxy: execProxy
}, modulemapper)
let modules = global.modules
for (const key in modules) {
if (modules.hasOwnProperty(key)) {
const module = modules[key]
extend({ module, symbolPath: key, proxy: null }, modulemapper)
}
}
// 预读取project.json
if (platform.id.toLowerCase().indexOf("ios") !== -1 || platform.id.toLowerCase().indexOf("android") !== -1) {
window.mtl.getConfig({
success(res) {
localStorage.setItem("mtlAppConfig", JSON.stringify(res))
},
fail(err) {
console.log(JSON.stringify(err))
},
})
}
if (platform.id.toLowerCase().indexOf("apiandroid") !== -1) {
setTimeout(() => {
if (window.api) {
window.api.addEventListener({
name: "appintent",
}, function (ret, err) {
if (window.api.systemType === "android" && ret?.sourceAppId) {
const mtlPush = window.api.require("mtlPush")
const sourceAppId = ret.sourceAppId
const isIndexof = sourceAppId.toLowerCase().indexOf("launcher") === -1 && sourceAppId.toLowerCase().indexOf("packageinstaller") === -1
if (mtlPush && ret.appParam && isIndexof) {
mtl.setStorage({
domain: "AndroidPush",
key: "AndroidPushData",
data: JSON.stringify(ret),
})
}
}
})
}
}, 1000)
}
instance.loadPlugin = function (plugin) {
if (typeof plugin === "function") {
extend(plugin(), modulemapper)
} else {
extend(plugin, modulemapper)
}
}
/**
* 加载自定义插件
* 在customPlugins目录下找到插件index.js文件加载到document的head中
*/
instance.loadCustomPlugin = function (plugin) {
var script = document.createElement("script")
script.type = "text/javascript"
var baseUrl = "./customPlugins/"
var url = baseUrl + plugin + "/pluginJS/index.js"
script.src = url
document.head.appendChild(script)
}
/**
* 挂到到window上的统一回调方法,原生调用该方法后,根据callbackId获取之前缓存的success、fail、complete回调方法
*/
window.mtl_handleCustomPluginCallback = function (result) {
const { callbackId, keepCallback, code, msg: message, data } = result
let callbackInfo = _callbackCaches[callbackId]
if (callbackInfo.type === CALLBACK_TYPE_COMMON) {
let { success, fail, complete } = callbackInfo.funcGroup
if (code === 0) {
success && success(data)
} else {
fail && fail({ code, message })
}
complete && complete({ code, message, data })
} else if (callbackInfo.type === CALLBACK_TYPE_EXTRA) {
let { func } = callbackInfo
func && func(data)
}
if (!keepCallback) {
delete _callbackCaches[callbackId]
}
}
var options = { platform: PLATFORM };
extend(require("./plugins/mobile").default(options, { symbolPath: "mobile" }), modulemapper);
extend(require("./plugins/pay").default(options, { symbolPath: "pay" }), modulemapper);
extend(require("./plugins/ymprinter").default(options, { symbolPath: "ymprinter" }), modulemapper);
extend(require("./plugins/ai").default(options, { symbolPath: "ai" }), modulemapper);
extend(require("./plugins/vui").default(options, { symbolPath: "vui" }), modulemapper);
extend(require("./plugins/video").default(options, { symbolPath: "video" }), modulemapper);
extend(require("./plugins/ncc").default(options, { symbolPath: "ncc" }), modulemapper);
extend(require("./plugins/apkCheck").default(options, { symbolPath: "apkCheck" }), modulemapper);
window.mtl = instance
return instance
}
// hook 捕捉函数调用增加数据统计
function overrideMTL(origmMtl, module) {
let object = {}
for (let key in origmMtl) {
let originFunc = origmMtl[key]
if (typeof originFunc === 'function') {
object[key] = (...args) => {
// 统计函数
if (window?.AnalysysAgent) {
const obj = {
"service_code": window.location.origin + window.location?.pathname,
"fun_name": module ? `${module}.${key}` : key,
"useragent_name": window.navigator.userAgent,
"origin_name": window.location.origin,
"version_name": origmMtl.version,
"platform_name": origmMtl.platform,
}
console.log("mtl AnalysysAgent obj: ", obj);
window?.AnalysysAgent?.track("function_call", obj);
}
return originFunc(...args)
}
} else if (typeof originFunc === "object") {
// 如果是对象, 还需要继续遍历
object[key] = overrideMTL(originFunc, key)
} else {
object[key] = originFunc
}
}
if (Object.keys(object).length === 0) {
return origmMtl
}
return object
}
function analysysInit(obj) {
if (isYonyoucloud && !window?.AnalysysAgent) {
var path = "https://design.yonyoucloud.com/" + "static/analytics/yiguan/lat" + "est/AnalysysAgent_JSSDK_INIT.dev.js"
var script = document.createElement("script")
script.type = "text/javascript"
script.defer = "defer"
script.src = path
script.onload = (res) => {
console.log("analysys init success");
obj?.success && obj?.success()
}
script.onerror = (err) => {
console.log(err);
obj?.fail && obj?.fail()
}
document.head.insertBefore(script, document.head.childNodes[0].nextSibling);
return
}
obj?.fail && obj?.fail()
}
function isYonyoucloud() {
var domain = window.location.origin
return (
domain.includes('yonyoucloud.') || domain.includes('diwork.')
)
}
/**
* 加载扩展
* @param {string} appCode 应用编码
*/
function loadingExtensionScript(object) {
const serviceCode = 'iuap-yonbuilder-mobile'
const appCode = object?.appCode
environment.getDomain({
serviceCode,
success: (res) => {
const domain = res.endsWith('/') ? res : res + '/'
let pl = window.mtl.platform
if (window.mtl.platform === 'wx') {
if (window.navigator.userAgent.indexOf("wxwork") !== -1) {
pl = 'wecom'
} else {
pl = 'wechat'
}
} else if (window.mtl.platform === 'tt') {
pl = 'feishu'
} else if (window.mtl.platform === 'dingtalk') {
pl = 'dingtalk'
}
window.mtl.request({
url: `${domain}/iuap-yonbuilder-mobile/rest/v2/mobile/mtl/authInfo`,
method: "GET",
params: {
serviceCode: appCode
},
success: function (res) {
try {
let result = res.data
if (typeof result === 'string') {
result = JSON.parse(res.data)
}
if (result.code === 200) {
// 扩展函数地址
if (result?.data?.url) {
environment.loadCDNJS(result?.data?.url)
}
if (pl === 'wecom' || pl === 'wechat' || pl === 'feishu' || pl === 'dingtalk') {
// 存储鉴权信息
const authInfo = result?.data?.[pl]
try {
window.localStorage.setItem('mtlConfigParams', JSON.stringify(authInfo))
} catch (error) {
console.warn(error)
}
}
}
} catch (error) {
console.warn("11 error = ", error)
}
},
fail: function (err) {
console.warn('err = ', err);
}
});
}
})
}
export default init()