UNPKG

mtl-js-sdk

Version:

ynf-fw-mtl-api

1,359 lines (1,276 loc) 44.5 kB
/* * @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