[uni-app] Инкапсулируйте общие методы и глобальные данные

uni-app
[uni-app] Инкапсулируйте общие методы и глобальные данные

Введение статьи

  1. Обычные методы инструмента, глобальные данные
  2. Все методы и вычисляемые свойства, определенные ниже, будут смонтированы на всех страницах .vue.

Примечание. Со стороны апплета вычисляемые свойства будут смонтированы в объекте Page всех страниц в виде объектов данных. Поэтому в случае большого объема данных для оптимизации производительности используйте форму вызова метода для получения динамически, чтобы не занимать слишком много памяти.

banner.jpg

(1) onBackPress

Введение: 【Платформа приложений】Отключите загрузку после нажатия кнопки возврата, чтобы предотвратить загрузку из-за ошибки страницы после нажатия кнопки возврата.

// #ifdef APP-VUE

 onBackPress() {
	uni.hideLoading()
    }
       
// #endif     ----结束条件编译

methods

Метод класса перехода маршрутизации

(2) SET_ПАРАМ

Введение: создание кросс-страничной переменной (сGET_PARAMиспользуется парами)

 SET_PARAM(val) {
	this.SET_GLOBAL('pageParam', val)
    }

(3) ПОЛУЧИТЬ_ПАРАМ

Введение. Получите предварительно подготовленные кросс-страничные переменные (с помощьюSET_PARAMиспользуется парами)

 GET_PARAM() {
	return this.GET_GLOBAL('pageParam')
     }

(4) НАВ_ТО

Введение: Перейти на страницу

NAV_TO(url, param, usePageParam) {
	uni.navigateTo({
		url: this.handleNav(url, param, usePageParam)
	  })
    }

(5) НАВ_НАЗАД

Введение: Вернуться на предыдущую страницу ----delta 参数为返回的次数

NAV_BACK(delta = 1) {
	uni.navigateBack({
		delta
	 })
   }

(6) JUMP_TO

Введение: Перейти на страницу, вы не можете вернуться после прыжка

JUMP_TO(url, param, usePageParam) {
	uni.redirectTo({
	url: this.handleNav(url, param, usePageParam)
        })
   }

(7) TAB_TO

Введение: переход на вкладку

TAB_TO(url, param) {
	uni.switchTab({
	url: this.handleNav(url, param, true)
        })
  }

(8) RELAUNCH_TO

Введение: перезапустите приложение и перейдите на указанную страницу.

RELAUNCH_TO(url) {
	uni.reLaunch({
	url
	})
 }

(9) ПОЛУЧИТЬ_ГЛОБАЛЬНО

Введение: получить глобальную переменную ----key 为键名

GET_GLOBAL(key) {
	return this.$store.state[key]
 }

(10) SET_GLOBAL

Введение: установка глобальной переменной ----key 为键名----val 为值

SET_GLOBAL(key, val) {
	this.$store.commit(key, val)
 }

(11) CLEAR_GLOBAL

Введение: очистка глобальных переменных

CLEAR_GLOBAL() {
	this.$store.commit('clear')
	uni.removeStorageSync('token')
 }

(12) SET_STORAGE

Введение: запись данных в локальный кеш

SET_STORAGE(key, data) {
	if (data === null) {
		uni.removeStorageSync(key)
	} else {
		uni.setStorageSync(key, data)
	}
 }

(13) ПОЛУЧИТЬ_ХРАНИЛИЩЕ

Введение: получение данных, которые ранее были записаны в локальный кеш

GET_STORAGE(key) {
	return uni.getStorageSync(key)
 }

(14) CLEAR_STORAGE

Введение: очистить локальный кеш

CLEAR_STORAGE() {
	uni.clearStorageSync()
 }

Метод класса всплывающей подсказки

(15) ТОСТ

Введение: Отображение окна подсказки ----title 为提示文字----mask 为是否禁止点击----icon 为显示图标,可以改为 'success'

TOAST(title, icon = 'none', mask = false) {
	uni.showToast({
		title,
		icon,
		mask
	})
 }

(16) HIDE_TOAST

Введение: Прекратить показ всплывающей подсказки

HIDE_TOAST() {
	uni.hideToast()
 }

(17) ЗАГРУЗКА

Введение: Показать загрузку подсказки ----title 为提示文字----mask 为是否禁止点击

LOADING(title, mask = true) {
	uni.showLoading({
		title,
		mask
	})
 }

(18) HIDE_LOADING

Введение: Прекратить показ запроса на загрузку

HIDE_LOADING() {
	uni.hideLoading()
 }

(19) ПОДТВЕРДИТЬ

Введение: Показать окно подтверждения ----title 为标题----content 为提示框文字内容----showCancel 为是否显示取消按钮

async CONFIRM(title, content, showCancel = false) {
	return new Promise(res => {
		uni.showModal({
			title,
			content,
			showCancel,
		success: ({
			confirm
		    }) => {
			res(confirm)
		     },
		fail: () => {
			res(false)
		     }
		})
	   })
  }

глобальный метод класса событий

(20) SET_TITLE

Введение: Установить заголовок страницы

SET_TITLE(title) {
	uni.setNavigationBarTitle({
		title
	})
 }

(21) КОНФИГУРАЦИЯ

Введение: из/config.jsПолучить элемент конфигурации в/config.js Если вы не можете получить его, перейдите к /common/config.default.jsПолучить значение по умолчанию в ----path 为配置项的访问路径

Пример: Следующий оператор получает, включен ли круглый аватар глобальноthis.CONFIG('pageConfig.roundAvatar')

CONFIG(path) {
	return get(globalConfig, path, get(defaultConfig, path))
 }

(22) ВКЛ.

Введение: прослушивание глобального события

ON(name, func) {
	uni.$on(name, func)
 }

(23) ОДИН РАЗ

Введение: слушайте только одно глобальное событие за раз

ONCE(name, func) {
	uni.$once(name, func)
 }

(24) ИЗЛУЧАТЬ

Введение: запуск глобального события

EMIT(name, data) {
	uni.$emit(name, data)
 }

(25) ВЫКЛ.

Введение: удаление прослушивателей глобальных событий

OFF(name, func) {
	uni.$off(name, func)
 }

Извлечь указанный метод класса данных

(26) FETCH_ИСТОЧНИК ДАННЫХ

Введение: извлечение данных источника данных с указанным значением кода

async FETCH_DATASOURCE(code) {
	if (!code) {
		return []
	}

	return await this.HTTP_GET('/datasource/map', {
		code,
		ver: ''
	})
 }

(27) FETCH_ENCODE

Введение. Извлеките закодированные в форме данные указанного номера правила.

async FETCH_ENCODE(rulecode) {
	if (!rulecode) {
		return ''
	}

	return await this.HTTP_GET('/coderule/code', rulecode)
 }

(28) FETCH_FILEINFO

Введение: извлеките информацию о файле с указанным идентификатором

async FETCH_FILEINFO(fileId) {
	if (!fileId) {
		return null
	}

	return await this.HTTP_GET('/annexes/wxfileinfo', fileId)
 }

метод класса запроса

(29) HTTP_GET

Введение: ИнкапсулированныйGETзапрос, интегрирует информацию аутентификации, возвращает результат запроса илиnullи работать с сетевыми ошибками, возвращаемыми кодами ошибок и неверным статусом входа.urlадрес запроса,dataОтправьте данные для сопровождения запроса

async HTTP_GET(url, data, showTips) {
	const [err, res] = await this.requestBase(url, data, null, 'GET')
		return this.handleResult(err, res, showTips)
 }

(30) HTTP_POST

Введение: ИнкапсулированныйPOSTзапрос, интегрирует информацию аутентификации, возвращает результат запроса илиnullи работать с сетевыми ошибками, возвращаемыми кодами ошибок и неверным статусом входа.urlадрес запроса,dataОтправьте данные для сопровождения запроса

async HTTP_POST(url, data, showTips) {
	const [err, res] = await this.requestBase(url, data, null, 'POST')
                return this.handleResult(err, res, showTips)
 }

(31) ПОЛУЧИТЬ

Введение: инициироватьGET 请求, который инкапсулирует аутентификацию,urlадрес запроса,dataДля отправленных данных, которые сопровождают запрос, возвращаемый результат представляет собой массив:[error, result],errorУказывает на ошибку, обычно сетевую, запрос, скорее всего, вообще не отправляется,resultВключать{ statusCode, headers, data }Представляет код состояния, заголовок ответа, данные

async GET(url, data, header) {
	return await this.requestBase(url, data, header, 'GET')
 }

(32) ПОСТ

Введение: инициироватьPOST 请求, который инкапсулирует аутентификацию,urlадрес запроса,dataДля отправленных данных, которые сопровождают запрос, возвращаемый результат представляет собой массив:[error, result],errorУказывает на ошибку, обычно сетевую, запрос, скорее всего, вообще не отправляется,resultВключать{ statusCode, headers, data }Представляет код состояния, заголовок ответа, данные

async POST(url, data, header) {
	return await this.requestBase(url, data, header, 'POST')
 }

Методы загрузки и загрузки файлов класса

(33) HTTP_UPLOAD

Введение: загрузка инкапсулированного файла, интегрированная информация аутентификации, возвращаемое значение интерфейса илиnullи работать с сетевыми ошибками, возвращаемыми кодами ошибок и неверным статусом входа.urlадрес запроса,filePathпуть к временному файлу,formDataОтправьте данные для сопровождения запроса

async HTTP_UPLOAD(filePath, formData) {
	const [err, res] = await this.UPLOAD('/annexes/wxupload', filePath, formData)
        return this.handleResult(err, res)
 }

(34) HTTP_DOWNLOAD

Введение: загрузка инкапсулированного файла, интеграция аутентификационной информации, возврат значения интерфейса илиnullи работать с сетевыми ошибками, возвращаемыми кодами ошибок и неверным статусом входа.urlадрес запроса,formDataОтправьте данные для сопровождения запроса

async HTTP_DOWNLOAD(formData) {
	const [err, res] = await this.DOWNLOAD('/annexes/wxdown', formData)
        return this.handleResult(err, res)
 }

(35) ЗАГРУЗИТЬ

Введение: Загрузите файл (локальный временный файл), который инкапсулирует аутентификацию,urlадрес отправки,filePathлокальный путь к временному файлу,formDataДля параметров, прикрепленных к загрузке, возвращаемый результат представляет собой массив:[error, result],errorУказывает на ошибку, обычно сетевую, запрос, скорее всего, вообще не отправляется,resultВключать{ statusCode, data }Представлять код состояния и данные, возвращаемые интерфейсом.

async UPLOAD(url, filePath, formData) {
	const uploadUrl = this.handleUrl(url)
	const query = {
		loginMark: this.getLoginMark(),
		token: this.GET_GLOBAL('token')
	  }
          if (formData && typeof formData === 'object') {
		Object.assign(query, formData)
	  } else if (typeof formData === 'string') {
		Object.assign(query, {
		data: formData
	     })
	  }

	 // #ifdef MP-DINGTALK ----钉钉小程序
         
	 return new Promise((res, rej) => {
		dd.uploadFile({
			url: uploadUrl,
			filePath,
			fileName: 'file',
			fileType: 'image',
			formData: query,
				success: dt => {
					dt.data = JSON.parse(dt.data)
					res([null, dt])
				},
				fail: rs => {
					rej([rs, null])
				}
			 })
		})
	 // #endif

	 // #ifndef MP-DINGTALK ----钉钉小程序
         
		return uni.uploadFile({
			url: uploadUrl,
			filePath,
			name: 'file',
			fileType: 'image',
			formData: query
		}).then(([err, result]) => {
			if (!err) {
				result.data = JSON.parse(result.data)
				return [null, result]
			} else {
				return [err, null]
			}

		})
	// #endif
	}

(36) СКАЧАТЬ

Введение: Загрузите файл (временный файл после загрузки), который инкапсулирует аутентификацию,urlдля запрошенного адреса,formDataДля параметров, прикрепленных к запросу, возвращаемый результат представляет собой массив:[error, result],errorУказывает на ошибку, обычно сетевую, запрос, скорее всего, вообще не отправляется,resultВключать{ statusCode, tempFilePath }Соответственно представлять код состояния и путь к временному файлу после скачивания

async DOWNLOAD(url, formData) {
	let downloadUrl = this.handleUrl(url)
        const query = {}
	if (formData && typeof formData === 'object') {
		Object.assign(query, formData)
	} else if (typeof formData === 'string') {
		Object.assign(query, {
			data: formData
	})
    }
    downloadUrl = downloadUrl + '?' + this.URL_QUERY(query, true)
                  return uni.downloadFile({
			url: downloadUrl
			}).then(([err, result]) => {
			        if (!err) {
				         result.data = {
						data: result.tempFilePath
					}
					result.statusCode = 200
				}

				return [err, result]
			})
		}

Получить глобальные данные клиента

(37) FETCH_CLIENTDATA

Введение: извлеките глобальные данные клиента и запишите их непосредственно в глобальную переменную, которая в настоящее время включает в себя: компанию, отдел, персонал, словарь данных.

async FETCH_CLIENTDATA() {
    await Promise.all([
	this.HTTP_GET('/company/map').then(res => this.SET_GLOBAL('company', res.data || {})),
	this.HTTP_GET('/department/map').then(res => this.SET_GLOBAL('department', res.data ||         {})),
	this.HTTP_GET('/user/map').then(res => this.SET_GLOBAL('user', res.data || {})),
	this.HTTP_GET('/dataitem/map').then(res => this.SET_GLOBAL('dataDictionary', res.data           || {}))
	])
  }

Общие методы интерфейса

(38) КОПИРОВАТЬ

Введение: использованиеJSONSerialize клонирует объект или массив

COPY(val) {
	return JSON.parse(JSON.stringify(val))
 }

(39) ГУИД

Введение: сделать 32-битнуюGUIDслучайная строка,joinCharРазделитель, по умолчанию подчеркивание

GUID(joinChar = '_') {
   return `xxxxxxxx${joinChar}xxxx${joinChar}4xxx${joinChar}yxxx${joinChar}xxxxxxxxxxxx`.replace(/[xy]/g,    c => {
	  const r = Math.random() * 16 | 0;
	  const v = c === 'x' ? r : (r & 0x3 | 0x8);
          return v.toString(16);
	})
 }

(40) МД5

Введение: получить код MD5 указанной строки

MD5(val = '') {
	return md5(val)
 }

(41) TABLEITEM_DATEFORMAT

Введение. Преобразование времени и даты в определенный формат (обычно используемый для<l-list-item>),datetimeStringДля форматируемой строки даты и времени возвращаемое значение представляет собой массив, его также можно использовать непосредственно в виде строки.

Пример:

  1. Возвращает, если дата является текущим днем['今天 17:32']или'今天 17:32'
  2. Возвращает, если дата в этом году['6月8日', '17:32']или'6月8日 17:32'
  3. Если дата не в этом году, вернуть['2018-06-08']или'2018-06-08'
TABLEITEM_DATEFORMAT(datetimeString) {
        const dt = moment(datetimeString)
        let result = []

        if (!dt.isValid()) {
                result.toString = () => ''
                return result
        }

        const now = moment()

        if (dt.isSame(now, 'day')) {
                result = [`今天 ${dt.format('HH:mm')}`]
                result.toString = () => `今天 ${dt.format('HH:mm')}`

        } else if (dt.isSame(now, 'year')) {
                result = [dt.format('M月D日'), dt.format('HH:mm')]
                result.toString = () => dt.format('M月D日') + ' ' + dt.format('HH:mm')

        } else {
                result = [dt.format('YYYY-MM-DD')]
                result.toString = () => dt.format('YYYY-MM-DD')
        }

        return result
 }

(42) URL_ЗАПРОС

Введение: кодирование и преобразование объекта вurlСтрока запроса,objобъект для преобразования. Если значение пустое, оно будет проигнорировано. Если значение является объектом, оно будет преобразовано вJSON 字符串,authСледует ли программировать аутентификационную информацию

URL_QUERY(obj, auth = false) {
        let queryObject = obj || {}
        if (typeof obj === 'string') {
                queryObject = {
                        data: obj
                }
        }
        if (auth) {
                Object.assign(queryObject, {
                        loginMark: this.getLoginMark(),
                        token: this.GET_GLOBAL('token')
                })
        }
        return Object.entries(queryObject)
                .filter(([k, v]) => k && v)
                .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(typeof v === 'object' ? JSON.stringify(v) : v))
                .join('&')
 }

(43) КОНВЕРТ_HTML

Введение: преобразование строки вHTMLФорматирование (обработка HTML для страниц форм)

CONVERT_HTML(str) {
        if (!str) {
                return ''
        }

        return str
                .replace(/{@zuojian@}|{@youjian@}|{@and@}/g, tag => ({
                        '{@zuojian@}': '<',
                        '{@youjian@}': '>',
                        '{@and@}': '&'
                })[tag] || tag)
                .replace(/&amp;|&lt;|&gt;|&#39;|&quot;/g, tag => ({
                        '&amp;': '&',
                        '&lt;': '<',
                        '&gt;': '>',
                        '&#39;': "'",
                        '&quot;': '"'
                })[tag] || tag)
 }

(44) MP_SHARE_ENCODE

Введение: используется для кодирования апплета для обмена сообщениями.urlстрока запроса (также печатается в среде разработки),pageParamОн переносится, когда вы нажимаете, чтобы поделиться сообщением, чтобы перейти кpageParam,queryОн переносится, когда вы нажимаете, чтобы поделиться сообщением, чтобы перейти кquery,pagePathЩелкните сообщение общего доступа, чтобы перейти на страницу апплета (по умолчанию это текущая страница) и вернуть закодированную строку запроса.

MP_SHARE_ENCODE(pageParam, query, pagePath) {
        const shareObj = {
                fromUser: this.GET_GLOBAL('loginUser').userId,
                fromPlatform: this.PLATFORM,
                timestamp: new Date().valueOf(),
                pagePath: pagePath || this.pagePath,
                query: query,
                pageParam,
                learun: this.APP_VERSION
        }
        const result = this.URL_QUERY(shareObj)

        if (this.DEV) {
                console.log('【您正在分享***小程序页面】')
                console.log('====分享对象:====')
                console.log(shareObj)
                console.log('====启动路径:====')
                console.log('/pages/home')
                console.log('====启动参数:====')
                console.log(result)
                console.log('====(以上消息仅开发模式可见)====')
        }

        return result
 }

(45) MP_SHARE_DECODE

Введение: проанализируйте строку обмена мини-программой (автоматически адаптируется к мини-программе WeChat).urlкод), общая информация, полученная в апплете WeChat,urlКодируется, требуется декодирование; апплет Alipay/DingTalk не требует декодирования

MP_SHARE_DECODE(info) {
        // #ifdef MP-WEIXIN
        const shareInfo = mapValues(info, decodeURIComponent)
        // #endif

        shareInfo.pageParam = shareInfo.pageParam ? JSON.parse(shareInfo.pageParam) : undefined
        shareInfo.query = shareInfo.query ? this.URL_QUERY(JSON.parse(shareInfo.query)) : undefined

        if (this.DEV) {
                console.log('【您通过小程序消息分享启动了***小程序】')
                console.log('====小程序分享对象:====')
                console.log(shareInfo)
                console.log('====即将转入页面:====')
                console.log(shareInfo.pagePath)
                console.log('====设置的 url query:====')
                console.log(shareInfo.query)
                console.log('====设置的 pageParam:====')
                console.log(shareInfo.pageParam)
                console.log('====(以上消息仅开发模式可见)====')
        }

        this.SET_GLOBAL('pageParam', shareInfo.pageParam)
        uni.navigateTo({
                url: `${shareInfo.pagePath}?${this.URL_QUERY(shareInfo.query)}`
        })
 }

внутренний метод

(46) ручкаNav

Введение: обработка переходов между страницамиurlи параметры

handleNav(url, param, usePageParam) {
        let query = ''
        if (param && usePageParam) {
                this.SET_PARAM(param)
        } else if (param && !usePageParam) {
                query += '?' + Object.entries(param).filter(([k, v]) => k && v).map(([k, v]) => k + '=' + v).join('&')
        }

        return url + query
 }

(47) получитьЛогинМарк

Введение: выборка из глобальных переменных и кешейloginMarkИдентификатор устройства, если его невозможно получить, будет сгенерирован новый

getLoginMark() {
        if (this.GET_GLOBAL('loginMark')) {
                return this.GET_GLOBAL('loginMark')
        }

        const storageData = uni.getStorageSync('loginMark')
        if (storageData && storageData !== 'null' && storageData !== 'undefined') {
                this.SET_GLOBAL('loginMark', storageData)

                return storageData
        }

        const newLoginMark = this.GUID()
        this.SET_GLOBAL('loginMark', newLoginMark)
        uni.setStorageSync('loginMark', newLoginMark)

        return newLoginMark
 }

(48) дескрипторурл

Введение: обработкаurl, чтобы определить, следует ли добавлять префикс фонового адреса

handleUrl(url) {
        let result = url
        if (result.startsWith('http://') || result.startsWith('https://')) {
                return result
        }
        if (!result.startsWith(this.API)) {
                result = this.API + result
        }

        return result
 }

(49) запросбаза

представлять:HTTPбазовый метод запроса

async requestBase(url, data, header, method = 'GET') {
        const requestUrl = this.handleUrl(url)
        const requestHeader = header || {}

        let requestData = {
                loginMark: this.getLoginMark(),
                token: this.GET_GLOBAL('token') || ''
        }
        if (data && typeof data === 'object') {
                requestData.data = JSON.stringify(data)
        } else if (data) {
                Object.assign(requestData, {
                        data
                })
        }

        return uni.request({
                url: requestUrl,
                method,
                header: {
                        'content-type': 'application/x-www-form-urlencoded',
                        ...requestHeader
                },
                data: requestData
        })
 }

(50) обработать результат

Введение: обработка возвращаемого результата метода сетевого запроса

handleResult(err, result, tips) {
    // 出现错误,一般是网络连接错误
    if (err || !result) {
            uni.hideLoading()
            uni.showToast({
                    title: '网络请求失败,请检查您的网络连接',
                    icon: 'none'
            })

            return null
    }

    // 状态码为 410,登录状态失效
    if (result.statusCode === 410 || (result.data && result.data.code === 410)) {
            uni.hideLoading()
            uni.showToast({
                    title: '登录状态无效,正在跳转到登录页…',
                    icon: 'none'
            })
            this.CLEAR_GLOBAL()
            uni.reLaunch({
                    url: '/pages/login'
            })

            return null

            uni.hideLoading()
            if (tips) {
                    const errInfo = (result.data && result.data.info) || '(未知原因)'
                    const errTips = typeof tips === 'string' ? tips : '请求数据时发生错误'
                    uni.showToast({
                            title: `${errTips}: ${errInfo}`,
                            icon: 'none'
                    })
            }

            return null
    }

    return result.data.data
 }

computed

(51) API

Введение: запрос адреса фонового интерфейса

API() {
        return this.$store.state.apiRoot ||this.CONFIG('apiHost')[this.DEV ?this.CONFIG('devApiHostIndex') : this.CONFIG('prodApiHostIndex')]
 }

(52) ПУТЬ

Описание: Путь к текущей странице

PATH() {
        if (!getCurrentPages) {
                return ''
        }
        const pages = getCurrentPages()

        return pages ? '/' + pages.slice(-1)[0].route : ''
 }

(53) ДЕВ

Введение: Является ли текущая среда разработки

DEV() {
        return process.env.NODE_ENV === 'development'
 }

(54) DEV_ONLY_GLOBAL

Введение: [Только в режиме разработки] Получение текущих глобальных переменных недопустимо в производственной среде и официальном выпуске, поскольку глобальные переменные на стороне апплета будут монтироваться на каждой странице, что влияет на производительность.

DEV_ONLY_GLOBAL() {
        return process.env.NODE_ENV === 'development' && this.$store.state
 }

(55) ПРИЛОЖЕНИЕ_ВЕРСИЯ

Введение: Получите номер текущей мобильной версии (определен вconfig.js)

APP_VERSION() {
        return this.CONFIG('appVersion')
 }

(56) ПЛАТФОРМА

Введение: текущая рабочая платформа, стоимость'alipay'/weixin'/'dingtalk'/'h5'/'app'/'unknow'

PLATFORM() {
        let result = 'unknow'

        // #ifdef MP-ALIPAY
        // #ifndef MP-DINGTALK
        result = 'alipay'
        // #endif
        // #ifdef MP-DINGTALK
        result = 'dingtalk'
        // #endif
        // #endif

        // #ifdef MP-WEIXIN
        result = 'weixin'
        // #endif

        // #ifdef H5
        result = 'h5'
        // #endif

        // #ifdef APP-VUE
        result = 'app'
        // #endif

        return result
 }

(57) ПЛАТФОРМА_ТЕКСТ

Введение: Получите полное китайское название текущей работающей платформы и получите значение'支付宝小程序'/微信小程序'/'钉钉小程序'/'移动 H5 '/'手机 App'/'(未知)'

PLATFORM_TEXT() {
        let result = '(未知)'

        // #ifdef MP-ALIPAY
        // #ifndef MP-DINGTALK
        result = '支付宝小程序'
        // #endif
        // #ifdef MP-DINGTALK
        result = '钉钉小程序'
        // #endif
        // #endif

        // #ifdef MP-WEIXIN
        result = '微信小程序'
        // #endif

        // #ifdef H5
        result = '移动 H5 '
        // #endif

        // #ifdef APP-VUE
        result = '手机 App '
        // #endif

        return result
 }