diff --git a/packages/uni-api/src/index.ts b/packages/uni-api/src/index.ts index 3d0fd648ea3364e8f1159db209dfd7f21740ed97..4d09d514e81ddbdb061277987cccfaba7a20201c 100644 --- a/packages/uni-api/src/index.ts +++ b/packages/uni-api/src/index.ts @@ -79,6 +79,7 @@ export * from './protocols/ui/window' export * from './protocols/plugin/getProvider' export * from './protocols/plugin/oauth' +export * from './protocols/plugin/share' // helpers export { defineOnApi, diff --git a/packages/uni-api/src/protocols/plugin/share.ts b/packages/uni-api/src/protocols/plugin/share.ts new file mode 100644 index 0000000000000000000000000000000000000000..4f0dde86bbe7cbf317dc3adad74c3c2d3302c3ac --- /dev/null +++ b/packages/uni-api/src/protocols/plugin/share.ts @@ -0,0 +1,79 @@ +import { elemInArray } from '../../helpers/protocol' + +export const API_SHREA = 'share' +export type API_TYPE_SHARE = typeof uni.share +const SCENE: Parameters[0]['scene'][] = [ + 'WXSceneSession', + 'WXSenceTimeline', + 'WXSceneFavorite', +] +export const SahreOptions: ApiOptions = { + formatArgs: { + scene(value, params) { + if (params.provider === 'weixin' && (!value || !SCENE.includes(value))) { + return `分享到微信时,scene必须为以下其中一个:${SCENE.join('、')}` + } + }, + summary(value, params) { + if (params.type === 1 && !value) { + return '分享纯文本时,summary必填' + } + }, + href(value, params) { + if (params.type === 0 && !value) { + return '分享图文时,href必填' + } + }, + imageUrl(value, params) { + if ([0, 2, 5].includes(Number(params.type)) && !value) { + return '分享图文、纯图片、小程序时,imageUrl必填,推荐使用小于20Kb的图片' + } + }, + mediaUrl(value, params) { + if ([3, 4].includes(Number(params.type)) && !value) { + return '分享音乐、视频时,mediaUrl必填' + } + }, + miniProgram(value, params) { + if (params.type === 5 && !value) { + return '分享小程序时,miniProgram必填' + } + }, + }, +} +export const ShareProtocols: ApiProtocol = { + provider: { + type: String as any, + required: true, + }, + type: Number as any, + title: String, + scene: String as any, + summary: String, + href: String, + imageUrl: String, + mediaUrl: String, + miniProgram: Object, +} + +export const API_SHARE_WITH_SYSTEM = 'shareWithSystem' +export type API_TYPE_SHARE_WITH_SYSTEM = typeof uni.shareWithSystem +const TYPE: Parameters[0]['type'][] = [ + 'text', + 'image', +] +export const ShareWithSystemOptions: ApiOptions = { + formatArgs: { + type(value, params) { + if (!TYPE.includes(value)) return '分享参数 type 不正确' + return elemInArray(value, TYPE) + }, + }, +} +export const ShareWithSystemProtocols: ApiProtocol = + { + type: String as any, + summary: String, + href: String, + imageUrl: String, + } diff --git a/packages/uni-app-plus/src/service/api/index.ts b/packages/uni-app-plus/src/service/api/index.ts index 2156c1c9048a2c78d7332563ae2f9382c0c9baec..41bddf03af51289835ca4145b47834956ef690be 100644 --- a/packages/uni-app-plus/src/service/api/index.ts +++ b/packages/uni-app-plus/src/service/api/index.ts @@ -35,3 +35,4 @@ export * from './ui/popup/showToast' export * from './plugin/getProvider' export * from './plugin/oauth' +export * from './plugin/share' diff --git a/packages/uni-app-plus/src/service/api/plugin/oauth.ts b/packages/uni-app-plus/src/service/api/plugin/oauth.ts index 58dc87395521e932b550a0c220350e9cb2ab243a..e699f5a592b80167144b205ac3174bd030a5728a 100644 --- a/packages/uni-app-plus/src/service/api/plugin/oauth.ts +++ b/packages/uni-app-plus/src/service/api/plugin/oauth.ts @@ -16,7 +16,7 @@ import { API_TYPE_CLOSE_AUTH_VIEW, defineAsyncApi, } from '@dcloudio/uni-api' -import { isPlainObject } from '@vue/shared' +import { isPlainObject, toTypeString } from '@vue/shared' import { warpPlusSuccessCallback, warpPlusErrorCallback, @@ -202,11 +202,9 @@ function univerifyButtonsClickHandling( errorCallback: Function ) { if ( - univerifyStyle && isPlainObject(univerifyStyle) && univerifyStyle.buttons && - Object.prototype.toString.call(univerifyStyle.buttons.list) === - '[object Array]' && + toTypeString(univerifyStyle.buttons.list) === '[object Array]' && univerifyStyle.buttons.list!.length > 0 ) { univerifyStyle.buttons.list!.forEach((button, index) => { diff --git a/packages/uni-app-plus/src/service/api/plugin/share.ts b/packages/uni-app-plus/src/service/api/plugin/share.ts new file mode 100644 index 0000000000000000000000000000000000000000..665b6f6816819a7dac26650bdc5b2d2862ec13d9 --- /dev/null +++ b/packages/uni-app-plus/src/service/api/plugin/share.ts @@ -0,0 +1,157 @@ +import { getRealPath } from '@dcloudio/uni-platform' +import { warpPlusErrorCallback } from '../../../helpers/plus' +import { + defineAsyncApi, + API_SHREA, + API_TYPE_SHARE, + SahreOptions, + ShareProtocols, + API_SHARE_WITH_SYSTEM, + API_TYPE_SHARE_WITH_SYSTEM, + ShareWithSystemOptions, + ShareWithSystemProtocols, +} from '@dcloudio/uni-api' + +// 0:图文,1:纯文字,2:纯图片,3:音乐,4:视频,5:小程序 +const TYPES = { + 0: { + name: 'web', + title: '图文', + }, + 1: { + name: 'text', + title: '纯文字', + }, + 2: { + name: 'image', + title: '纯图片', + }, + 3: { + name: 'music', + title: '音乐', + }, + 4: { + name: 'video', + title: '视频', + }, + 5: { + name: 'miniProgram', + title: '小程序', + }, +} + +const parseParams = (args: UniApp.ShareOptions): T | string => { + args.type = args.type || 0 + + let { + provider, + type, + title, + summary: content, + href, + imageUrl, + mediaUrl: media, + scene, + miniProgram, + } = args + + if (typeof imageUrl === 'string' && imageUrl) { + imageUrl = getRealPath(imageUrl) + } + + const shareType = TYPES[type] + if (shareType) { + const sendMsg = { + provider, + type: shareType.name, + title, + content, + href, + pictures: [imageUrl], + thumbs: imageUrl ? [imageUrl] : undefined, + media, + miniProgram, + extra: { + scene, + }, + } + if (provider === 'weixin' && (type === 1 || type === 2)) { + delete sendMsg.thumbs + } + return sendMsg as unknown as T + } + return '分享参数 type 不正确' +} + +const sendShareMsg = function ( + service: PlusShareShareService, + params: Data, + resolve: (args?: any) => void, + reject: (errMsg: string, errRes?: any) => void, + method = 'share' +) { + const errorCallback = warpPlusErrorCallback(reject) + + service.send( + params, + () => { + resolve() + }, + errorCallback + ) +} + +export const share = defineAsyncApi( + API_SHREA, + (params, { resolve, reject }) => { + const res = parseParams(params) + const errorCallback = warpPlusErrorCallback(reject) + + if (typeof res === 'string') { + return reject(res) + } else { + params = res + } + + plus.share.getServices((services) => { + const service = services.find(({ id }) => id === params.provider) + if (!service) { + reject('service not found') + } else { + if (service.authenticated) { + sendShareMsg(service, params, resolve, reject) + } else { + service.authorize( + () => sendShareMsg(service, params, resolve, reject), + errorCallback + ) + } + } + }, errorCallback) + }, + ShareProtocols, + SahreOptions +) + +export const shareWithSystem = defineAsyncApi( + API_SHARE_WITH_SYSTEM, + ({ type, imageUrl, summary, href }, { resolve, reject }) => { + const errorCallback = warpPlusErrorCallback(reject) + + if (typeof imageUrl === 'string' && imageUrl) { + imageUrl = getRealPath(imageUrl) + } + plus.share.sendWithSystem( + { + type, + pictures: imageUrl ? [imageUrl] : undefined, + content: summary, + href, + }, + () => resolve(), + errorCallback + ) + }, + ShareWithSystemProtocols, + ShareWithSystemOptions +)