mtl-js-sdk
Version:
ynf-fw-mtl-api
1,359 lines (1,276 loc) • 44.5 kB
JavaScript
/*
* @Author: wangyingliang@yonyou.com
* @Date: 2024-07-22 15:47:03
* @LastEditors: wangyingliang wangyingliang@yonyou.com
* @LastEditTime: 2026-03-18 09:04:40
* @FilePath: /mtl-api-project/src/platforms/dingtalk/methods.js
* @Description: 钉钉函数集合
* Copyright (c) 2024 by Yonyou, All Rights Reserved.
*/
import h5 from '../h5/methods'
import db from './utils/db'
import xaxios from 'axios'
import unique from '../../common/unique.js'
import proxy from './dd.proxy.js'
import syncMethod from '../../common/syncMethod.js'
import map from '../h5/map/amapLocation.js'
// var script = document.createElement("script");
// script.type = "text/javascript";
// script.async = false
// script.id = 'dingtalk.js';
// script.src = "https://g.alicdn.com/dingding/dingtalk-jsapi/3.0.12/dingtalk.open.js";
// document.head && document.head.appendChild(script);
console.log("load-dingtalk.open.js")
const axios = xaxios?.default || xaxios
let urlDingtalk = "https://g.alicdn.com/dingding/dingtalk-jsapi/3.0.12/dingtalk.open.js"
const xhr = new XMLHttpRequest()
xhr.open("GET", urlDingtalk, false)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
const script = document.createElement("script")
script.textContent = xhr.responseText
document.head.appendChild(script)
}
}
xhr.send()
const { configPermission } = proxy
const FAIL_CODE = 1 // api 调用失败统一返回 code
const unsupportFailRes = {
// api 当前平台不支持统一返回值
code: FAIL_CODE,
message: "The current platform does not support",
}
/**
* @description: api 当前平台不支持统一回调
* @param {*} object
*/
function unsupportMethod(object = {}) {
object?.fail && object?.fail(unsupportFailRes)
object?.complete && object?.complete(unsupportFailRes)
}
// 当前平台不支持 api 列表
const unsupportMethods = []
/**
* @description 统一处理API的回调
* @param {Object} objectbiz.navigation.replace
* @param {Function} callback
*/
const handleResponse = (object, callback) => {
let writeLog = object?.writeLog
return {
onSuccess: (res) => {
writeLog && writeLog("API call successful --- success res:", null, res)
let data = (callback && callback(res)) || res
object.complete && object.complete({ code: 200, data })
if (object.callback) {
object.callback(data)
return
}
object.success && object.success(data)
},
onFail: (res) => {
writeLog && writeLog("API call fail --- fail res:", null, res)
console.log("handleResponse:fail", res)
object.fail && object.fail(res)
object.complete && object.complete(res)
},
}
}
/**
* @description: api 成功调用且无返回值时统一回调
* @param {Object} obj
*/
function successCallBack(obj = {}) {
obj?.success && obj?.success({})
obj?.complete && obj?.complete({})
}
const supportMethods = []
//Set nav bar
/* const setNavBar = function ({ hide, backgroundColor, tintColor, centerItems, success = () => { }, fail = () => { } }) {
settingNavBar({ hide, backgroundColor, tintColor, centerItems, success, fail });
}; */
let currentNavTitle = null
const settingNavBar = function ({ hide, backgroundColor, tintColor, leftItems, centerItems, rightItems, success = () => { }, fail = () => { } }) {
// Handle nav bar's display
dd.biz.navigation.hideBar({
hidden: !!hide,
onSuccess: function (result) {
//当系统为ios时,在钉钉打开隐藏了原生导航的mdf页面会整体上移。设置下container的margin-top为36px
},
onFail: function (err) { },
}) // true:隐藏,false:显示
// Handle left back
leftItems &&
dd.biz.navigation.setLeft({
//control: true,
text: "",
onSuccess: (result) => {
//leftItems[0].callback && leftItems[0].callback(result);
},
onFail: (err) => console.log(err),
})
// Handle center title
Array.isArray(centerItems) &&
centerItems.length > 0 &&
dd.biz.navigation.setTitle({
control: true,
title: centerItems[0].title,
onSuccess: (result) => {
if (currentNavTitle) document.removeEventListener("navTitle", currentNavTitle)
if (centerItems[0].callback) {
//双击标题的事件监听
currentNavTitle = centerItems[0].callback
document.addEventListener("navTitle", centerItems[0].callback)
}
},
onFail: (err) => console.log(err),
})
// Handle right text and callback
const checkRightItemsAvaliable = Array.isArray(rightItems) && rightItems[0]
const rightOptions = {
text: checkRightItemsAvaliable && rightItems[0].title ? rightItems[0].title : "",
callback: checkRightItemsAvaliable && rightItems[0].callback ? rightItems[0].callback : null,
}
dd.biz.navigation.setRight({
show: rightOptions.text ? true : false,
control: rightOptions.callback ? true : false,
text: rightOptions.text,
onSuccess: (result) => {
rightOptions.callback && rightOptions.callback(result)
},
onFail: (err) => console.log(err),
})
}
/**
* @description: 选择图片
* @param {Object} params
* @param {String []} sourceType - 相册选取或者拍照
* @param {Number} count - 最大可选照片数
* @param {String} position - 相机拍照使用的摄像头:front:前置摄像头 back:后置摄像头
* @param {Boolean} secret - 相机拍照生成的图片,是否存储到私有目录
*/
const chooseImage = (params = {}) => {
dd.ready(function () {
dd.biz.util.chooseImage({
sourceType: params?.sourceType || ["camera", "album"],
count: params?.count || 9, // 当sourceType参数内只有camera时,该参数只能传1。
position: params?.position || "back",
secret: params?.secret || false,
onSuccess: (res) => {
console.log("chooseImage res:", res)
const { files, filePaths, path, size, fileType } = res
params?.success && params?.success({ ...res, localIds: filePaths })
params?.complete && params?.complete({ ...res, localIds: filePaths })
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `chooseImage fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
/**
* @description: 预览图片
* @param {Object} params
* @param {String []} urls - 要预览的图片链接列表 必传
* @param {String} current - 当前显示的图片链接,建议使用png、jpg格式图片链接
*/
const previewImage = function (params = {}) {
// dd.biz.util.previewImage({
// urls,
// current,
// onSuccess: success,
// onFail: fail,
// })
if (!(Array.isArray(params?.urls) && !!params?.urls?.length)) {
// urls 不合法
const error = {
code: FAIL_CODE,
message: `previewImage fail: 'urls' Illegal parameters`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
return
}
dd.biz.util.previewImage({
urls: params?.urls,
current: params?.current || params?.urls?.[0],
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `previewImage fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
}
//Back to previous h5 page, if current is root page, close the current page
const onWebviewGoBack = function (options) {
const { onSuccess, onFail } = handleResponse(options)
dd.biz.navigation.goBack({
onSuccess,
onFail,
})
}
/**
* @description: 跳转到目标页
* @param {Object} params
* @param {String} url - 要打开链接的地址 必传
* @param {Number} orientation - 0 强制竖屏; 1 跟随系统; 2 强制横屏
*/
const navigateTo = function (params = {}) {
const { search, hash } = new URL(params?.url)
const orientation = params?.orientation
const url = params?.url
if (!url) {
const error = {
code: FAIL_CODE,
message: `navigateTo fail: url is null`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
return
}
const dd_orientation = orientation ? (orientation === 0 ? "" : orientation === 1 ? "auto" : "landscape") : ""
const connector = search || hash.indexOf("?") > -1 ? "&" : "?"
const openUrl = orientation ? `${url}${connector}dd_orientation=${dd_orientation}` : `${url}`
// dd.biz.util.openLink({
// url: openUrl,
// onSuccess: (res) => {
// dd.device.notification.hidePreloader({})
// success(res)
// },
// onFail: (err) => {
// fail(err)
// },
// })
dd.biz.util.openLink({
url: openUrl,
onSuccess: (res) => {
dd.device.notification.hidePreloader({})
params?.success && params?.success(res)
params?.complete && params?.complete(res)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `navigateTo fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
}
/**
* @description: 当前页面打开 url
* @param {Object} params
* @param {String} url - 要打开链接的地址 必传
* @param {Boolean} newWindow - 是否新开窗口打开链接
*/
const webviewLoadUrl = function (params = {}) {
// dd.biz.navigation.replace({
// url,
// onSuccess: success,
// onFail: fail,
// })
if (!params?.url) {
const error = {
code: FAIL_CODE,
message: `webviewLoadUrl fail: url is null`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
return
}
if (!params?.newWindow) {
// 不新开窗口
location.href = params?.url
successCallBack(params)
return
}
dd.biz.util.openLink({
url: params?.url,
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `webviewLoadUrl fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
}
/**
* @description: 关闭当前窗口
* @param {Object} params
* @param {Boolean} goBack - 是否仅返回上一页不关闭当前窗口
*/
const navigateBack = function (params = {}) {
// const { onSuccess, onFail } = handleResponse(object)
// dd.biz.navigation.close({
// onSuccess,
// onFail,
// })
if (params?.goBack) {
history.back()
successCallBack(params)
return
}
dd.biz.navigation.close({
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `navigateBack fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
}
/**
* 页面resume事件的回调监听
*/
const registerLifeCycle = function ({ onShow = () => { }, onHide = () => { } }) {
document.addEventListener("resume", function () {
onShow()
})
}
/**
* @description: 获取网络状态
* @param {Object} params
*/
function getNetworkType(params = {}) {
// const { onSuccess, onFail } = handleResponse(object)
// dd.device.connection.getNetworkType({
// onSuccess,
// onFail,
// })
dd.device.connection.getNetworkType({
onSuccess: (res) => {
console.log("getNetworkType res:", res)
// result: 网络类型值,UNKNOWN / NOTREACHABLE / WIFI / 3G / 2G / 4G / WWAN。 netWorkAvailable: 网络是否可用。
const { netWorkType, netWorkAvailable, result } = res
params?.success && params?.success({ networkType: result || netWorkType })
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `getNetworkType fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
},
})
}
function getStorageSync(options) {
let { key } = options
let structs = localStorage.getItem("domain.default")
structs = structs && JSON.parse(structs)
const data = structs && structs.hasOwnProperty(key) ? structs[key] : null
return data
}
function chooseLocalFiles(options) {
const { success } = options
if (success) {
options.success = function (res) {
success(res)
mtl.platform = "dingtalk"
}
} else {
options.success = function () {
mtl.platform = "dingtalk"
}
}
mtl.platform = "h5"
h5.chooseLocalFiles(options)
}
/**
*返回上一级页面
*/
function webviewBack(options) {
onWebviewGoBack(options)
}
function isWebviewCanGoBack(options = {}) {
options.success && options.success({ result: true })
}
function canWebviewBack(options = {}) {
isWebviewCanGoBack(options)
}
let isInPremission = false
let needPremission = true
// 安全取值:若 localStorage 项为 null/undefined/空串,则使用兜底值
const safeGet = (key, fallback) => {
const val = localStorage.getItem(key)
return (val === null || val === undefined || val === '') ? fallback : val
}
// 人力云鉴权逻辑.
const dingtalkSdkPermission = (callback, errCallBack) => {
let dingtalkUser = {}
try {
const raw = localStorage.getItem("dingtalk-user")
if (raw) {
dingtalkUser = JSON.parse(raw)
}
} catch (e) {
console.warn("Failed to parse dingtalk-user from localStorage", e)
dingtalkUser = {}
}
if (Object.keys(dingtalkUser).length === 0) {
errCallBack && errCallBack()
return
}
const { appType, suiteId, corpId, agentId, ytenantId } = dingtalkUser
const url = location.href.indexOf("#") > -1 ? location.href.substring(0, location.href.indexOf("#")) : location.href
let origin = location.origin
if (/dbox\.[a-zA-Z0-9]+\.com/i.test(location.hostname)) {
const matchResult = location.hostname.match(/dbox\.([a-zA-Z0-9]+)\.com/i)
const level_1_path = matchResult[1]
origin = `${location.protocol}//dbox.${level_1_path}.com`
} else if (/yonbip(-)?[a-zA-Z0-9]*\.diwork\.com/i.test(location.hostname)) {
origin = `${location.protocol}//yonbip.diwork.com`
} else if (/c[0-9]*\.yonyoucloud\.com/i.test(location.hostname)) {
origin = `${location.protocol}//c2.yonyoucloud.com`
}
let jsapiConfigUrl = ""
if (localStorage.getItem("dingtalk-jsapiConfig")) {
jsapiConfigUrl = localStorage.getItem("dingtalk-jsapiConfig")
} else {
jsapiConfigUrl = `${origin}/yonbip-hr-socializationapp/dingding/auth/jsapiConfig`
}
axios({
method: "post",
url: jsapiConfigUrl,
params: null,
data: {
url,
appType: safeGet("appType", appType),
suiteId: safeGet("suiteId", suiteId),
corpId: safeGet("corpId", corpId),
agentId: safeGet("agentId", agentId),
ytenantId: safeGet("ytenantId", ytenantId),
},
headers: {
"Content-Type": "application/json;charset=UTF-8",
},
})
.then((res) => {
console.log("res: ", res)
if (res.status === 200) {
console.log("jsapiConfig success >>>>>")
const { agentId, corpId, timeStamp, nonceStr, signature } = res.data.data
dd.config({
appId: agentId,
agentId, // 必填,微应用ID
corpId, //必填,企业ID
timeStamp, // 必填,生成签名的时间戳
nonceStr, // 必填,自定义固定字符串。
signature, // 必填,签名
type: 0,
jsApiList: [
"runtime.info",
"biz.contact.choose",
"device.notification.confirm",
"device.notification.alert",
"device.notification.prompt",
"biz.ding.post",
"biz.util.openLink",
"device.geolocation.get",
"device.geolocation",
"device.base.getUUID",
], // 必填,需要使用的jsapi列表,注意:不要带dd。
})
dd.error(function (err) {
needPremission = true
sessionStorage.setItem(`${location.origin}${location.pathname}_dingtalk`, false)
console.log("dd error: " + JSON.stringify(err))
// 钉钉获取定位失败,尝试用H5获取
errCallBack && errCallBack()
// alert('dd error: ' + JSON.stringify(err));
})
dd.ready(function () {
needPremission = false
sessionStorage.setItem(`${location.origin}${location.pathname}_dingtalk`, true)
console.log("dd ready >>>>>")
callback()
})
} else {
console.log("res.status ===", res.status)
// 钉钉获取定位失败,尝试用H5获取
errCallBack && errCallBack()
}
isInPremission = false
})
.catch(function (err) {
console.log("jsapiConfig err--", err)
isInPremission = false
// 钉钉获取定位失败,尝试用H5获取
errCallBack && errCallBack()
// alert('jsapiConfig error: ' + JSON.stringify(err ? err.message : err));
})
}
/**
* @description 获取当前坐标
* @param {type: String, success: Function, fail: Function, jsKey:'amapKey',jsCode:'amapSecret'}} options
*/
const getLocation = (options) => {
if (options?.useOld) {
oldLocation(options)
return
}
h5.getLocation(options)
}
/**
* 人力维护版本的getLocation, 保留逻辑!!!
*/
const oldLocation = (options) => {
const { onSuccess, onFail } = handleResponse(options)
if (isInPremission) {
onFail("Positioning is currently authorized")
return
}
let jsKey = options.jsKey
let jsCode = options.jsCode
let writeLog = options?.writeLog
const getH5Location = (onSuccess, onFail, jsKey, jsCode) => {
console.log("getH5Location--")
writeLog && writeLog("h5 getLocation process ----------------")
// 通过H5获取位置信息
map.amapLocation({
success: onSuccess,
jsKey: jsKey,
jsCode: jsCode,
fail: (err) => {
console.log("getH5Location-err--", err)
writeLog && writeLog("h5 getLocation fail --- fail res:", null, err)
alert("getH5Location-err--" + JSON.stringify(err ? err.message : err))
onFail(err)
},
})
}
if (!sessionStorage.getItem(`${location.origin}${location.pathname}_dingtalk`) || needPremission) {
console.log("Authorized process----------------")
writeLog && writeLog("Authorized process ----------------")
isInPremission = true
dingtalkSdkPermission(
function (result) {
writeLog && writeLog("Authorized success --- success res:", null, result)
dd.device.geolocation.get({
targetAccuracy: 200,
coordinate: 1,
withReGeocode: true,
useCache: false,
onSuccess: (res) => {
writeLog && writeLog("dd getLocation success --- success res:", null, res)
onSuccess(res)
},
onFail: (err) => {
writeLog && writeLog("dd getLocation fail --- fail res:", null, err)
if (err.errorCode === 7) {
onFail(err)
needPremission = true
} else {
// 通过H5获取位置信息
getH5Location(onSuccess, onFail, jsKey, jsCode)
}
},
})
},
function (result) {
writeLog && writeLog("Authorized fail --- fail res:", null, result)
// 通过H5获取位置信息
getH5Location(onSuccess, onFail, jsKey, jsCode)
}
)
} else {
console.log("Unauthorized process ----------------")
writeLog && writeLog("Unauthorized process----------------")
dd.ready(function () {
dd.device.geolocation.get({
targetAccuracy: 200,
coordinate: 1,
withReGeocode: true,
useCache: false,
onSuccess,
onFail: (err) => {
if (err.errorCode === 7) {
onFail(err)
needPremission = true
} else {
// 通过H5获取位置信息
getH5Location(onSuccess, onFail, jsKey, jsCode)
}
},
})
})
}
}
/**
* @description: 获取系统信息
* @param {Object} params
*/
const getSystemInfo = (params = {}) => {
if (params?.useOld) {
const { onSuccess, onFail } = handleResponse(params)
const excuteGetSystemInfo = () => {
dd.device.base.getPhoneInfo({
onSuccess: (data) => {
const { screenWidth, screenHeight, SIMCard, netInfo, model, operatorType, brand, version } = data
onSuccess({
screenWidth,
screenHeight,
model,
brand,
operatorType,
system: version,
SIMCard,
netInfo,
})
},
onFail,
})
}
excuteGetSystemInfo()
return
}
dd.device.base.getPhoneInfo({
onSuccess: (res) => {
console.log("getPhoneInfo res:", res)
let data = {
...res,
YZLanguage: "zhs",
platform: mtl?.platform,
pixelRatio: res?.screenScale,
systemLanguage: window?.navigator?.language,
}
params?.success && params?.success(data)
},
onFail: (err) => {
let data = {
YZLanguage: "zhs",
platform: mtl?.platform,
pixelRatio: window?.devicePixelRatio,
screenWidth: window?.screen?.width,
screenHeight: window?.screen?.height,
systemLanguage: window?.navigator?.language,
}
params?.success && params?.success(data)
},
})
}
/**
* 获取Uuid
* @param {boolean} useOld 是否使用人力维护时期的逻辑
* @param {function} success
* @param {function} fail
*/
const getMac = (params) => {
if (params?.useOld) {
const { onSuccess, onFail } = handleResponse(params)
if (!sessionStorage.getItem(`${location.origin}${location.pathname}_dingtalk`)) {
dingtalkSdkPermission(function () {
dd.device.base.getUUID({
onSuccess: (data) => {
onSuccess({
macAddress: data.uuid,
})
},
onFail,
})
})
} else {
console.log("getMac--dd--", dd)
dd.ready(function () {
dd.device.base.getUUID({
onSuccess: (data) => {
onSuccess({
macAddress: data.uuid,
})
},
onFail,
})
})
}
return
}
// 新逻辑获取UUID
dd.ready(function () {
dd.device.base.getUUID({
onSuccess: (res) => {
console.log("getUUID res:", res)
const { uuid } = res // uuid:通用唯一识别码。
params?.success && params?.success({ macAddress: uuid })
params?.complete && params?.complete({ macAddress: uuid })
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `getMac fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
const getUniqueId = (options) => {
getMac(options)
}
/**
* @description: 监听摇一摇
* @param {Object} params
* @param {Function} callback - 回调函数
* @param {Number} sensitivity - 振动幅度,Number类型,加速度变化超过这个值后触发shake
* @param {Number} frequency - 采样间隔(毫秒),Number类型,指每隔多长时间对加速度进行一次采样,然后对比前后变化,判断是否触发shake
* @param {Number} callbackDelay - 触发『摇一摇』后的等待时间(毫秒),Number类型,防止频繁调用
*/
const onShake = (params = {}) => {
// const { onSuccess, onFail } = handleResponse(options)
// dd.device.accelerometer.watchShake({
// sensitivity: 20, //振动幅度,Number类型,加速度变化超过这个值后触发shake
// frequency: 150, //采样间隔(毫秒),Number类型,指每隔多长时间对加速度进行一次采样,然后对比前后变化,判断是否触发shake
// callbackDelay: 3000, //触发『摇一摇』后的等待时间(毫秒),Number类型,防止频繁调用
// onSuccess,
// onFail,
// })
dd.device.accelerometer.watchShake({
callbackDelay: params?.callbackDelay || 3000,
sensitivity: params?.sensitivity || 20,
frequency: params?.frequency || 150,
onSuccess: (res) => {
params?.callback && params?.callback({})
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `watchShake fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
},
})
}
/**
* @description 震动
* @param {success: Function, fail: Function}
*/
const vibrateOnce = (options) => {
const { onSuccess, onFail } = handleResponse(options)
dd.device.notification.vibrate({
duration: 300, //震动时间,android可配置 iOS忽略
onSuccess,
onFail,
})
}
/**
* @param {fileName: String, showDate: Boolean, parameterDic: String, success: Function, fail: Function} options
*/
const writeLocationLog = (options) => {
if (!options.fileName) throw new Error("Illegal parameters!")
const { fileName, parameterDic, success } = options
db.openDB(fileName, fileName).then((dbInstance) => {
const now = new Date().getTime()
db.addData(dbInstance, fileName, {
id: now,
parameterDic: parameterDic,
timestamp: now,
}).then((res) => {
success && success(res)
})
})
}
const readLocationLog = (options) => {
if (!options.fileName) throw new Error("Illegal parameters!")
const { fileName, success } = options
db.openDB(fileName, fileName).then((dbInstance) => {
db.getAll(dbInstance, fileName).then((res) => {
const data = Array.isArray(res) && res.length > 0 ? res.map((item) => item.parameterDic || "") : []
success && success({ data })
})
})
}
/**
* @description: 关闭当前窗口
* @param {Object} params
*/
const closeCurrentWebview = function (params = {}) {
dd.biz.navigation.close({
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `closePage fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
}
/**
* @description: 打开新窗口
* @param {Object} params
* @param {String} url - 要打开链接的地址 必传
*/
const openNewWebview = function (params = {}) {
if (!params?.url) {
const error = {
code: FAIL_CODE,
message: `openNewWebview fail: url is null`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
return
}
dd.biz.util.openLink({
url: params?.url,
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `openNewWebview fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
}
/**
* @description: 跳转到新页面,并关闭当前页面
* @param {Object} params
* @param {String} url - 要打开链接的地址 必传
*/
const redirectTo = function (params = {}) {
const { search, hash } = new URL(params?.url)
const orientation = params?.orientation
const url = params?.url
if (!url) {
const error = {
code: FAIL_CODE,
message: `redirectTo fail: url is null`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
return
}
const dd_orientation = orientation ? (orientation === 0 ? "" : orientation === 1 ? "auto" : "landscape") : ""
const connector = search || hash.indexOf("?") > -1 ? "&" : "?"
const openUrl = orientation ? `${url}${connector}dd_orientation=${dd_orientation}` : `${url}`
dd.biz.navigation.replace({
url: openUrl,
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `redirectTo fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
}
/**
* @description: 开始录音
* @param {*} params
* @param {Number} maxDuration - 录音最大时长,单位:秒,必须为整数,范围[1,300]
*/
const startRecord = (params = {}) => {
dd.ready(function () {
dd.device.audio.startRecord({
maxDuration: params?.maxDuration || 60,
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `startRecord fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
/**
* @description: 停止录音
* @param {*} params
*/
const stopRecord = (params = {}) => {
dd.ready(function () {
dd.device.audio.stopRecord({
onSuccess: (res) => {
console.log("stopRecord res:", res)
const { mediaId, duration } = res // mediaId:返回音频的MediaID,可用于本地播放和音频下载 duration:返回音频的时长,单位:秒
params?.success && params?.success({ localId: mediaId })
params?.complete && params?.complete({ localId: mediaId })
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `stopRecord fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
/**
* @description: 监听录音自动停止
* @param {Object} params
*/
function onVoiceRecordEnd(params = {}) {
dd.ready(function () {
dd.device.audio.onRecordEnd({
onSuccess: (res) => {
console.log("onVoiceRecordEnd res:", res)
const { duration, mediaId } = res // duration - 返回音频的时长,单位:秒 mediaId - 停止播放音频 MediaId
params?.success && params?.success({ localId: mediaId })
params?.complete && params?.complete({ localId: mediaId })
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `onVoiceRecordEnd fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
/**
* @description: 播放录音
* @param {*} params
* @param {String} localId - 本地音频 id
* @param {Boolean} resume - 是否暂停后继续播放
*/
const playVoice = (params = {}) => {
if (params?.resume) {
// 暂停后继续播放
dd.ready(function () {
dd.device.audio.resume({
localAudioId: params?.localId,
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `playVoice fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
} else {
dd.ready(function () {
dd.device.audio.play({
localAudioId: params?.localId,
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `playVoice fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
}
/**
* @description: 暂停播放录音
* @param {*} params
* @param {String} localId - 本地音频 id
*/
const pauseVoice = (params = {}) => {
dd.ready(function () {
dd.device.audio.pause({
localAudioId: params?.localId,
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `pauseVoice fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
/**
* @description: 结束播放
* @param {*} params
* @param {String} localId - 本地音频 id
*/
const stopVoice = (params = {}) => {
dd.ready(function () {
dd.device.audio.stop({
localAudioId: params?.localId,
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `stopVoice fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
/**
* @description: 监听录音播放完毕
* @param {*} params
*/
const onVoicePlayEnd = (params = {}) => {
dd.ready(function () {
dd.device.audio.onPlayEnd({
onSuccess: (res) => {
successCallBack(params)
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `onVoicePlayEnd fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
/**
* @description: 打开地图
* @param {Object} params
* @param {Number} latitude - 纬度,范围为 -90~90,负数表示南纬 必传
* @param {Number} longitude - 经度,范围为 -180~180,负数表示西经 必传
* @param {String} name - 在地图锚点气泡显示的文案
*/
const openLocation = (params = {}) => {
const latitude = params?.latitude
const longitude = params?.longitude
if (typeof latitude === "undefined" || typeof longitude === "undefined") {
const error = {
code: FAIL_CODE,
message: `openLocation fail: latitude 或 longitude is null`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
return
}
if (typeof latitude !== "number" || isNaN(latitude) || typeof longitude !== "number" || isNaN(longitude)) {
const error = {
code: FAIL_CODE,
message: `openLocation fail: latitude 或 longitude error`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
return
}
dd.ready(function () {
dd.biz.map.view({
latitude: params?.latitude,
title: params?.name,
longitude: params?.longitude,
success: (res) => {
successCallBack(params)
},
fail: (err) => {
const error = {
code: FAIL_CODE,
message: `openLocation fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
})
}
function convertToObject(res) {
let dataObj = res
if (typeof res === "string") {
try {
dataObj = JSON.parse(res)
} catch (error) {
dataObj = res
}
}
return dataObj
}
function getUrlParams() {
let res = {}
let serach = window.location.search
if (!serach || serach === "") {
serach = window.location.href.split("?").pop()
}
let str = decodeURIComponent(serach)
str = str.trim().replace(/^[?#&]/, "")
if (!str) {
return res
}
str.split("&").forEach((strItem) => {
if (strItem) {
let parts = strItem.split("=")
let partKey = parts[0],
partValue = parts[1] || ""
res[partKey] = partValue
}
})
return res
}
function getConfig(obj = {}) {
const { envURL, resId, configUrl } = getUrlParams()
if (!envURL) {
obj.fail && obj.fail({ code: FAIL_CODE, message: "envURL is null" })
obj.complete && obj.complete({ code: FAIL_CODE, message: "envURL is null" })
return
}
const urlArray = envURL.split("rest")
const url = configUrl || urlArray[0] + "/rest/v2/mobile/out/getConfigJson?id=" + resId
let params = {
url: url,
method: "GET",
withCredentials: true,
responseType: "json",
headers: {
"content-type": "application/json",
},
}
axios(params)
.then((response) => {
let res = response.data && response.status && response.headers ? response.data : response
let dataObj = convertToObject(res)
obj.success && obj.success(dataObj)
obj.complete && obj.complete(dataObj)
})
.catch((err) => {
obj.fail && obj.fail(err)
obj.complete && obj.complete(err)
})
}
const scanQRCode = (params = {}) => {
let scanType = params?.scanType || ["all"]
dd.biz.util.scan({
type: scanType?.[0], // type 为 all、qrCode、barCode,默认是all。
onSuccess: (res) => {
console.log("scanQRCode res:", res)
const { text } = res
params?.success && params?.success({ resultStr: text })
params?.complete && params?.complete({ resultStr: text })
},
onFail: (err) => {
const error = {
code: FAIL_CODE,
message: `scanQRCode fail: ${JSON.stringify(err)}`,
}
params?.fail && params?.fail(error)
params?.complete && params?.complete(error)
},
})
}
let exports = Object.assign({}, h5, {
request: h5.request,
setStorage: h5.setStorage,
getStorage: h5.getStorage,
getStorageSync: syncMethod.getStorageSync,
removeStorage: h5.removeStorage,
clearStorage: h5.clearStorage,
getStorageParseSync: syncMethod.getStorageParseSync,
getStorageStringifySync: syncMethod.getStorageStringifySync,
getUserYHTInfo: h5.getUserYHTInfo,
setUserYHTInfo: h5.setUserYHTInfo,
getUserInfo: h5.getUserInfo,
saveExclusiveYhtInfo: unique.saveExclusiveYhtInfo,
saveExclusiveUserInfo: unique.saveExclusiveUserInfo,
gainUserInfo: h5.gainUserInfo,
getConfig,
saveExclusiveDomain: h5.saveExclusiveDomain,
checkBridgeNameExist: unique.checkBridgeNameExist,
canExecUpesnBridge: unique.canExecUpesnBridge,
getExclusiveCode: unique.getExclusiveCode,
getToken: h5.getToken,
getAppCode: unique.getAppCode,
getAuthCode: unique.getAuthCode,
setExclusiveLanguage: unique.setExclusiveLanguage,
getNetworkType,
onNetworkStatusChange: unique.onNetworkStatusChange,
getSystemInfo,
dail: h5.dail,
generateQRCode: h5.generateQRCode,
scanQRCode,
onShake,
watchShake: onShake,
previewFile: h5.previewFile,
wpsPreview: h5.wpsPreview,
previewDoc: h5.previewDoc,
uploadFile: h5.uploadFile,
uploadToFileService: h5.uploadToFileService,
downloadFile: h5.downloadFile,
chooseImage: h5.chooseImage,
chooseImages: h5.chooseImages,
previewImage,
startRecord,
stopRecord,
onVoiceRecordEnd,
navigateTo,
navigateBack,
redirectTo,
reLaunch: h5.reLaunch,
openNewWebview,
closeCurrentWebview,
webviewLoadUrl,
getLocation,
openLocation,
settingNavBar,
onWebviewGoBack,
registerLifeCycle,
chooseLocalFiles,
webviewBack,
isWebviewCanGoBack,
canWebviewBack,
getUniqueId,
getMac,
vibrateOnce,
writeLocationLog,
readLocationLog,
playVoice,
pauseVoice,
stopVoice,
onVoicePlayEnd,
})
unsupportMethods.forEach((pop) => {
exports[pop] = unsupportMethod
})
supportMethods.forEach((pop) => {
if (!exports[pop]) exports[pop] = successCallBack
})
export default exports