添加 cool-share 插件
This commit is contained in:
@@ -4,7 +4,7 @@ globs: *.uts,*.uvue
|
|||||||
alwaysApply: false
|
alwaysApply: false
|
||||||
---
|
---
|
||||||
|
|
||||||
# ts
|
# ts | uts
|
||||||
|
|
||||||
- 所有方法必须在被调用之前进行定义,避免出现“先调用后定义”的情况。
|
- 所有方法必须在被调用之前进行定义,避免出现“先调用后定义”的情况。
|
||||||
- 当使用 {} 进行对象赋值时,必须显式声明类型,例如:{} as Data,确保类型安全与规范。
|
- 当使用 {} 进行对象赋值时,必须显式声明类型,例如:{} as Data,确保类型安全与规范。
|
||||||
|
|||||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -15,5 +15,8 @@
|
|||||||
"[ets]": {
|
"[ets]": {
|
||||||
"editor.defaultFormatter": "NailyZero.vscode-naily-ets"
|
"editor.defaultFormatter": "NailyZero.vscode-naily-ets"
|
||||||
},
|
},
|
||||||
"scss.lint.unknownAtRules": "ignore"
|
"scss.lint.unknownAtRules": "ignore",
|
||||||
|
"[xml]": {
|
||||||
|
"editor.defaultFormatter": "redhat.vscode-xml"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ Cool Unix 是一个高效的项目脚手架。它内置了 UI 组件库、Servic
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { $t, t } from "@/uni_modules/cool-unix";
|
import { $t, t } from "@/uni_modules/cool-ui";
|
||||||
import { useUi } from "@/uni_modules/cool-unix";
|
import { useUi } from "@/uni_modules/cool-ui";
|
||||||
|
|
||||||
const ui = useUi();
|
const ui = useUi();
|
||||||
|
|
||||||
|
|||||||
@@ -504,6 +504,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "other/router/query"
|
"path": "other/router/query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "other/share",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "Share 分享"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
73
pages/demo/other/share.uvue
Normal file
73
pages/demo/other/share.uvue
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<cl-page>
|
||||||
|
<view class="p-3">
|
||||||
|
<demo-item :label="t('分享文本')">
|
||||||
|
<cl-button @tap="shareText">{{ t("分享文本") }}</cl-button>
|
||||||
|
</demo-item>
|
||||||
|
|
||||||
|
<demo-item :label="t('分享图片')">
|
||||||
|
<cl-button @tap="shareImage">{{ t("分享图片") }}</cl-button>
|
||||||
|
</demo-item>
|
||||||
|
|
||||||
|
<demo-item :label="t('分享文件')">
|
||||||
|
<cl-button @tap="shareFile">{{ t("分享文件") }}</cl-button>
|
||||||
|
</demo-item>
|
||||||
|
|
||||||
|
<demo-item :label="t('分享链接')">
|
||||||
|
<cl-button @tap="shareLink">{{ t("分享链接") }}</cl-button>
|
||||||
|
</demo-item>
|
||||||
|
</view>
|
||||||
|
</cl-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { shareWithSystem } from "@/uni_modules/cool-share";
|
||||||
|
import DemoItem from "../components/item.uvue";
|
||||||
|
import { t } from "@/locale";
|
||||||
|
|
||||||
|
function shareText() {
|
||||||
|
shareWithSystem({
|
||||||
|
type: "text",
|
||||||
|
title: "Cool Unix 是一个高效的项目脚手架",
|
||||||
|
summary: "",
|
||||||
|
success: () => {
|
||||||
|
console.log("success");
|
||||||
|
},
|
||||||
|
fail: (error) => {
|
||||||
|
console.log("fail", error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function shareImage() {
|
||||||
|
shareWithSystem({
|
||||||
|
type: "image",
|
||||||
|
imageUrl: "https://cool-js.com/logo.png",
|
||||||
|
success: () => {
|
||||||
|
console.log("success");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function shareFile() {
|
||||||
|
shareWithSystem({
|
||||||
|
type: "file",
|
||||||
|
href: "https://show.cool-admin.com/用户导入模版.xlsx",
|
||||||
|
success: () => {
|
||||||
|
console.log("success");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function shareLink() {
|
||||||
|
shareWithSystem({
|
||||||
|
type: "link",
|
||||||
|
href: "https://cool-js.com/",
|
||||||
|
success: () => {
|
||||||
|
console.log("success");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -471,6 +471,11 @@ const data = computed<Item[]>(() => {
|
|||||||
label: "Router",
|
label: "Router",
|
||||||
icon: "compass-discover-line",
|
icon: "compass-discover-line",
|
||||||
path: "/pages/demo/other/router/index"
|
path: "/pages/demo/other/router/index"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Share",
|
||||||
|
icon: "share-line",
|
||||||
|
path: "/pages/demo/other/share"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
11
uni_modules/cool-share/index.d.ts
vendored
Normal file
11
uni_modules/cool-share/index.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
declare module "@/uni_modules/cool-share" {
|
||||||
|
export function shareWithSystem(options: {
|
||||||
|
type: "text" | "image" | "file" | "link" | "video" | "audio";
|
||||||
|
title?: string;
|
||||||
|
summary?: string;
|
||||||
|
href?: string;
|
||||||
|
imageUrl?: string;
|
||||||
|
success?: () => void;
|
||||||
|
fail?: (error: string) => void;
|
||||||
|
}): void;
|
||||||
|
}
|
||||||
84
uni_modules/cool-share/package.json
Normal file
84
uni_modules/cool-share/package.json
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"id": "cool-share",
|
||||||
|
"displayName": "cool-share",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "cool-share",
|
||||||
|
"keywords": [
|
||||||
|
"cool-share",
|
||||||
|
"share",
|
||||||
|
"系统分享"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^4.75"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "uts",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "",
|
||||||
|
"data": "",
|
||||||
|
"permissions": ""
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "u",
|
||||||
|
"aliyun": "u",
|
||||||
|
"alipay": "u"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "u",
|
||||||
|
"vue3": "u"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-android": "u",
|
||||||
|
"app-ios": "u"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "u",
|
||||||
|
"Android Browser": "u",
|
||||||
|
"微信浏览器(Android)": "u",
|
||||||
|
"QQ浏览器(Android)": "u"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "u",
|
||||||
|
"IE": "u",
|
||||||
|
"Edge": "u",
|
||||||
|
"Firefox": "u",
|
||||||
|
"Safari": "u"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "u",
|
||||||
|
"阿里": "u",
|
||||||
|
"百度": "u",
|
||||||
|
"字节跳动": "u",
|
||||||
|
"QQ": "u",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
package="uts.sdk.modules.coolShare">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<meta-data android:name="ScopedStorage" android:value="true" />
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true"
|
||||||
|
tools:replace="android:authorities">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/file_paths" />
|
||||||
|
</provider>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
3
uni_modules/cool-share/utssdk/app-android/config.json
Normal file
3
uni_modules/cool-share/utssdk/app-android/config.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"minSdkVersion": "21"
|
||||||
|
}
|
||||||
461
uni_modules/cool-share/utssdk/app-android/index.uts
Normal file
461
uni_modules/cool-share/utssdk/app-android/index.uts
Normal file
@@ -0,0 +1,461 @@
|
|||||||
|
import Intent from "android.content.Intent";
|
||||||
|
import Uri from "android.net.Uri";
|
||||||
|
import Context from "android.content.Context";
|
||||||
|
import File from "java.io.File";
|
||||||
|
import FileProvider from "androidx.core.content.FileProvider";
|
||||||
|
import { ShareWithSystemOptions } from "../interface.uts";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分享类型枚举
|
||||||
|
*/
|
||||||
|
const ShareType = {
|
||||||
|
TEXT: "text", // 纯文本分享
|
||||||
|
IMAGE: "image", // 图片分享
|
||||||
|
VIDEO: "video", // 视频分享
|
||||||
|
AUDIO: "audio", // 音频分享
|
||||||
|
FILE: "file", // 文件分享
|
||||||
|
LINK: "link" // 链接分享
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIME 类型映射
|
||||||
|
*/
|
||||||
|
const MimeTypes = {
|
||||||
|
IMAGE: "image/*",
|
||||||
|
VIDEO: "video/*",
|
||||||
|
AUDIO: "audio/*",
|
||||||
|
TEXT: "text/plain",
|
||||||
|
PDF: "application/pdf",
|
||||||
|
WORD: "application/msword",
|
||||||
|
EXCEL: "application/vnd.ms-excel",
|
||||||
|
PPT: "application/vnd.ms-powerpoint",
|
||||||
|
ZIP: "application/zip",
|
||||||
|
DEFAULT: "*/*"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为网络 URL
|
||||||
|
* @param url 地址
|
||||||
|
* @returns 是否为网络 URL
|
||||||
|
*/
|
||||||
|
function isNetworkUrl(url: string): boolean {
|
||||||
|
return url.startsWith("http://") || url.startsWith("https://");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件路径获取 File 对象
|
||||||
|
* 按优先级尝试多种路径解析方式
|
||||||
|
* @param filePath 文件路径
|
||||||
|
* @returns File 对象或 null
|
||||||
|
*/
|
||||||
|
function getFileFromPath(filePath: string): File | null {
|
||||||
|
// 1. 尝试直接路径
|
||||||
|
let file = new File(filePath);
|
||||||
|
if (file.exists()) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 尝试资源路径
|
||||||
|
file = new File(UTSAndroid.getResourcePath(filePath));
|
||||||
|
if (file.exists()) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 尝试绝对路径转换
|
||||||
|
file = new File(UTSAndroid.convert2AbsFullPath(filePath));
|
||||||
|
if (file.exists()) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件扩展名获取 MIME 类型
|
||||||
|
* @param filePath 文件路径
|
||||||
|
* @param defaultType 默认类型
|
||||||
|
* @returns MIME 类型字符串
|
||||||
|
*/
|
||||||
|
function getMimeTypeByPath(filePath: string, defaultType: string): string {
|
||||||
|
const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
|
||||||
|
|
||||||
|
if (ext == "") {
|
||||||
|
return defaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 常见文件类型映射
|
||||||
|
const mimeMap = {
|
||||||
|
// 文档类型
|
||||||
|
pdf: MimeTypes["PDF"],
|
||||||
|
doc: MimeTypes["WORD"],
|
||||||
|
docx: MimeTypes["WORD"],
|
||||||
|
xls: MimeTypes["EXCEL"],
|
||||||
|
xlsx: MimeTypes["EXCEL"],
|
||||||
|
ppt: MimeTypes["PPT"],
|
||||||
|
pptx: MimeTypes["PPT"],
|
||||||
|
// 压缩包类型
|
||||||
|
zip: MimeTypes["ZIP"],
|
||||||
|
rar: "application/x-rar-compressed",
|
||||||
|
"7z": "application/x-7z-compressed",
|
||||||
|
tar: "application/x-tar",
|
||||||
|
gz: "application/gzip"
|
||||||
|
};
|
||||||
|
|
||||||
|
return (mimeMap[ext] as string) ?? defaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载网络文件到本地缓存
|
||||||
|
* @param url 网络地址
|
||||||
|
* @param success 成功回调,返回本地文件路径
|
||||||
|
* @param fail 失败回调
|
||||||
|
*/
|
||||||
|
function downloadNetworkFile(
|
||||||
|
url: string,
|
||||||
|
success: (localPath: string) => void,
|
||||||
|
fail: (error: string) => void
|
||||||
|
): void {
|
||||||
|
uni.downloadFile({
|
||||||
|
url: url,
|
||||||
|
success: (res) => {
|
||||||
|
if (res.statusCode == 200) {
|
||||||
|
success(res.tempFilePath);
|
||||||
|
} else {
|
||||||
|
fail("下载失败,状态码: " + res.statusCode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
fail("下载失败: " + (err.errMsg ?? "未知错误"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文件 Uri
|
||||||
|
* @param filePath 文件路径(支持本地路径和网络 URL)
|
||||||
|
* @param success 成功回调
|
||||||
|
* @param fail 失败回调
|
||||||
|
*/
|
||||||
|
function createFileUriAsync(
|
||||||
|
filePath: string,
|
||||||
|
success: (uri: Uri) => void,
|
||||||
|
fail: (error: string) => void
|
||||||
|
): void {
|
||||||
|
// 创建文件Uri,支持网络和本地文件。网络文件先下载到本地缓存,再获取Uri。
|
||||||
|
const handleFileToUri = (localPath: string) => {
|
||||||
|
const file = getFileFromPath(localPath);
|
||||||
|
if (file == null) {
|
||||||
|
fail(`文件不存在: ${localPath}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const context = UTSAndroid.getAppContext();
|
||||||
|
if (context == null) {
|
||||||
|
fail("无法获取App Context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const authority = context.getPackageName() + ".fileprovider";
|
||||||
|
const uri = FileProvider.getUriForFile(context, authority, file);
|
||||||
|
success(uri);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isNetworkUrl(filePath)) {
|
||||||
|
// 网络路径需先下载,下载完成后处理
|
||||||
|
downloadNetworkFile(filePath, handleFileToUri, fail);
|
||||||
|
} else {
|
||||||
|
// 本地文件直接处理
|
||||||
|
handleFileToUri(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建图片分享 Intent(异步)
|
||||||
|
* @param imageUrl 图片路径(支持本地路径和网络 URL)
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param success 成功回调
|
||||||
|
* @param fail 失败回调
|
||||||
|
*/
|
||||||
|
function createImageShareIntent(
|
||||||
|
imageUrl: string,
|
||||||
|
title: string,
|
||||||
|
success: (intent: Intent) => void,
|
||||||
|
fail: (error: string) => void
|
||||||
|
): void {
|
||||||
|
if (imageUrl == "") {
|
||||||
|
fail("图片路径不能为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createFileUriAsync(
|
||||||
|
imageUrl,
|
||||||
|
(uri: Uri) => {
|
||||||
|
const intent = new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.setType(MimeTypes["IMAGE"] as string);
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||||
|
intent.putExtra(Intent.EXTRA_TITLE, title);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
success(intent);
|
||||||
|
},
|
||||||
|
(error: string) => {
|
||||||
|
fail(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建视频分享 Intent(异步)
|
||||||
|
* @param videoUrl 视频路径(支持本地路径和网络 URL)
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param success 成功回调
|
||||||
|
* @param fail 失败回调
|
||||||
|
*/
|
||||||
|
function createVideoShareIntent(
|
||||||
|
videoUrl: string,
|
||||||
|
title: string,
|
||||||
|
success: (intent: Intent) => void,
|
||||||
|
fail: (error: string) => void
|
||||||
|
): void {
|
||||||
|
if (videoUrl == "") {
|
||||||
|
fail("视频路径不能为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createFileUriAsync(
|
||||||
|
videoUrl,
|
||||||
|
(uri: Uri) => {
|
||||||
|
const intent = new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.setType(MimeTypes["VIDEO"] as string);
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||||
|
intent.putExtra(Intent.EXTRA_TITLE, title);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
success(intent);
|
||||||
|
},
|
||||||
|
(error: string) => {
|
||||||
|
fail(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建音频分享 Intent(异步)
|
||||||
|
* @param audioUrl 音频路径(支持本地路径和网络 URL)
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param success 成功回调
|
||||||
|
* @param fail 失败回调
|
||||||
|
*/
|
||||||
|
function createAudioShareIntent(
|
||||||
|
audioUrl: string,
|
||||||
|
title: string,
|
||||||
|
success: (intent: Intent) => void,
|
||||||
|
fail: (error: string) => void
|
||||||
|
): void {
|
||||||
|
if (audioUrl == "") {
|
||||||
|
fail("音频路径不能为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createFileUriAsync(
|
||||||
|
audioUrl,
|
||||||
|
(uri: Uri) => {
|
||||||
|
const intent = new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.setType(MimeTypes["AUDIO"] as string);
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||||
|
intent.putExtra(Intent.EXTRA_TITLE, title);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
success(intent);
|
||||||
|
},
|
||||||
|
(error: string) => {
|
||||||
|
fail(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文件分享 Intent(异步)
|
||||||
|
* @param filePath 文件路径(支持本地路径和网络 URL)
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param success 成功回调
|
||||||
|
* @param fail 失败回调
|
||||||
|
*/
|
||||||
|
function createFileShareIntent(
|
||||||
|
filePath: string,
|
||||||
|
title: string,
|
||||||
|
success: (intent: Intent) => void,
|
||||||
|
fail: (error: string) => void
|
||||||
|
): void {
|
||||||
|
if (filePath == "") {
|
||||||
|
fail("文件路径不能为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createFileUriAsync(
|
||||||
|
filePath,
|
||||||
|
(uri: Uri) => {
|
||||||
|
// 根据文件扩展名确定 MIME 类型
|
||||||
|
const mimeType = getMimeTypeByPath(filePath, MimeTypes["DEFAULT"] as string);
|
||||||
|
|
||||||
|
const intent = new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.setType(mimeType);
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||||
|
intent.putExtra(Intent.EXTRA_TITLE, title);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
success(intent);
|
||||||
|
},
|
||||||
|
(error: string) => {
|
||||||
|
fail(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建链接分享 Intent
|
||||||
|
* @param href 链接地址
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param summary 分享描述
|
||||||
|
* @param success 成功回调
|
||||||
|
* @param fail 失败回调
|
||||||
|
*/
|
||||||
|
function createLinkShareIntent(
|
||||||
|
href: string,
|
||||||
|
title: string,
|
||||||
|
summary: string,
|
||||||
|
success: (intent: Intent) => void,
|
||||||
|
fail: (error: string) => void
|
||||||
|
): void {
|
||||||
|
if (href == "") {
|
||||||
|
fail("链接地址不能为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组合分享内容:标题 + 描述 + 链接
|
||||||
|
let content = "";
|
||||||
|
if (title != "") {
|
||||||
|
content = title;
|
||||||
|
}
|
||||||
|
if (summary != "") {
|
||||||
|
content = content == "" ? summary : content + "\n" + summary;
|
||||||
|
}
|
||||||
|
if (href != "") {
|
||||||
|
content = content == "" ? href : content + "\n" + href;
|
||||||
|
}
|
||||||
|
|
||||||
|
const intent = new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.setType(MimeTypes["TEXT"] as string);
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT, content);
|
||||||
|
|
||||||
|
success(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文本分享 Intent
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param summary 分享描述
|
||||||
|
* @param href 附加链接(可选)
|
||||||
|
* @param success 成功回调
|
||||||
|
*/
|
||||||
|
function createTextShareIntent(
|
||||||
|
title: string,
|
||||||
|
summary: string,
|
||||||
|
href: string,
|
||||||
|
success: (intent: Intent) => void
|
||||||
|
): void {
|
||||||
|
// 组合分享内容
|
||||||
|
let content = "";
|
||||||
|
if (title != "") {
|
||||||
|
content = title;
|
||||||
|
}
|
||||||
|
if (summary != "") {
|
||||||
|
content = content == "" ? summary : content + "\n" + summary;
|
||||||
|
}
|
||||||
|
if (href != "") {
|
||||||
|
content = content == "" ? href : content + "\n" + href;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果内容为空,使用默认文本
|
||||||
|
if (content == "") {
|
||||||
|
content = "分享内容";
|
||||||
|
}
|
||||||
|
|
||||||
|
const intent = new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.setType(MimeTypes["TEXT"] as string);
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT, content);
|
||||||
|
|
||||||
|
success(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动分享 Activity
|
||||||
|
* @param intent 分享 Intent
|
||||||
|
* @param title 选择器标题
|
||||||
|
* @param success 成功回调
|
||||||
|
* @param fail 失败回调
|
||||||
|
*/
|
||||||
|
function startShareActivity(
|
||||||
|
intent: Intent,
|
||||||
|
title: string,
|
||||||
|
success: () => void,
|
||||||
|
fail: (error: string) => void
|
||||||
|
): void {
|
||||||
|
const chooserTitle = title != "" ? title : "选择分享方式";
|
||||||
|
const chooser = Intent.createChooser(intent, chooserTitle);
|
||||||
|
|
||||||
|
try {
|
||||||
|
UTSAndroid.getUniActivity()!.startActivity(chooser);
|
||||||
|
success();
|
||||||
|
} catch (e: Exception) {
|
||||||
|
const errorMsg = e.message ?? "分享失败";
|
||||||
|
fail(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统分享功能
|
||||||
|
* @param options 分享参数
|
||||||
|
* @param options.type 分享类型: text(文本) | image(图片) | video(视频) | audio(音频) | file(文件) | link(链接)
|
||||||
|
* @param options.title 分享标题
|
||||||
|
* @param options.summary 分享描述/内容
|
||||||
|
* @param options.href 链接地址或文件路径
|
||||||
|
* @param options.imageUrl 图片/视频/音频路径(支持本地路径和网络 URL)
|
||||||
|
* @param options.success 成功回调
|
||||||
|
* @param options.fail 失败回调
|
||||||
|
*/
|
||||||
|
export function shareWithSystem(options: ShareWithSystemOptions): void {
|
||||||
|
const type = options.type;
|
||||||
|
const title = options.title ?? "";
|
||||||
|
const summary = options.summary ?? "";
|
||||||
|
const href = options.href ?? "";
|
||||||
|
const imageUrl = options.imageUrl ?? "";
|
||||||
|
|
||||||
|
// 成功和失败回调
|
||||||
|
const onSuccess = (intent: Intent) => {
|
||||||
|
startShareActivity(
|
||||||
|
intent,
|
||||||
|
title,
|
||||||
|
() => {
|
||||||
|
options.success?.();
|
||||||
|
},
|
||||||
|
(error: string) => {
|
||||||
|
options.fail?.(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error: string) => {
|
||||||
|
options.fail?.(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据分享类型创建对应的 Intent
|
||||||
|
if (type == ShareType["IMAGE"]) {
|
||||||
|
createImageShareIntent(imageUrl, title, onSuccess, onFail);
|
||||||
|
} else if (type == ShareType["VIDEO"]) {
|
||||||
|
createVideoShareIntent(imageUrl, title, onSuccess, onFail);
|
||||||
|
} else if (type == ShareType["AUDIO"]) {
|
||||||
|
createAudioShareIntent(imageUrl, title, onSuccess, onFail);
|
||||||
|
} else if (type == ShareType["FILE"]) {
|
||||||
|
createFileShareIntent(href, title, onSuccess, onFail);
|
||||||
|
} else if (type == ShareType["LINK"]) {
|
||||||
|
createLinkShareIntent(href, title, summary, onSuccess, onFail);
|
||||||
|
} else {
|
||||||
|
// 默认为文本分享
|
||||||
|
createTextShareIntent(title, summary, href, onSuccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<!-- 外部存储路径 -->
|
||||||
|
<external-path name="external_files" path="." />
|
||||||
|
|
||||||
|
<!-- 外部缓存路径 -->
|
||||||
|
<external-cache-path name="external_cache" path="." />
|
||||||
|
|
||||||
|
<!-- 应用缓存路径(用于 uni.downloadFile 下载的临时文件) -->
|
||||||
|
<cache-path name="cache" path="." />
|
||||||
|
|
||||||
|
<!-- 应用内部文件路径 -->
|
||||||
|
<files-path name="files" path="." />
|
||||||
|
|
||||||
|
<!-- 根路径(谨慎使用) -->
|
||||||
|
<root-path name="root" path="." />
|
||||||
|
</paths>
|
||||||
14
uni_modules/cool-share/utssdk/app-harmony/index.uts
Normal file
14
uni_modules/cool-share/utssdk/app-harmony/index.uts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { ShareWithSystemOptions } from "../interface.uts";
|
||||||
|
import { share } from "./share.ets";
|
||||||
|
|
||||||
|
export function shareWithSystem(options: ShareWithSystemOptions) {
|
||||||
|
share(
|
||||||
|
options.type,
|
||||||
|
options.title ?? "",
|
||||||
|
options.summary ?? "",
|
||||||
|
options.href ?? "",
|
||||||
|
options.imageUrl ?? "",
|
||||||
|
options.success ?? (() => {}),
|
||||||
|
options.fail ?? (() => {})
|
||||||
|
);
|
||||||
|
}
|
||||||
265
uni_modules/cool-share/utssdk/app-harmony/share.ets
Normal file
265
uni_modules/cool-share/utssdk/app-harmony/share.ets
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
import { UTSHarmony } from '@dcloudio/uni-app-x-runtime';
|
||||||
|
import { systemShare } from '@kit.ShareKit';
|
||||||
|
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
|
||||||
|
import { common } from '@kit.AbilityKit';
|
||||||
|
import { fileUri } from '@kit.CoreFileKit';
|
||||||
|
import { BusinessError } from '@kit.BasicServicesKit';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分享类型枚举
|
||||||
|
*/
|
||||||
|
enum ShareType {
|
||||||
|
TEXT = "text", // 纯文本分享
|
||||||
|
IMAGE = "image", // 图片分享
|
||||||
|
VIDEO = "video", // 视频分享
|
||||||
|
AUDIO = "audio", // 音频分享
|
||||||
|
FILE = "file", // 文件分享
|
||||||
|
LINK = "link" // 链接分享
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件路径获取统一数据类型标识符
|
||||||
|
* @param filePath 文件路径
|
||||||
|
* @param defaultType 默认数据类型
|
||||||
|
* @returns 统一数据类型标识符
|
||||||
|
*/
|
||||||
|
function getUtdTypeByPath(filePath: string, defaultType: string): string {
|
||||||
|
const ext = filePath?.split('.')?.pop()?.toLowerCase() ?? '';
|
||||||
|
if (ext === '') {
|
||||||
|
return defaultType;
|
||||||
|
}
|
||||||
|
return utd.getUniformDataTypeByFilenameExtension('.' + ext, defaultType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建图片分享数据
|
||||||
|
* @param imageUrl 图片路径(支持本地路径和网络 URL)
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param summary 分享描述
|
||||||
|
* @returns 分享数据对象
|
||||||
|
*/
|
||||||
|
function createImageShareData(imageUrl: string, title: string, summary: string): systemShare.SharedData | null {
|
||||||
|
if (imageUrl === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = UTSHarmony.getResourcePath(imageUrl);
|
||||||
|
const utdTypeId = getUtdTypeByPath(filePath, utd.UniformDataType.IMAGE);
|
||||||
|
|
||||||
|
return new systemShare.SharedData({
|
||||||
|
utd: utdTypeId,
|
||||||
|
uri: fileUri.getUriFromPath(filePath),
|
||||||
|
title: title,
|
||||||
|
description: summary,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建视频分享数据
|
||||||
|
* @param videoUrl 视频路径(支持本地路径和网络 URL)
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param summary 分享描述
|
||||||
|
* @returns 分享数据对象
|
||||||
|
*/
|
||||||
|
function createVideoShareData(videoUrl: string, title: string, summary: string): systemShare.SharedData | null {
|
||||||
|
if (videoUrl === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = UTSHarmony.getResourcePath(videoUrl);
|
||||||
|
const utdTypeId = getUtdTypeByPath(filePath, utd.UniformDataType.VIDEO);
|
||||||
|
|
||||||
|
return new systemShare.SharedData({
|
||||||
|
utd: utdTypeId,
|
||||||
|
uri: fileUri.getUriFromPath(filePath),
|
||||||
|
title: title,
|
||||||
|
description: summary,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建音频分享数据
|
||||||
|
* @param audioUrl 音频路径(支持本地路径和网络 URL)
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param summary 分享描述
|
||||||
|
* @returns 分享数据对象
|
||||||
|
*/
|
||||||
|
function createAudioShareData(audioUrl: string, title: string, summary: string): systemShare.SharedData | null {
|
||||||
|
if (audioUrl === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = UTSHarmony.getResourcePath(audioUrl);
|
||||||
|
const utdTypeId = getUtdTypeByPath(filePath, utd.UniformDataType.AUDIO);
|
||||||
|
|
||||||
|
return new systemShare.SharedData({
|
||||||
|
utd: utdTypeId,
|
||||||
|
uri: fileUri.getUriFromPath(filePath),
|
||||||
|
title: title,
|
||||||
|
description: summary,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文件分享数据
|
||||||
|
* @param filePath 文件路径(支持本地路径和网络 URL)
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param summary 分享描述
|
||||||
|
* @returns 分享数据对象
|
||||||
|
*/
|
||||||
|
function createFileShareData(filePath: string, title: string, summary: string): systemShare.SharedData | null {
|
||||||
|
if (filePath === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourcePath = UTSHarmony.getResourcePath(filePath);
|
||||||
|
const ext = resourcePath?.split('.')?.pop()?.toLowerCase() ?? '';
|
||||||
|
|
||||||
|
// 根据文件扩展名确定数据类型
|
||||||
|
let utdType = utd.UniformDataType.FILE;
|
||||||
|
let utdTypeId = '';
|
||||||
|
|
||||||
|
// 支持常见的文件类型
|
||||||
|
switch (ext) {
|
||||||
|
case 'zip':
|
||||||
|
case 'rar':
|
||||||
|
case '7z':
|
||||||
|
case 'tar':
|
||||||
|
case 'gz':
|
||||||
|
utdType = utd.UniformDataType.ARCHIVE;
|
||||||
|
break;
|
||||||
|
case 'pdf':
|
||||||
|
utdType = utd.UniformDataType.PDF;
|
||||||
|
break;
|
||||||
|
case 'doc':
|
||||||
|
case 'docx':
|
||||||
|
utdType = utd.UniformDataType.WORD_DOC;
|
||||||
|
break;
|
||||||
|
case 'xls':
|
||||||
|
case 'xlsx':
|
||||||
|
utdType = utd.UniformDataType.EXCEL;
|
||||||
|
break;
|
||||||
|
case 'ppt':
|
||||||
|
case 'pptx':
|
||||||
|
utdType = utd.UniformDataType.PPT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
utdType = utd.UniformDataType.FILE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
utdTypeId = utd.getUniformDataTypeByFilenameExtension('.' + ext, utdType);
|
||||||
|
|
||||||
|
return new systemShare.SharedData({
|
||||||
|
utd: utdTypeId,
|
||||||
|
uri: fileUri.getUriFromPath(resourcePath),
|
||||||
|
title: title,
|
||||||
|
description: summary,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建链接分享数据
|
||||||
|
* @param href 链接地址
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param summary 分享描述
|
||||||
|
* @returns 分享数据对象
|
||||||
|
*/
|
||||||
|
function createLinkShareData(href: string, title: string, summary: string): systemShare.SharedData {
|
||||||
|
return new systemShare.SharedData({
|
||||||
|
utd: utd.UniformDataType.HYPERLINK,
|
||||||
|
title: title,
|
||||||
|
content: href,
|
||||||
|
description: summary
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文本分享数据
|
||||||
|
* @param title 分享标题
|
||||||
|
* @param summary 分享内容
|
||||||
|
* @returns 分享数据对象
|
||||||
|
*/
|
||||||
|
function createTextShareData(title: string, summary: string): systemShare.SharedData {
|
||||||
|
return new systemShare.SharedData({
|
||||||
|
utd: utd.UniformDataType.TEXT,
|
||||||
|
title: title,
|
||||||
|
content: summary
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统分享功能
|
||||||
|
* @param options 分享参数
|
||||||
|
* @param options.type 分享类型: text(文本) | image(图片) | video(视频) | audio(音频) | file(文件) | link(链接)
|
||||||
|
* @param options.title 分享标题
|
||||||
|
* @param options.summary 分享描述/内容
|
||||||
|
* @param options.href 链接地址或文件路径
|
||||||
|
* @param options.imageUrl 图片/视频/音频路径(支持本地路径和网络 URL)
|
||||||
|
* @param options.success 成功回调
|
||||||
|
* @param options.fail 失败回调
|
||||||
|
*/
|
||||||
|
export function share(type: string, title: string, summary: string, href: string, imageUrl: string, success: () => void, fail: (error: string) => void): void {
|
||||||
|
// 获取UI上下文
|
||||||
|
const uiContext: UIContext = UTSHarmony.getCurrentWindow()?.getUIContext();
|
||||||
|
const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext;
|
||||||
|
|
||||||
|
// 根据分享类型创建分享数据
|
||||||
|
let shareData: systemShare.SharedData | null = null;
|
||||||
|
let errorMsg = '';
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case ShareType.IMAGE:
|
||||||
|
shareData = createImageShareData(imageUrl, title, summary);
|
||||||
|
errorMsg = '图片路径不能为空';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ShareType.VIDEO:
|
||||||
|
shareData = createVideoShareData(imageUrl, title, summary);
|
||||||
|
errorMsg = '视频路径不能为空';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ShareType.AUDIO:
|
||||||
|
shareData = createAudioShareData(imageUrl, title, summary);
|
||||||
|
errorMsg = '音频路径不能为空';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ShareType.FILE:
|
||||||
|
shareData = createFileShareData(href, title, summary);
|
||||||
|
errorMsg = '文件路径不能为空';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ShareType.LINK:
|
||||||
|
shareData = createLinkShareData(href, title, summary);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// 默认为文本分享
|
||||||
|
shareData = createTextShareData(title, summary);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证分享数据
|
||||||
|
if (shareData === null) {
|
||||||
|
fail(errorMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建分享控制器
|
||||||
|
const controller: systemShare.ShareController = new systemShare.ShareController(shareData);
|
||||||
|
|
||||||
|
// 显示分享面板,配置分享选项
|
||||||
|
controller.show(context, {
|
||||||
|
selectionMode: systemShare.SelectionMode.SINGLE, // 单选模式
|
||||||
|
previewMode: systemShare.SharePreviewMode.DEFAULT, // 默认预览模式
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
// 分享成功
|
||||||
|
success();
|
||||||
|
})
|
||||||
|
.catch((error: BusinessError) => {
|
||||||
|
// 分享失败,返回错误信息
|
||||||
|
const errorMessage = error?.message ?? '分享失败';
|
||||||
|
fail(errorMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
9
uni_modules/cool-share/utssdk/interface.uts
Normal file
9
uni_modules/cool-share/utssdk/interface.uts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export type ShareWithSystemOptions = {
|
||||||
|
type: string;
|
||||||
|
title?: string;
|
||||||
|
summary?: string;
|
||||||
|
href?: string;
|
||||||
|
imageUrl?: string;
|
||||||
|
success?: () => void;
|
||||||
|
fail?: (error: string) => void;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user