浏览代码

完善第三方链接的打开

shmily1213 3 周之前
父节点
当前提交
e73802ef53
共有 5 个文件被更改,包括 131 次插入98 次删除
  1. 1 0
      src/global.d.ts
  2. 2 2
      src/pagesMain/pages/index/components/index-news.vue
  3. 95 83
      src/pagesMain/pages/index/index.vue
  4. 13 2
      src/store/appStore.ts
  5. 20 11
      src/utils/uni-tool.ts

+ 1 - 0
src/global.d.ts

@@ -15,6 +15,7 @@ declare global {
   interface Wx {
     exitMiniProgram: (options?: { success?: () => void; fail?: (err: any) => void; complete?: () => void }) => void;
     restartMiniProgram: (options?: { path?: string; success?: () => void; fail?: (err: any) => void; complete?: () => void }) => void;
+    openOfficialAccountArticle: (options?: { url: string; success?: ({ cancel: boolean, confirm: boolean }) => void; fail?: (err: any) => void; complete?: () => void }) => void;
   }
   
   /**

+ 2 - 2
src/pagesMain/pages/index/components/index-news.vue

@@ -15,11 +15,11 @@ import { NewsItem } from '@/types/news';
 const newsList = ref<NewsItem[]>([]);
 
 const emit = defineEmits<{
-  detail: [id: number | string, title: string|null, url: string|undefined]
+  detail: [id: number | string, title?: string, url?: string]
 }>();
 
 const handleClick = async (data: NewsItem) => {
-  emit('detail', data.id, null, data.url);
+  emit('detail', data.id, undefined, data.url);
 }
 const loadData = async () => {
   const { rows } = await getNewsListNoToken({

+ 95 - 83
src/pagesMain/pages/index/index.vue

@@ -1,34 +1,33 @@
 <template>
-    <ie-page bg-color="white">
-        <ie-navbar transparent bg-color="#FFFFFF" :placeholder="false" custom-back :click-hover="false">
-            <template #headerLeft>
-                <view class="flex items-center gap-7 text-fore-title">
-                    <view class="text-38 font-bold">{{ orgName }}</view>
-                </view>
-            </template>
-            <template #headerRight="{ isTransparent }">
-                <view v-if="userStore.getLocation" class="ml-10 flex items-center gap-x-4"
-                      @click="handleChangeLocation">
-                    <uv-icon name="map" size="16" :color="isTransparent ? '#333' : 'var(--primary-color)'"/>
-                    <text class="text-30 font-medium" :class="[isTransparent ? 'text-fore-title' : 'text-primary']">
-                        {{ userStore.getLocation }}
-                    </text>
-                </view>
-            </template>
-        </ie-navbar>
-        <view class="absolute top-0 left-0 right-0 z-0 h-[489rpx] bg-gradient-to-b from-[#6ACAFF] to-white"></view>
-        <view class="relative z-2" :style="{ paddingTop: baseStickyTop + 10 + 'px' }">
-            <index-banner/>
-            <index-map/>
-            <index-guide v-if="false" @detail="handleDetail"/>
-            <index-news @detail="handleDetail"/>
+  <ie-page bg-color="white">
+    <ie-navbar transparent bg-color="#FFFFFF" :placeholder="false" custom-back :click-hover="false">
+      <template #headerLeft>
+        <view class="flex items-center gap-7 text-fore-title">
+          <view class="text-38 font-bold">{{ orgName }}</view>
         </view>
-        <template #tabbar>
-            <ie-tabbar :active="0"/>
-            <index-popup ref="popupRef"/>
-            <index-maintain-popup ref="maintainPopupRef"/>
-        </template>
-    </ie-page>
+      </template>
+      <template #headerRight="{ isTransparent }">
+        <view v-if="userStore.getLocation" class="ml-10 flex items-center gap-x-4" @click="handleChangeLocation">
+          <uv-icon name="map" size="16" :color="isTransparent ? '#333' : 'var(--primary-color)'" />
+          <text class="text-30 font-medium" :class="[isTransparent ? 'text-fore-title' : 'text-primary']">
+            {{ userStore.getLocation }}
+          </text>
+        </view>
+      </template>
+    </ie-navbar>
+    <view class="absolute top-0 left-0 right-0 z-0 h-[489rpx] bg-gradient-to-b from-[#6ACAFF] to-white"></view>
+    <view class="relative z-2" :style="{ paddingTop: baseStickyTop + 10 + 'px' }">
+      <index-banner />
+      <index-map />
+      <index-guide v-if="false" @detail="handleDetail" />
+      <index-news @detail="handleDetail" />
+    </view>
+    <template #tabbar>
+      <ie-tabbar :active="0" />
+      <index-popup ref="popupRef" />
+      <index-maintain-popup ref="maintainPopupRef" />
+    </template>
+  </ie-page>
 </template>
 
 <script lang="ts" setup>
@@ -39,90 +38,103 @@ import IndexMap from "./components/index-map.vue";
 import indexPopup from './components/index-popup.vue';
 import indexMaintainPopup from './components/index-maintain-popup.vue';
 
-import {useUserStore} from '@/store/userStore';
+import { useUserStore } from '@/store/userStore';
 // @ts-ignore
-import {useTransferPage} from '@/hooks/useTransferPage';
-import {useAppStore} from '@/store/appStore';
-import {useNavbar} from '@/hooks/useNavbar';
-import {onPageShow} from '@dcloudio/uni-app';
+import { useTransferPage } from '@/hooks/useTransferPage';
+import { useAppStore } from '@/store/appStore';
+import { useNavbar } from '@/hooks/useNavbar';
+import { onPageShow } from '@dcloudio/uni-app';
+import { useEnv } from '@/hooks/useEnv';
 
 const appStore = useAppStore();
-const {routes, transferTo} = useTransferPage();
-const {baseStickyTop} = useNavbar();
+const { routes, transferTo } = useTransferPage();
+const { isAndroid, isIOS, isWap2App, isMP, isH5 } = useEnv();
+const { baseStickyTop } = useNavbar();
 const scrollTop = ref(0);
 const isHide = ref(false);
 const userStore = useUserStore();
 const orgName = computed(() => userStore.orgInfo.orgName);
 
 const handleDetail = async (id: number | string, title?: string, url?: string) => {
-    if (url) {
-        uni.$ie.openBrowser(url)
-    } else if (('' + id).includes(',')) {
-        transferTo(routes.newsGroup, {
-            data: {
-                ids: id,
-                title: title
-            }
-        });
+  if (url) {
+    if (isMP.value) {
+      wx.openOfficialAccountArticle({
+        url,
+        fail: () => uni.$ie.copyWithModal(url)
+      })
+    } else if (isH5.value) {
+      window.open(url, '_blank')
+    } else if (isWap2App.value) {
+      plus.runtime.openURL(url)
     } else {
-        transferTo(routes.newsDetail, {
-            data: {
-                id: id,
-                title: title
-            }
-        })
+      uni.$ie.copyWithModal(url)
     }
+  } else if (('' + id).includes(',')) {
+    transferTo(routes.newsGroup, {
+      data: {
+        ids: id,
+        title: title
+      }
+    });
+  } else {
+    transferTo(routes.newsDetail, {
+      data: {
+        id: id,
+        title: title
+      }
+    })
+  }
 }
 
 const popupRef = ref();
 const checkProvinceInfo = () => {
-    if (!userStore.isLogin && !userStore.tempInfo?.location) {
-        popupRef.value.open();
-    }
+  if (!userStore.isLogin && !userStore.tempInfo?.location) {
+    popupRef.value.open();
+  }
 }
 const checkInfo = async () => {
-    await userStore.checkInfoTeacherComplete();
-    await userStore.checkInfoStudentComplete();
+  await userStore.checkInfoTeacherComplete();
+  await userStore.checkInfoStudentComplete();
 }
 const reloadUserInfo = async () => {
-    if (userStore.isLogin) {
-        await userStore.getUserInfo();
-    }
+  if (userStore.isLogin) {
+    await userStore.getUserInfo();
+  }
 }
 const handleChangeLocation = () => {
-    if (userStore.isLogin) {
-        return;
-    }
-    popupRef.value.open();
+  if (userStore.isLogin) {
+    return;
+  }
+  popupRef.value.open();
 }
 onHide(() => {
-    isHide.value = true;
+  isHide.value = true;
 })
 onPageScroll((e) => {
-    if (!isHide.value) {
-        scrollTop.value = e.scrollTop;
-    }
+  if (!isHide.value) {
+    scrollTop.value = e.scrollTop;
+  }
 });
 const maintainPopupRef = ref();
 onMounted(async () => {
-    if (appStore.hasMaintain && !appStore.maintainNotice!.read) {
-        await uni.$uv.sleep(500);
-        await maintainPopupRef.value?.open();
-    }
-    checkProvinceInfo();
-    if (userStore.isLogin) {
-        checkInfo();
-        userStore.getDirectedSchoolList();
-    }
+  if (appStore.hasMaintain && !appStore.maintainNotice!.read) {
+    await uni.$uv.sleep(500);
+    await maintainPopupRef.value?.open();
+  }
+  checkProvinceInfo();
+  if (userStore.isLogin) {
+    checkInfo();
+    userStore.getDirectedSchoolList();
+  }
 });
 onShow(() => {
-    setTimeout(() => {
-        uni.pageScrollTo({
-            scrollTop: scrollTop.value,
-            duration: 0
-        });
-    }, 0);
-    isHide.value = false;
+  setTimeout(() => {
+    uni.pageScrollTo({
+      scrollTop: scrollTop.value,
+      duration: 0
+    });
+  }, 0);
+  isHide.value = false;
 });
 </script>
 

+ 13 - 2
src/store/appStore.ts

@@ -34,7 +34,8 @@ export const useAppStore = defineStore('ie-app', {
       return this.sysInfo.uniPlatform === 'mp-weixin';
     },
     hasMaintain(): boolean {
-      return this.maintainNotice !== null;
+      // 时间没有过期
+      return this.maintainNotice !== null && !isExpired(this.maintainNotice?.beginTime, this.maintainNotice?.endTime);
     },
     isMaintaining(): boolean {
       return isBetweenTime(this.maintainNotice?.beginTime, this.maintainNotice?.endTime);
@@ -189,4 +190,14 @@ const isBetweenTime = (beginTime?: string, endTime?: string) => {
     return new Date(beginTime).getTime() <= now && new Date(endTime).getTime() >= now;
   }
   return false;
-}
+}
+
+const isExpired = (beginTime?: string, endTime?: string) => {
+  const now = Date.now();
+  if (beginTime && endTime) {
+    beginTime = beginTime.replaceAll('-', '/');
+    endTime = endTime.replaceAll('-', '/');
+    return new Date(endTime).getTime() <= now;
+  }
+  return false;
+} 

+ 20 - 11
src/utils/uni-tool.ts

@@ -83,6 +83,7 @@ export interface IeTool {
 
   /* 打开网址 */
   openBrowser(url: string): void;
+  copyWithModal(content: string): Promise<boolean>;
 }
 
 const defaultModalOptions: IModalOptions = {
@@ -187,19 +188,25 @@ const tool: IeTool = {
       success: () => { }
     });
   },
-  openBrowser(url: string) {
-    const handleCopy = function () {
+  copyWithModal(content: string): Promise<boolean> {
+    return new Promise((resolve, reject) => {
       uni.setClipboardData({
-        data: url,
+        data: content,
+        showToast: false, // 不显示toast
         success: () => {
           uni.showModal({
             title: '提示',
             content: '链接已复制,请在浏览器中打开',
-            showCancel: false
+            showCancel: false,
+            complete: () => {
+              resolve(true)
+            }
           })
         }
       })
-    }
+    })
+  },
+  openBrowser(url: string) {
     // 判断平台
     // #ifdef APP-PLUS
     plus.runtime.openURL(url)
@@ -213,23 +220,25 @@ const tool: IeTool = {
     // 微信小程序
     try {
       if (url.toLowerCase().startsWith('https://mp.weixin.qq.com/')) {
-        uni.openOfficialAccountArticle({
+        wx.openOfficialAccountArticle({
           url,
-          fail: handleCopy
+          fail: () => {
+            this.copyWithModal(url)
+          }
         })
       } else {
-        handleCopy()
+        this.copyWithModal(url)
       }
-    } catch (e){
+    } catch (e) {
       console.log('小程序打开链接降级处理', e)
-      handleCopy()
+      this.copyWithModal(url)
     }
     // #endif
 
     // 其他平台,如App、快应用等,可以根据需要补充
     // 对于不支持直接打开浏览器的平台,使用降级方案
     // #ifndef H5 || MP-WEIXIN
-    handleCopy()
+    this.copyWithModal(url)
     // #endif
   }
 };