Kaynağa Gözat

feat(mobile-h5): add OA WeChat notify bind entry and web-view page

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 2 ay önce
ebeveyn
işleme
3a41902d2b

+ 8 - 0
mobile-h5/pages.json

@@ -64,6 +64,14 @@
         "navigationBarTextStyle": "black"
       }
     },
+    {
+      "path": "pages/oa/mp-bind/index",
+      "style": {
+        "navigationBarTitleText": "微信审批通知",
+        "navigationBarBackgroundColor": "#ecfdf5",
+        "navigationBarTextStyle": "black"
+      }
+    },
     {
       "path": "pages/oa/pdf-preview/index",
       "style": {

+ 49 - 2
mobile-h5/pages/index/index.vue

@@ -11,7 +11,12 @@
           <view v-if="postName && deptName" class="dot" />
           <text v-if="deptName">{{ deptName }}</text>
         </view>
-        <text class="home-logout" @click="onLogout">退出登录</text>
+        <view class="meta__right">
+          <text class="home-mp-notify" @click="onTapMpNotify">
+            {{ mpNotifyBound ? '微信通知已开启' : '开启微信审批通知' }}
+          </text>
+          <text class="home-logout" @click="onLogout">退出登录</text>
+        </view>
       </view>
     </view>
 
@@ -86,7 +91,12 @@
 <script>
   import MenuGrid from '../../components/MenuGrid.vue'
   import VanEmpty from '../../components/van-empty/van-empty.vue'
-  import { clearSession, fetchCurrentUser, getUser } from '../../utils/auth.js'
+  import {
+    clearSession,
+    fetchCurrentUser,
+    fetchMpBindStatus,
+    getUser
+  } from '../../utils/auth.js'
   import { fetchMyMobileMenus } from '../../utils/menu.js'
   import {
     formatOaBadgeCount,
@@ -124,6 +134,8 @@
         deptName: '',
         menus: [],
         menusLoading: true,
+        mpNotifyBound: false,
+        mpNotifyLoading: false,
         banners: [
           {
             id: 'banner-video-1',
@@ -148,9 +160,28 @@
         .catch(() => {
           /* 本地缓存已展示,忽略刷新失败 */
         })
+      this.refreshMpBindStatus()
       this.loadMenus()
     },
     methods: {
+      async refreshMpBindStatus() {
+        this.mpNotifyLoading = true
+        try {
+          const res = await fetchMpBindStatus()
+          this.mpNotifyBound = !!(res && res.bound)
+        } catch (_) {
+          this.mpNotifyBound = false
+        } finally {
+          this.mpNotifyLoading = false
+        }
+      },
+      onTapMpNotify() {
+        if (this.mpNotifyBound) {
+          uni.showToast({ title: '已开启', icon: 'none' })
+          return
+        }
+        uni.navigateTo({ url: '/pages/oa/mp-bind/index' })
+      },
       mergeBadgesIntoMenus(menus, badgeMap) {
         const map = badgeMap || {}
         return (menus || []).map((m) => {
@@ -222,6 +253,22 @@
 </script>
 
 <style lang="scss" scoped>
+  .meta__right {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-end;
+    gap: 12rpx;
+    flex-shrink: 0;
+  }
+
+  .home-mp-notify {
+    font-size: 22rpx;
+    line-height: 1.3;
+    color: rgba(6, 95, 70, 0.72);
+    text-decoration: underline;
+    text-underline-offset: 4rpx;
+  }
+
   .home-menus-loading {
     display: flex;
     flex-direction: column;

+ 30 - 0
mobile-h5/pages/oa/mp-bind/index.vue

@@ -0,0 +1,30 @@
+<template>
+  <web-view v-if="src" :src="src" />
+</template>
+<script>
+import { forceRelogin, getToken } from '../../../utils/auth.js'
+import { OA_H5_ORIGIN, MP_BIND_H5_PATH } from '../../../utils/config.js'
+
+export default {
+  data() {
+    return { src: '' }
+  },
+  onLoad() {
+    const token = getToken()
+    if (!token) {
+      forceRelogin('请先登录')
+      return
+    }
+    const base = String(OA_H5_ORIGIN || '').replace(/\/$/, '')
+    // Align with mobile-oa-h5 route `/oa-mp-bind` (no trailing slash)
+    const path =
+      String(MP_BIND_H5_PATH || '/oa-mp-bind').replace(/\/+$/, '') ||
+      '/oa-mp-bind'
+    this.src =
+      base +
+      (path.charAt(0) === '/' ? path : '/' + path) +
+      '?token=' +
+      encodeURIComponent(token)
+  }
+}
+</script>

+ 13 - 0
mobile-h5/utils/auth.js

@@ -122,3 +122,16 @@ export async function bindWechatQuietly() {
     console.warn('wechat bind skipped', e && e.message)
   }
 }
+
+/**
+ * 查询当前用户是否已绑定服务号(用于微信审批通知)。
+ * @returns {Promise<{ bound: boolean }>}
+ */
+export async function fetchMpBindStatus() {
+  const token = getToken()
+  if (!token) return { bound: false }
+  const data = await get('/mini/auth/mp-bind-status', {
+    Authorization: 'Bearer ' + token
+  })
+  return { bound: !!(data && data.bound) }
+}