This commit is contained in:
owenchen committed 2026-10-22 14:54:36 +08:00
1 parent 6710b429b0
commit 15d8eb3f4e
6 files changed
+39 -1

No files matched your search

@@ -3,7 +3,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<_PublishTargetUrl>C:\inetpub\wwwroot\dockwebapi2</_PublishTargetUrl> <_PublishTargetUrl>C:\inetpub\wwwroot\dockwebapi2</_PublishTargetUrl>
<History>True|2026-10-21T13:22:01.1456473Z||;True|2026-10-20T15:45:39.3393674+08:00||;True|2026-10-17T20:49:21.0401213+08:00||;True|2026-09-23T13:19:13.0148919+08:00||;True|2026-09-23T13:16:07.8584304+08:00||;True|2026-09-22T23:03:13.6509491+08:00||;True|2026-09-22T16:07:15.9177123+08:00||;True|2026-09-22T11:19:19.6087109+08:00||;True|2026-09-22T11:09:24.9165065+08:00||;True|2026-09-21T22:40:07.1232044+08:00||;True|2026-09-21T22:35:06.9446571+08:00||;True|2026-09-21T22:27:42.1146825+08:00||;False|2026-09-21T22:27:17.6066573+08:00||;True|2026-09-21T21:01:22.8888913+08:00||;True|2026-09-21T19:15:03.4753747+08:00||;True|2026-09-21T18:08:30.0866986+08:00||;True|2026-09-21T16:51:19.8137872+08:00||;True|2026-09-21T16:30:01.0950896+08:00||;True|2026-09-21T15:09:00.2326737+08:00||;True|2026-09-21T14:47:09.6120256+08:00||;True|2026-09-21T14:16:35.3194409+08:00||;True|2026-09-21T13:54:58.2829712+08:00||;True|2026-09-21T13:36:45.3134499+08:00||;True|2026-09-19T09:48:52.0085130+08:00||;False|2026-09-19T09:47:56.1658214+08:00||;True|2026-09-17T18:50:15.9493380+08:00||;True|2026-09-17T18:11:11.5364547+08:00||;True|2026-09-17T18:07:27.7830758+08:00||;True|2026-09-17T17:58:16.5798560+08:00||;True|2026-09-17T15:37:30.9025614+08:00||;True|2026-09-17T15:25:46.9116292+08:00||;True|2026-09-17T15:05:18.6592403+08:00||;True|2026-09-17T14:57:28.7997437+08:00||;True|2026-09-17T14:36:00.6339386+08:00||;True|2026-09-17T13:56:43.2376873+08:00||;True|2026-09-16T13:56:51.8724546+08:00||;True|2026-09-15T20:44:46.6559899+08:00||;True|2026-09-13T19:02:59.5654245+08:00||;True|2026-09-10T09:14:56.2914193+08:00||;True|2026-09-09T16:40:16.6461154+08:00||;True|2026-09-08T13:55:23.1502435+08:00||;True|2026-09-08T08:04:53.4279263+08:00||;True|2026-09-07T08:48:17.4682304+08:00||;True|2026-09-04T14:39:08.7878670+08:00||;True|2026-09-04T14:35:48.2937877+08:00||;True|2026-09-04T11:45:16.1372876+08:00||;True|2026-09-04T11:42:59.9356436+08:00||;True|2026-09-03T16:05:52.5270232+08:00||;True|2026-09-03T14:52:56.8559144+08:00||;True|2026-09-02T11:08:23.8720038+08:00||;True|2026-09-02T10:58:16.8081797+08:00||;True|2026-08-26T13:34:12.3805892+08:00||;True|2026-08-25T08:31:30.7787234+08:00||;True|2026-08-20T13:10:46.4725468+08:00||;True|2026-08-20T13:10:28.3142576+08:00||;True|2026-08-19T16:10:27.3362887+08:00||;True|2026-08-19T16:01:12.6234971+08:00||;True|2026-08-19T15:42:46.6576265+08:00||;True|2026-08-19T13:39:59.9363522+08:00||;True|2026-08-19T13:36:53.0379313+08:00||;True|2026-08-19T13:31:36.0841398+08:00||;True|2026-08-19T11:44:37.5319626+08:00||;True|2026-08-19T09:36:45.6000047+08:00||;True|2026-08-19T09:34:36.8468631+08:00||;True|2026-08-19T08:35:41.2202300+08:00||;True|2026-08-18T16:20:59.0170916+08:00||;</History> <History>True|2026-10-22T06:27:02.4892588Z||;True|2026-10-21T21:22:01.1456473+08:00||;True|2026-10-20T15:45:39.3393674+08:00||;True|2026-10-17T20:49:21.0401213+08:00||;True|2026-09-23T13:19:13.0148919+08:00||;True|2026-09-23T13:16:07.8584304+08:00||;True|2026-09-22T23:03:13.6509491+08:00||;True|2026-09-22T16:07:15.9177123+08:00||;True|2026-09-22T11:19:19.6087109+08:00||;True|2026-09-22T11:09:24.9165065+08:00||;True|2026-09-21T22:40:07.1232044+08:00||;True|2026-09-21T22:35:06.9446571+08:00||;True|2026-09-21T22:27:42.1146825+08:00||;False|2026-09-21T22:27:17.6066573+08:00||;True|2026-09-21T21:01:22.8888913+08:00||;True|2026-09-21T19:15:03.4753747+08:00||;True|2026-09-21T18:08:30.0866986+08:00||;True|2026-09-21T16:51:19.8137872+08:00||;True|2026-09-21T16:30:01.0950896+08:00||;True|2026-09-21T15:09:00.2326737+08:00||;True|2026-09-21T14:47:09.6120256+08:00||;True|2026-09-21T14:16:35.3194409+08:00||;True|2026-09-21T13:54:58.2829712+08:00||;True|2026-09-21T13:36:45.3134499+08:00||;True|2026-09-19T09:48:52.0085130+08:00||;False|2026-09-19T09:47:56.1658214+08:00||;True|2026-09-17T18:50:15.9493380+08:00||;True|2026-09-17T18:11:11.5364547+08:00||;True|2026-09-17T18:07:27.7830758+08:00||;True|2026-09-17T17:58:16.5798560+08:00||;True|2026-09-17T15:37:30.9025614+08:00||;True|2026-09-17T15:25:46.9116292+08:00||;True|2026-09-17T15:05:18.6592403+08:00||;True|2026-09-17T14:57:28.7997437+08:00||;True|2026-09-17T14:36:00.6339386+08:00||;True|2026-09-17T13:56:43.2376873+08:00||;True|2026-09-16T13:56:51.8724546+08:00||;True|2026-09-15T20:44:46.6559899+08:00||;True|2026-09-13T19:02:59.5654245+08:00||;True|2026-09-10T09:14:56.2914193+08:00||;True|2026-09-09T16:40:16.6461154+08:00||;True|2026-09-08T13:55:23.1502435+08:00||;True|2026-09-08T08:04:53.4279263+08:00||;True|2026-09-07T08:48:17.4682304+08:00||;True|2026-09-04T14:39:08.7878670+08:00||;True|2026-09-04T14:35:48.2937877+08:00||;True|2026-09-04T11:45:16.1372876+08:00||;True|2026-09-04T11:42:59.9356436+08:00||;True|2026-09-03T16:05:52.5270232+08:00||;True|2026-09-03T14:52:56.8559144+08:00||;True|2026-09-02T11:08:23.8720038+08:00||;True|2026-09-02T10:58:16.8081797+08:00||;True|2026-08-26T13:34:12.3805892+08:00||;True|2026-08-25T08:31:30.7787234+08:00||;True|2026-08-20T13:10:46.4725468+08:00||;True|2026-08-20T13:10:28.3142576+08:00||;True|2026-08-19T16:10:27.3362887+08:00||;True|2026-08-19T16:01:12.6234971+08:00||;True|2026-08-19T15:42:46.6576265+08:00||;True|2026-08-19T13:39:59.9363522+08:00||;True|2026-08-19T13:36:53.0379313+08:00||;True|2026-08-19T13:31:36.0841398+08:00||;True|2026-08-19T11:44:37.5319626+08:00||;True|2026-08-19T09:36:45.6000047+08:00||;True|2026-08-19T09:34:36.8468631+08:00||;True|2026-08-19T08:35:41.2202300+08:00||;True|2026-08-18T16:20:59.0170916+08:00||;</History>
<LastFailureDetails /> <LastFailureDetails />
</PropertyGroup> </PropertyGroup>
</Project> </Project>
@@ -42,6 +42,7 @@ import { pageUrl } from "@/router/routes";
import { chooseFiles } from "@/utils/chooseFiles"; import { chooseFiles } from "@/utils/chooseFiles";
import { saveFileBytes } from "@/utils/dmsBytes"; import { saveFileBytes } from "@/utils/dmsBytes";
import { absoluteFileUrl, backupFileUrl } from "@/utils/fileUrl"; import { absoluteFileUrl, backupFileUrl } from "@/utils/fileUrl";
import { isWeixinBrowser } from "@/utils/weixin";
/** ready:组件挂载完成通知(时序口径见文件底部 onMounted 注释) */ /** ready:组件挂载完成通知(时序口径见文件底部 onMounted 注释) */
const emit = defineEmits<{ (e: "ready"): void }>(); const emit = defineEmits<{ (e: "ready"): void }>();
@@ -151,6 +152,16 @@ const downloadGlyph = `data:image/svg+xml,${encodeURIComponent(downloadSvg)}`;
/** H5 下载 App 安装包:复用网盘 file 页同一条下载链——requestBuffer 按当前线路取字节 /** H5 下载 App 安装包:复用网盘 file 页同一条下载链——requestBuffer 按当前线路取字节
* (后端报错回的是 JSON,按 content-type 转成错误提示,不会跳错误页),saveFileBytes 走 blob <a download> 落盘 */ * (后端报错回的是 JSON,按 content-type 转成错误提示,不会跳错误页),saveFileBytes 走 blob <a download> 落盘 */
async function onDownloadApp(): Promise<void> { async function onDownloadApp(): Promise<void> {
// 微信内置浏览器屏蔽 <a download> 且 apk 在微信下载封禁名单里(点击静默无反应),
// 只能引导用户到系统浏览器下载
if (isWeixinBrowser()) {
uni.showModal({
title: t("storage.downloadApp"),
content: t("storage.openInBrowserTip"),
showCancel: false,
});
return;
}
uni.showLoading({ title: t("storage.downloadingApp"), mask: true }); uni.showLoading({ title: t("storage.downloadingApp"), mask: true });
try { try {
const bytes = await requestBuffer({ url: "/FileServer/youjiala.apk", method: "GET" }); const bytes = await requestBuffer({ url: "/FileServer/youjiala.apk", method: "GET" });
@@ -13,6 +13,7 @@
"avatarUploadFailed": "Avatar upload failed", "avatarUploadFailed": "Avatar upload failed",
"downloadApp": "Download App", "downloadApp": "Download App",
"downloadingApp": "Downloading…", "downloadingApp": "Downloading…",
"openInBrowserTip": "Downloads are blocked inside WeChat. Please tap \"···\" at the top right, choose \"Open in browser\", then tap download again.",
"downloadStarted": "Downloading youjiala.apk…" "downloadStarted": "Downloading youjiala.apk…"
}, },
"article": { "article": {
@@ -13,6 +13,7 @@
"avatarUploadFailed": "头像上传失败", "avatarUploadFailed": "头像上传失败",
"downloadApp": "下载 App", "downloadApp": "下载 App",
"downloadingApp": "正在下载…", "downloadingApp": "正在下载…",
"openInBrowserTip": "微信内无法直接下载文件,请点击右上角「···」,选择「在浏览器打开」后再点击下载",
"downloadStarted": "开始下载 youjiala.apk…" "downloadStarted": "开始下载 youjiala.apk…"
}, },
"article": { "article": {
+10
View File
@@ -40,6 +40,7 @@ import { fetchFileBytes, saveFileBytes, toImageUrl, toPlayableUrl } from "@/util
import { absoluteFileUrl } from "@/utils/fileUrl"; import { absoluteFileUrl } from "@/utils/fileUrl";
import { clearPlayback, setPlayback } from "@/utils/playbackBus"; import { clearPlayback, setPlayback } from "@/utils/playbackBus";
import { transferGlyph } from "@/utils/transferGlyph"; import { transferGlyph } from "@/utils/transferGlyph";
import { isWeixinBrowser } from "@/utils/weixin";
const { t } = useLocale(); const { t } = useLocale();
@@ -584,6 +585,15 @@ async function actionDownload(targets: FileItem[]): Promise<void> {
toast(t("FilePage.downloadNoFile")); toast(t("FilePage.downloadNoFile"));
return; return;
} }
// 微信内置浏览器屏蔽 blob/<a download>(点击静默无反应),只能引导转系统浏览器下载
if (isWeixinBrowser()) {
uni.showModal({
title: t("FilePage.actionDownload"),
content: t("storage.openInBrowserTip"),
showCancel: false,
});
return;
}
await withBusy(async () => { await withBusy(async () => {
for (const file of picked) { for (const file of picked) {
const record = recordOf(file); const record = recordOf(file);
+15
View File
@@ -0,0 +1,15 @@
/**
* 微信内置浏览器检测(iOS WKWebView / 安卓 XWeb 的 UA 都带 MicroMessenger 标记):
* 微信屏蔽 <a download> 与 blob 落盘(点击静默无反应、无任何报错),apk 更在
* 微信下载封禁名单里,客户端没有绕过手段——H5 的下载入口命中微信时必须弹窗
* 引导用户「右上角··· → 在浏览器打开」后回系统浏览器下载。
* 非 H5 端(App/小程序)不存在微信网页环境,恒为 false。
*/
export function isWeixinBrowser(): boolean {
// #ifdef H5
return /MicroMessenger/i.test(navigator.userAgent);
// #endif
// #ifndef H5
return false;
// #endif
}