diff --git a/CHANGELOG.md b/CHANGELOG.md index f40bb5f260ba8417c3f2e0954ed4cd4f540aad72..3c7409ea624683b79fbba8b98608457f5a0d8734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ ## [Unreleased] +### Added + +- 新增download下载页面,用于安卓微信端下载文件 + ## [0.7.41-alpha.16] - 2025-09-23 ### Change diff --git a/src/ibiz-vue3.ts b/src/ibiz-vue3.ts index e0434e5d06c00c47209a8449bd219aae62482a2c..f5d7aa81a88e982045bf1aca688d8ec42f539c64 100644 --- a/src/ibiz-vue3.ts +++ b/src/ibiz-vue3.ts @@ -37,6 +37,7 @@ import { VueBrowserPlatformProvider, DingTalkPlatformProvider, IosPlatformProvider, + WeChatOfficialPlatformProvider, } from './platform'; import { IBizPortalView } from './view/portal-view'; import { IBizViewEngine } from './view-engine'; @@ -50,6 +51,7 @@ export default { const browserPlatformProvider = new VueBrowserPlatformProvider(); const dingTalkPlatformProvider = new DingTalkPlatformProvider(); const iosPlatformProvider = new IosPlatformProvider(); + const weChatOfficialPlatformProvider = new WeChatOfficialPlatformProvider(); registerPlatformProvider( PlatformType.BROWSER, () => browserPlatformProvider, @@ -59,6 +61,10 @@ export default { () => dingTalkPlatformProvider, ); registerPlatformProvider(PlatformType.IOS, () => iosPlatformProvider); + registerPlatformProvider( + PlatformType.WECHAT, + () => weChatOfficialPlatformProvider, + ); v.use(IBizCommonComponents); v.use(IBizViewEngine); diff --git a/src/locale/en/index.ts b/src/locale/en/index.ts index 2f0593cb36fba959e4b3c1c0c6e311c7de724455..356bc72540f21906a4d73027dd5733cfe2334117 100644 --- a/src/locale/en/index.ts +++ b/src/locale/en/index.ts @@ -327,6 +327,13 @@ export default { password: 'Password', login: 'Login', thirdAuthFail: 'Third party login authorization failed', + downloading: 'Download now...', + downloadSuccess: 'Download successful!', + downloadFailed: 'Download failed!', + noSupportDownload: + 'This file is not supported for download. Please click the upper right corner to open and download it with your browser!', + immediatelyDownload: 'Download now', + reDownload: 'Download again', }, // 视图引擎 viewEngine: { diff --git a/src/locale/zh-CN/index.ts b/src/locale/zh-CN/index.ts index 9fb6a29e38f445723cd1314444e48e51ac2df9fe..a2f1bd1b0ff09001f3d3a93536f73e40902147d2 100644 --- a/src/locale/zh-CN/index.ts +++ b/src/locale/zh-CN/index.ts @@ -314,6 +314,12 @@ export default { password: '密码', login: '登录', thirdAuthFail: '第三方授权登录失败', + downloading: '下载中...', + downloadSuccess: '下载成功!', + downloadFailed: '下载失败!', + noSupportDownload: '不支持下载该文件,请点击右上角使用浏览器打开下载!', + immediatelyDownload: '立即下载', + reDownload: '重新下载', }, // 视图引擎 viewEngine: { diff --git a/src/mob-app/router/index.ts b/src/mob-app/router/index.ts index 75427d6536a6b516d2e509bd9bc397ec69937977..be89d642c44f4cb9a952f6b461274aff7cf64c07 100644 --- a/src/mob-app/router/index.ts +++ b/src/mob-app/router/index.ts @@ -11,7 +11,7 @@ import { AppRedirectView } from '@ibiz-template/vue3-util'; import qs from 'qs'; import { AuthGuard } from '../guard'; import { RouterShell, HomeView, ModalRouterShell } from '../components'; -import { LoginView, View404 } from '../../view'; +import { DownloadView, LoginView, View404 } from '../../view'; import { useViewStack } from '../../util'; const getPropsCallback = (depth: number) => { @@ -167,6 +167,12 @@ export class AppRouter { }, component: LoginView, }, + { + path: '/download', + name: 'downloadView', + meta: { preset: true }, + component: DownloadView, + }, { path: '/404', name: '404View1', diff --git a/src/platform/index.ts b/src/platform/index.ts index ab3701ae38ef7c35cbe3c87732a46a2fda61c440..dc9bdfaf6a200aca6940705cbdb4ad08a2f36bab 100644 --- a/src/platform/index.ts +++ b/src/platform/index.ts @@ -1,3 +1,4 @@ export { VueBrowserPlatformProvider } from './vue-browser-platform-provider'; export { DingTalkPlatformProvider } from './ding-talk-platform-provider'; export { IosPlatformProvider } from './ios-platform-provider'; +export { WeChatOfficialPlatformProvider } from './wechat-official-platform-provider'; diff --git a/src/platform/wechat-official-platform-provider.ts b/src/platform/wechat-official-platform-provider.ts new file mode 100644 index 0000000000000000000000000000000000000000..2acce2110cd9b69cc7e81d924bff2625cc17baeb --- /dev/null +++ b/src/platform/wechat-official-platform-provider.ts @@ -0,0 +1,31 @@ +import { getToken, UrlHelper } from '@ibiz-template/core'; +import { isAndroid, PlatformProviderBase } from '@ibiz-template/runtime'; + +/** + * @description 微信公众号搭载平台适配器 + * @export + * @class WeChatOfficialPlatformProvider + * @extends {BrowserPlatformProvider} + */ +export class WeChatOfficialPlatformProvider extends PlatformProviderBase { + /** + * @description 下载文件 + * @param {string} url + * @param {string} name + * @return {*} + * @memberof WeChatOfficialPlatformProvider + */ + async download(url: string, name: string): Promise { + // 安卓环境下微信浏览器不支持直接下载,需跳转到默认浏览器中下载 + if (isAndroid()) { + const search = new URLSearchParams({ + fileurl: encodeURIComponent(url), + filename: encodeURIComponent(name), + token: getToken() || '', + }); + window.open(`${UrlHelper.routeBase}/download?${search}`, '_self'); + return Promise.resolve(true); + } + return super.download(url, name); + } +} diff --git a/src/view/download-view/download-view.scss b/src/view/download-view/download-view.scss new file mode 100644 index 0000000000000000000000000000000000000000..a834bc76e810b0b1519e0fe054f90d48a6f91aeb --- /dev/null +++ b/src/view/download-view/download-view.scss @@ -0,0 +1,24 @@ +@include b(download-view) { + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background-color: #fff; + + @include e(tooltip) { + padding: 20px; + color: var(--van-cell-text-color); + } + + @include e(tip) { + width: 100%; + img { + width: 100%; + } + .van-loading { + text-align: center; + } + } +} \ No newline at end of file diff --git a/src/view/download-view/download-view.tsx b/src/view/download-view/download-view.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6922cf874bfdb078719bcea3b0efe25e5ed149b5 --- /dev/null +++ b/src/view/download-view/download-view.tsx @@ -0,0 +1,117 @@ +/* eslint-disable no-restricted-globals */ +/* eslint-disable prefer-template */ +import { useNamespace } from '@ibiz-template/vue3-util'; +import { defineComponent, ref, Ref } from 'vue'; +import { useRoute } from 'vue-router'; +import './download-view.scss'; +import { CoreConst, setAppCookie } from '@ibiz-template/core'; +import { isAndroid, isWeChat } from '@ibiz-template/runtime'; + +export const DownloadView = defineComponent({ + setup() { + const ns = useNamespace('download-view'); + + const route = useRoute(); + + // 是否为安卓微信端 + const isAndroidWeChat: Ref = ref(false); + + // 提示信息 + const tooltip: Ref = ref(''); + + const status: Ref = ref('init'); + + const searchParams: IData = {}; + if (route.query.filename) { + searchParams.fileName = decodeURIComponent( + route.query.filename as string, + ); + } + if (route.query.fileurl) { + searchParams.fileUrl = decodeURIComponent(route.query.fileurl as string); + } + if (route.query.token) { + setAppCookie(CoreConst.TOKEN, route.query.token as string, 0); + } + + const onDownload = async () => { + status.value = 'processing'; + tooltip.value = ibiz.i18n.t('view.downloading'); + const result = await ibiz.platform.download( + searchParams.fileUrl, + searchParams.fileName, + ); + if (result) { + status.value = 'success'; + tooltip.value = ibiz.i18n.t('view.downloadSuccess'); + } else { + status.value = 'error'; + tooltip.value = ibiz.i18n.t('view.downloadFailed'); + } + }; + + isAndroidWeChat.value = isWeChat() && isAndroid(); + + // 微信环境下安卓下载特殊处理,需跳转到其他浏览器中打开下载 + if (isAndroidWeChat.value) { + tooltip.value = ibiz.i18n.t('view.noSupportDownload'); + status.value = 'disabled'; + } else { + onDownload(); + } + + const renderTip = () => { + if (status.value === 'success') { + return ( + + ); + } + if (['disabled', 'error'].includes(status.value)) { + return ; + } + if (status.value === 'processing') { + return ; + } + }; + + const renderButton = () => { + if (status.value === 'init') { + return ( + + {ibiz.i18n.t('view.immediatelyDownload')} + + ); + } + if (['success', 'error'].includes(status.value)) { + return ( + + {ibiz.i18n.t('view.reDownload')} + + ); + } + }; + + return { + ns, + tooltip, + status, + onDownload, + renderTip, + renderButton, + }; + }, + render() { + return ( +
+
{this.renderTip()}
+
{this.tooltip}
+ {this.renderButton()} +
+ ); + }, +}); diff --git a/src/view/index.ts b/src/view/index.ts index a485c63cde472d52ee09800467d3a4ee999b914a..4e7515699114d60375155aa9f97c2afa6244f704 100644 --- a/src/view/index.ts +++ b/src/view/index.ts @@ -1,2 +1,3 @@ export { View404 } from './404-view/404-view'; export { LoginView } from './login-view/login-view'; +export { DownloadView } from './download-view/download-view';