| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- type QQMapApi = {
- IP_LOCATION: string
- GEOCODER: string
- DISTANCE: string
- SCAN_QR_CODE: string
- }
- type QQMapConfig = {
- KEY: string
- API: QQMapApi
- }
- type LocationPoint = {
- longitude: number
- latitude: number
- }
- type LocationResult = {
- code: number
- data?: UTSJSONObject
- message: string
- result?: any
- }
- const QQ_MAP: QQMapConfig = {
- KEY: 'SIFBZ-2UJEZ-FZIXF-TAVLV-6GWVK-ZEBZX',
- API: {
- IP_LOCATION: 'https://apis.map.qq.com/ws/location/v1/ip',
- GEOCODER: 'https://apis.map.qq.com/ws/geocoder/v1/',
- DISTANCE: 'https://apis.map.qq.com/ws/distance/v1/',
- SCAN_QR_CODE: 'https://apis.map.qq.com/ws/barcode/v1/scan',
- }
- }
- const showLocationSettingModal = () : void => {
- uni.showModal({
- title: '提示',
- content: '请先开启定位权限后重试',
- showCancel: false,
- confirmText: '我知道了',
- })
- }
- const buildLocationData = (point: LocationPoint, num: number) : UTSJSONObject => {
- return {
- location: {
- longitude: point.longitude,
- latitude: point.latitude,
- },
- num: num,
- } as UTSJSONObject
- }
- /**
- * 扫描二维码
- */
- export const scanQRCode = async () : Promise<any> => {
- return new Promise<any>((resolve: (value: any) => void, reject: (reason?: any) => void) => {
- uni.scanCode({
- scanType: ['qrCode', 'barCode'],
- success: (res) => {
- resolve((res.result as string | null) ?? '')
- },
- fail: (err) => {
- reject(err)
- }
- })
- })
- }
- /**
- * 请求位置授权
- */
- export const requestLocationAuth = async () : Promise<void> => {
- // #ifdef MP-WEIXIN
- const settings = await uni.getSetting({
- withSubscriptions: false,
- })
- const authSetting = settings.authSetting as UTSJSONObject | null
- const hasLocationAuth = (authSetting?.['scope.userLocation'] as boolean | null) ?? false
- if (!hasLocationAuth) {
- await uni.authorize({
- scope: 'scope.userLocation',
- success: () => {
- console.log('用户已授权')
- },
- fail: () => {
- console.log('用户拒绝授权')
- showLocationSettingModal()
- },
- })
- }
- // #endif
- }
- /**
- * 发起定位相关请求
- */
- export const requestJsonp = async (url: string, params: UTSJSONObject | null) : Promise<any> => {
- try {
- const requestParams = params ?? ({} as UTSJSONObject)
- return await new Promise<any>((resolve: (value: any) => void, reject: (reason?: any) => void) => {
- uni.request({
- url: url,
- method: 'GET',
- data: requestParams,
- success: (res) => {
- const response = res.data as UTSJSONObject | null
- if (response == null) {
- reject(new Error('定位服务响应为空'))
- return
- }
- const status = (response['status'] as number | null) ?? 0
- if (status === 0) {
- resolve(response['result'] ?? response)
- return
- }
- reject(response)
- },
- fail: (err) => {
- reject(err)
- }
- })
- })
- } catch (error) {
- console.error('定位请求错误:', error)
- return null
- }
- }
- /**
- * 通过城市名字搜索
- */
- export const getCityNameInfo = async (cityName: string = '') : Promise<UTSJSONObject | null> => {
- try {
- const params = {
- address: cityName,
- key: QQ_MAP.KEY,
- } as UTSJSONObject
- const res = await requestJsonp(QQ_MAP.API.GEOCODER, params) as UTSJSONObject | null
- if (res == null) {
- return null
- }
- return {
- area_code: ((res['ad_info'] as UTSJSONObject | null)?.['adcode'] as string | null) ?? '',
- city: ((res['address_components'] as UTSJSONObject | null)?.['city'] as string | null) ?? '',
- latitude: ((res['location'] as UTSJSONObject | null)?.['lat'] as number | null) ?? 0,
- longitude: ((res['location'] as UTSJSONObject | null)?.['lng'] as number | null) ?? 0,
- } as UTSJSONObject
- } catch (error) {
- console.error('城市定位请求错误:', error)
- return null
- }
- }
- /**
- * 初始化微信配置
- */
- export const initWxConfig = async () : Promise<UTSJSONObject> => {
- return Promise.resolve({
- code: 200,
- message: '当前平台无需微信初始化',
- } as UTSJSONObject)
- }
- /**
- * 获取当前位置信息
- */
- export const getCurrentLocation = async () : Promise<LocationResult> => {
- return new Promise<LocationResult>((resolve: (value: LocationResult) => void, reject: (reason?: any) => void) => {
- let hasResolved = false
- const fallbackToIpLocation = async () : Promise<void> => {
- if (hasResolved) {
- return
- }
- try {
- const locationData = await requestJsonp(QQ_MAP.API.IP_LOCATION, {
- key: QQ_MAP.KEY,
- } as UTSJSONObject) as UTSJSONObject | null
- const location = locationData?.['location'] as UTSJSONObject | null
- if (location != null) {
- hasResolved = true
- resolve({
- code: 200,
- data: buildLocationData({
- longitude: (location['lng'] as number | null) ?? 0,
- latitude: (location['lat'] as number | null) ?? 0,
- }, 1),
- message: '获取IP定位成功',
- })
- return
- }
- reject({ code: 202, message: '获取位置失败' } as UTSJSONObject)
- } catch (e) {
- reject({ code: 202, message: 'IP定位异常' } as UTSJSONObject)
- }
- }
- const timeoutInfo = setTimeout(() => {
- fallbackToIpLocation()
- }, 3000)
- uni.getLocation({
- type: 'gcj02',
- success: (res) => {
- if (hasResolved) {
- return
- }
- hasResolved = true
- clearTimeout(timeoutInfo)
- const point: LocationPoint = {
- longitude: res.longitude,
- latitude: res.latitude,
- }
- uni.setStorageSync('locationInfo', point)
- resolve({
- code: 200,
- data: buildLocationData(point, 2),
- message: '获取位置成功',
- })
- },
- fail: () => {
- clearTimeout(timeoutInfo)
- showLocationSettingModal()
- reject({
- code: 202,
- message: '获取位置失败',
- } as UTSJSONObject)
- },
- })
- })
- }
- /**
- * 解析地理位置信息
- */
- export const parseLocation = async (location: UTSJSONObject) : Promise<LocationResult> => {
- try {
- const latitude = (location['latitude'] as number | null) ?? 0
- const longitude = (location['longitude'] as number | null) ?? 0
- const geoLocation = await requestJsonp(QQ_MAP.API.GEOCODER, {
- key: QQ_MAP.KEY,
- location: `${latitude},${longitude}`,
- } as UTSJSONObject)
- uni.setStorageSync('userAddress', geoLocation)
- return {
- code: 200,
- data: {
- geoLocation: geoLocation,
- } as UTSJSONObject,
- message: '解析地址成功',
- }
- } catch (error) {
- return {
- code: 500,
- message: '解析地址失败',
- }
- }
- }
- /**
- * 计算两点间距离
- */
- export const calculateDistance = async (startPoint: UTSJSONObject, endPoint: UTSJSONObject) : Promise<LocationResult> => {
- try {
- const startLatitude = (startPoint['latitude'] as number | null) ?? 0
- const startLongitude = (startPoint['longitude'] as number | null) ?? 0
- const endLatitude = (endPoint['latitude'] as number | null) ?? 0
- const endLongitude = (endPoint['longitude'] as number | null) ?? 0
- const result = await requestJsonp(QQ_MAP.API.DISTANCE, {
- from: `${startLatitude},${startLongitude}`,
- to: `${endLatitude},${endLongitude}`,
- key: QQ_MAP.KEY,
- mode: 'driving',
- } as UTSJSONObject) as UTSJSONObject | null
- const elements = result?.['elements'] as UTSArray<UTSJSONObject> | null
- if (elements != null && elements.length > 0) {
- const firstElement = elements[0]
- return {
- code: 200,
- data: {
- distance: (firstElement['distance'] as number | null) ?? 0,
- } as UTSJSONObject,
- result: result,
- message: '计算距离成功',
- }
- }
- throw new Error('无效的距离数据')
- } catch (error) {
- return {
- code: 202,
- message: '计算距离失败',
- }
- }
- }
- /**
- * 格式化数字为千分位
- */
- export const formatThousands = (number: number = 0) : string => {
- return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
- }
- /**
- * 手机号码脱敏处理
- */
- export const maskPhoneNumber = (phone: string = '') : string => {
- return phone.length > 0 ? phone.replace(/(\d{3})\d{6}(\d{2})/, '$1******$2') : ''
- }
- /**
- * 拨打电话
- */
- export const makePhoneCall = (phoneNumber: string) : Promise<any> => {
- const phone = phoneNumber.length > 0 ? phoneNumber : '19806196313'
- return new Promise<any>((resolve: (value: any) => void, reject: (reason?: any) => void) => {
- uni.makePhoneCall({
- phoneNumber: phone,
- success: () => {
- resolve({
- code: 200,
- message: '拨号成功',
- })
- },
- fail: (err) => {
- reject({
- code: 500,
- message: '拨号失败',
- error: err,
- })
- },
- })
- })
- }
|