haiyang 6 өдөр өмнө
parent
commit
7fbe794259

+ 2 - 0
env/.env

@@ -11,6 +11,8 @@ VITE_APP_PUBLIC_BASE=/
 
 # 后台请求地址
 VITE_SERVER_BASEURL = 'http://192.168.1.28:8082/jeecg-boot'
+# 后台静态资源请求地址
+VITE_SERVER_RESOURCE_BASEURL ='/sys/common/static'
 # 备注:如果后台带统一前缀,则也要加到后面,eg: https://ukw0y1.laf.run/api
 
 # 注意,如果是微信小程序,还有一套请求地址的配置,根据 develop、trial、release 分别设置上传地址,见 `src/utils/index.ts`。

+ 4 - 0
env/.env.development

@@ -7,3 +7,7 @@ VITE_SHOW_SOURCEMAP = false
 
 # 后台请求地址
 VITE_SERVER_BASEURL = 'http://192.168.1.28:8082/jeecg-boot'
+# VITE_SERVER_BASEURL = 'http://192.168.1.232:8082/jeecg-boot'
+
+# 后台静态资源请求地址
+VITE_SERVER_RESOURCE_BASEURL ='/sys/common/static'

+ 3 - 0
env/.env.production

@@ -7,3 +7,6 @@ VITE_SHOW_SOURCEMAP = false
 
 # 后台请求地址
 # VITE_SERVER_BASEURL = 'https://prod.xxx.com'
+
+# 后台静态资源请求地址
+#VITE_SERVER_RESOURCE_BASEURL ='/sys/common/static'

+ 9 - 1
src/App.ku.vue

@@ -1,5 +1,6 @@
 <script setup lang="ts">
 import { ref } from 'vue'
+import { useTokenStore } from '@/store/token'
 import FgTabbar from '@/tabbar/index.vue'
 import { useLoadingStore } from './store/loading'
 import { isPageTabbar, tabbarStore } from './tabbar/store'
@@ -7,10 +8,11 @@ import { currRoute } from './utils'
 
 const isCurrentPageTabbar = ref(true)
 const loadingStore = useLoadingStore()
+const tokenStore = useTokenStore()
 
 onShow(() => {
     console.log('App.ku.vue onShow', currRoute())
-    const { path } = currRoute()
+    const { path, query } = currRoute()
     // “蜡笔小开心”提到本地是 '/pages/index/index',线上是 '/' 导致线上 tabbar 不见了
     // 所以这里需要判断一下,如果是 '/' 就当做首页,也要显示 tabbar
     isCurrentPageTabbar.value = path === '/' || isPageTabbar(path)
@@ -19,6 +21,12 @@ onShow(() => {
             tabbarStore.setAutoCurIdx(path)
         }
     }, 0)
+
+    // 判断是否是通过分享进入
+    if (query?.shareRecordId) {
+        tokenStore.cacheShareParams(query)
+    }
+
     loadingStore.hideLoading()
 })
 

+ 16 - 0
src/api/home.ts

@@ -45,3 +45,19 @@ export function getHomeCouponRedemptionList(params) {
         ...params,
     })
 }
+
+export function getShareInfo(params) {
+    return http.Post('/couponCenter/APP/shareRecord/add', {
+        ...params,
+    })
+}
+
+export function getCouponDetail(params) {
+    return http.Get('/couponCenter/APP/couponTemplate/queryById', {
+        params,
+    })
+}
+
+export function getIssuerDetail() {
+    return http.Get('/couponCenter/APP/couponIssuerApply/queryById')
+}

+ 7 - 1
src/api/login.ts

@@ -45,7 +45,7 @@ export function getUserInfo() {
  * 退出登录
  */
 export function logout() {
-    return http.Get<void>('/auth/logout')
+    return http.Get<void>('/couponCenter/APP/wx/logout')
 }
 
 /**
@@ -92,3 +92,9 @@ export function wxLogin(code: string) {
         },
     })
 }
+
+export function addInviteConversion(params) {
+    return http.Post('/couponCenter/APP/shareRecord/addInviteConversion', {
+        ...params,
+    })
+}

+ 13 - 2
src/components/discountCoupon.vue

@@ -14,6 +14,7 @@ const props = defineProps({
     }
 })
 const coupon = computed(() => props.coupon)
+const couponTemplateId = computed(() => coupon.value.templateId || '')
 const deadline = computed(() => {
     const type = props.coupon.validityType
     if (type === '1') {
@@ -50,10 +51,10 @@ const deadline = computed(() => {
         <view class="discount-desc-time">
             {{ deadline }},最高优惠{{ coupon.ruleDiscountCapAmount }}元
         </view>
-        <view class="discount-btn">
+        <button class="discount-btn" open-type="share" :data-coupon-id="couponTemplateId" data-share-type="coupon">
             <view>立即</view>
             <view>发券</view>
-        </view>
+        </button>
     </view>
 </template>
 
@@ -159,6 +160,16 @@ const deadline = computed(() => {
         align-items: center;
         gap: 10rpx;
         z-index: 1;
+        padding: 0;
+        background-color: transparent;
+        border: none;
+        line-height: 28rpx;
+
+        &::after {
+            border: none;
+            position: unset;
+            height: inherit;
+        }
     }
 }
 </style>

+ 17 - 1
src/components/spendAndSaveCoupon.vue

@@ -8,7 +8,23 @@ const props = defineProps({
         }),
     }
 })
+
 const coupon = computed(() => props.coupon)
+const couponTemplateId = computed(() => coupon.value.templateId || '')
+
+// async function handleShareClick() {
+//     if (!props.coupon?.templateId)
+//         return
+
+//     try {
+//         // 触发分享事件,传递给父组件处理
+//         emit('share', props.coupon)
+//     }
+//     finally {
+//         // 这里不需要立即设置为false,因为异步分享完成后由父组件控制
+//         // shareLoading.value = false
+//     }
+// }
 </script>
 
 <template>
@@ -27,7 +43,7 @@ const coupon = computed(() => props.coupon)
             </view>
         </view>
 
-        <button class="coupon-btn">
+        <button class="coupon-btn" open-type="share" :data-coupon-id="couponTemplateId" data-share-type="coupon">
             去发券
         </button>
     </view>

+ 15 - 8
src/components/spendAndSaveCoupon_large.vue

@@ -11,7 +11,7 @@ const props = defineProps({
     }
 })
 const coupon = computed(() => props.coupon)
-console.log(coupon.value)
+const couponTemplateId = computed(() => coupon.value.templateId || '')
 const deadline = computed(() => {
     const type = props.coupon.validityType
     if (type === '1') {
@@ -70,10 +70,11 @@ const category = computed(() => {
             </view>
         </view>
         <view class="discount-btn">
-            <view class="coupon-btn-container">
+            <button class="coupon-btn-container" open-type="share" :data-coupon-id="couponTemplateId"
+                data-share-type="coupon">
                 <view>立即</view>
                 <view>发券</view>
-            </view>
+            </button>
         </view>
     </view>
 </template>
@@ -184,16 +185,22 @@ const category = computed(() => {
         .coupon-btn-container {
             width: 115rpx;
             height: 115rpx;
-            display: flex;
-            flex-direction: column;
-            justify-content: center;
-            align-items: center;
-            gap: 10rpx;
+
             transform: translateX(7rpx);
+            padding: 17rpx 20rpx 18rpx 20rpx;
+            background-color: transparent;
+            border: none;
 
             font-weight: 500;
             font-size: 28rpx;
             color: #ffffff;
+            line-height: 41rpx;
+
+            &::after {
+                border: none;
+                position: unset;
+                height: inherit;
+            }
         }
     }
 }

+ 143 - 0
src/hooks/useShare.ts

@@ -0,0 +1,143 @@
+import { getIssuerDetail, getShareInfo } from '@/api/home'
+import { useTokenStore } from '@/store/token'
+
+/**
+ * 分享配置选项
+ */
+export interface ShareOptions {
+    title?: string
+    path?: string
+    imageUrl?: string
+    shareType?: 'INVITE' | 'COUPON' | string
+    showLoading?: boolean
+    imageSource?: 'LOCAL' | 'REMOTE'
+}
+
+interface ShareInfo {
+    shareType: 'INVITE' | 'COUPON' | string
+    shareContentId?: string
+    sharePath?: string
+}
+
+/**
+ * 默认分享配置
+ */
+const defaultOptions: Required<ShareOptions> = {
+    title: '领券省心,消费超值,优质生活轻松开启!',
+    path: '/pages/index/index',
+    imageUrl: '/static/images/share.jpg',
+    shareType: 'INVITE',
+    showLoading: true,
+    imageSource: 'LOCAL',
+}
+
+/**
+ * 分享hook - 用于页面生命周期中使用
+ * @param initOptions 自定义分享配置
+ * @returns 可以在onShareAppMessage中使用的异步函数
+ */
+export function useShare(initOptions: ShareOptions = {}) {
+    /**
+                                   * 获取分享配置 - 可以直接在onShareAppMessage中调用
+                                   * @returns 完整的分享配置
+                                   */
+    const getShareConfig = async (customOption?: ShareOptions, extraParams?): Promise<WechatMiniprogram.Page.ICustomShareContent | {}> => {
+        // 合并默认配置和自定义配置
+        const options = { ...defaultOptions, ...initOptions, ...customOption }
+
+        // 检查用户是否已登录
+        const tokenStore = useTokenStore()
+        if (!tokenStore.hasLogin) {
+            uni.showToast({
+                title: '请先登录后再分享',
+                icon: 'none',
+            })
+        }
+
+        try {
+            if (options.showLoading) {
+                uni.showLoading({
+                    title: '获取分享信息中...',
+                    mask: true,
+                })
+            }
+            const IssuerResult = await getIssuerDetail()
+            if (IssuerResult?.status !== '1') {
+                throw new Error('当前用户不是发券人,无法发放优惠券')
+            }
+            const params: ShareInfo = {
+                shareType: options.shareType,
+            }
+
+            if (options.shareType === 'COUPON') {
+                if (!extraParams?.shareContentId) {
+                    throw new Error('分享优惠券时需要提供优惠券ID')
+                }
+                params.shareContentId = extraParams?.shareContentId || ''
+            }
+            else {
+                params.sharePath = options.path
+            }
+
+            // 请求分享信息接口
+            const res = await getShareInfo(params)
+
+            if (options.showLoading) {
+                uni.hideLoading()
+            }
+
+            if (res !== '' && res !== null && res !== 'null') {
+                // 拼接分享路径
+                const sharePath = `${options.path}${options.path.includes('?') ? '&' : '?'}shareRecordId=${res}`
+                let imageUrl = ''
+                if (options.imageSource === 'LOCAL') {
+                    imageUrl = options.imageUrl
+                }
+                else {
+                    imageUrl = `${import.meta.env.VITE_SERVER_BASEURL}${import.meta.env.VITE_SERVER_RESOURCE_BASEURL}/${options.imageUrl}`
+                }
+                console.log(imageUrl)
+                return {
+                    title: options.title,
+                    path: sharePath,
+                    imageUrl,
+                }
+            }
+            else {
+                uni.showToast({
+                    title: '分享信息获取失败',
+                    icon: 'none',
+                    duration: 2000,
+                })
+            }
+        }
+        catch (error) {
+            if (options.showLoading) {
+                uni.hideLoading()
+            }
+
+            uni.showToast({
+                title: error.message || '获取分享信息失败,请稍后重试',
+                icon: 'none',
+            })
+        }
+    }
+
+    /**
+                                   * 获取朋友圈分享配置 - 可以直接在onShareTimeline中调用
+                                   * @returns 完整的朋友圈分享配置
+                                   */
+    const getTimelineShareConfig = async (): Promise<WechatMiniprogram.Page.ICustomShareTimelineContent | {}> => {
+        const config = await getShareConfig() as WechatMiniprogram.Page.ICustomShareContent
+        return {
+            title: config.title,
+            path: config.path,
+            imageUrl: config.imageUrl,
+        }
+    }
+
+    return {
+        getShareConfig,
+        getTimelineShareConfig
+    }
+}

+ 0 - 3
src/main.ts

@@ -5,14 +5,11 @@ import { requestInterceptor } from './http/interceptor'
 import { routeInterceptor } from './router/interceptor'
 import store from './store'
 import { registerGlobalFilters } from './utils/directive'
-import { shareMixin } from './utils/shareMixin'
 import '@/style/index.scss'
 import 'virtual:uno.css'
 
 export function createApp() {
     const app = createSSRApp(App)
-    // 注册全局分享函数
-    app.mixin(shareMixin)
 
     app.use(store)
     app.use(uviewPlus)

+ 25 - 1
src/pages-A/discountcouponList/index.vue

@@ -1,8 +1,9 @@
 <script lang="ts" setup>
 import { computed, ref } from 'vue'
 import { useScroll } from '@/hooks/useScroll'
+import { useShare } from '@/hooks/useShare'
 import { safeAreaInsets } from '@/utils'
-import { getCouponByType } from '../../api/home'
+import { getCouponByType, getCouponDetail } from '../../api/home'
 import DiscountCoupon from '../../components/discountCoupon.vue'
 
 definePage({
@@ -50,6 +51,29 @@ onLoad((options) => {
         onRefresh()
     }
 })
+
+const { getShareConfig: getShareCouponConfig } = useShare({
+    shareType: 'COUPON',
+    imageSource: 'REMOTE',
+})
+
+// #ifdef MP-WEIXIN
+// 分享功能实现
+// 分享生命周期函数
+onShareAppMessage(async (options) => {
+    console.log(options)
+    if (options.from === 'button' && options.target.dataset.shareType === 'coupon') {
+        const couponId = options.target.dataset.couponId
+        const couponinfo = await getCouponDetail({ templateId: couponId })
+        return await getShareCouponConfig({
+            imageUrl: couponinfo?.imageUrl,
+        }, {
+            shareContentId: couponId,
+        })
+    }
+    return null
+})
+// #endif
 </script>
 
 <template>

+ 24 - 1
src/pages-A/spendAndSaveCouponList/index.vue

@@ -1,8 +1,9 @@
 <script lang="ts" setup>
 import { computed, ref } from 'vue'
 import { useScroll } from '@/hooks/useScroll'
+import { useShare } from '@/hooks/useShare'
 import { safeAreaInsets } from '@/utils'
-import { getCouponByType } from '../../api/home'
+import { getCouponByType, getCouponDetail } from '../../api/home'
 import SpendAndSaveCoupon from '../../components/spendAndSaveCoupon_large.vue'
 
 definePage({
@@ -36,6 +37,28 @@ const {
     pageSize: 7,
 })
 
+const { getShareConfig: getShareCouponConfig } = useShare({
+    shareType: 'COUPON',
+    imageSource: 'REMOTE',
+})
+
+// #ifdef MP-WEIXIN
+// 分享功能实现
+// 分享生命周期函数
+onShareAppMessage(async (options) => {
+    if (options.from === 'button' && options.target.dataset.shareType === 'coupon') {
+        const couponId = options.target.dataset.couponId
+        const couponinfo = await getCouponDetail({ templateId: couponId })
+        return await getShareCouponConfig({
+            imageUrl: couponinfo?.imageUrl,
+        }, {
+            shareContentId: couponId,
+        })
+    }
+    return null
+})
+// #endif
+
 // 计算底部安全区高度
 const safeBottomHeight = computed(() => {
     return safeAreaInsets?.bottom || 0

+ 51 - 26
src/pages/index/index.vue

@@ -4,9 +4,10 @@ import indexBg from '@img/index/index-bg.png'
 import { useRequest } from 'alova/client'
 import { storeToRefs } from 'pinia'
 import { ref, watch } from 'vue'
-import { getAccountCount, getCouponSituation } from '@/api/home'
+import { getAccountCount, getCouponDetail, getCouponSituation, getShareInfo } from '@/api/home'
 import DiscountCoupon from '@/components/discountCoupon.vue'
 import SpendAndSaveCoupon from '@/components/spendAndSaveCoupon.vue'
+import { useShare } from '@/hooks/useShare'
 import { useCouponStore } from '@/store/coupon'
 import { useTokenStore } from '@/store/token'
 import { toLoginPage } from '@/utils/toLoginPage'
@@ -27,6 +28,11 @@ definePage({
 const tokenStore = useTokenStore()
 const { hasLogin } = storeToRefs(tokenStore)
 
+// 分享配置
+const shareConfig = ref(null)
+const shareButtonRef = ref<HTMLElement | null>(null)
+const currentCouponId = ref<string>('')
+
 // 获取优惠券
 const couponStore = useCouponStore()
 const { couponList, discountVoucherList } = storeToRefs(couponStore)
@@ -34,11 +40,13 @@ const { couponList, discountVoucherList } = storeToRefs(couponStore)
 // 获取首页收益
 const { send: getAccountCountRequest, data: accountCountData } = useRequest(getAccountCount, {
     immediate: false,
+    dependencies: [],
 })
 
 // 获取首页领券情况数据
 const { send: getCouponSituationRequest, data: couponSituationData } = useRequest(getCouponSituation, {
     immediate: false,
+    dependencies: [],
 })
 
 onLoad(async () => {
@@ -46,36 +54,15 @@ onLoad(async () => {
     couponStore.getCouponListByType()
 })
 
-onShow(() => {
+onShow((options) => {
     // 登录后查询收益数据
     if (hasLogin) {
-        getAccountCountRequest()
-        getCouponSituationRequest()
+        Promise.allSettled([getAccountCountRequest(), getCouponSituationRequest()])
+        // getAccountCountRequest()
+        // getCouponSituationRequest()
     }
 })
 
-// // 页面分享给朋友
-// onShareAppMessage(() => {
-//     return {
-//         title: '券中心',
-//         path: '/pages/index/index',
-//         imageUrl: '/static/logo.svg',
-//     }
-// })
-
-// // 页面分享到朋友圈
-// onShareTimeline(() => {
-//     return {
-//         title: '优惠券管理系统',
-//         path: '/pages/index/index',
-//         imageUrl: '/static/logo.svg',
-//     }
-// })
-
-watch(() => couponSituationData, (newVal) => {
-    console.log('首页领券情况数据:', newVal)
-})
-
 // #ifdef MP-WEIXIN
 async function login() {
     const currentPage = getCurrentPages()[0]
@@ -116,6 +103,33 @@ function toCouponRedemptionList(state) {
         url: `/pages-A/couponRedemptionList/index?state=${state}`,
     })
 }
+
+// 创建分享hook实例
+const { getShareConfig } = useShare()
+const { getShareConfig: getShareCouponConfig } = useShare({
+    shareType: 'COUPON',
+    imageSource: 'REMOTE',
+})
+
+// #ifdef MP-WEIXIN
+// 分享功能实现
+// 分享生命周期函数
+onShareAppMessage(async (options) => {
+    console.log(options)
+    if (options.from === 'button' && options.target.dataset.shareType === 'coupon') {
+        const couponId = options.target.dataset.couponId
+        const couponinfo = await getCouponDetail({ templateId: couponId })
+        return await getShareCouponConfig({
+            imageUrl: couponinfo?.imageUrl,
+        }, {
+            shareContentId: couponId,
+        })
+    }
+    else {
+        return await getShareConfig()
+    }
+})
+// #endif
 </script>
 
 <template>
@@ -421,6 +435,17 @@ function toCouponRedemptionList(state) {
             gap: 20rpx;
             position: relative;
             z-index: 1;
+
+            .hidden-share-btn {
+                /* 隐藏按钮但保持可点击 */
+                position: absolute;
+                left: -9999px;
+                top: -9999px;
+                width: 0;
+                height: 0;
+                opacity: 0;
+                pointer-events: none;
+            }
         }
 
         .home-header-coupon-btn {

BIN
src/static/images/share.jpg


+ 49 - 35
src/store/token.ts

@@ -9,6 +9,7 @@ import {
     logout as _logout,
     refreshToken as _refreshToken,
     wxLogin as _wxLogin,
+    addInviteConversion,
     getUserProfile,
     getWxCode,
 } from '@/api/login'
@@ -34,6 +35,11 @@ export const useTokenStore = defineStore(
     () => {
         // 定义用户信息
         const tokenInfo = ref<IAuthLoginRes>({ ...tokenInfoState })
+
+        const isShareEnter = computed(() => {
+            return uni.getStorageSync('shareParams') !== ''
+        })
+
         // 设置用户信息
         const setTokenInfo = (val: IAuthLoginRes) => {
             tokenInfo.value = val
@@ -55,8 +61,8 @@ export const useTokenStore = defineStore(
         }
 
         /**
-                                                                         * 判断token是否过期
-                                                                         */
+                                                                                                     * 判断token是否过期
+                                                                                                     */
         const isTokenExpired = computed(() => {
             if (!tokenInfo.value) {
                 return true
@@ -71,8 +77,8 @@ export const useTokenStore = defineStore(
         })
 
         /**
-                                                                         * 判断refreshToken是否过期
-                                                                         */
+                                                                                                     * 判断refreshToken是否过期
+                                                                                                     */
         const isRefreshTokenExpired = computed(() => {
             if (!isDoubleTokenMode)
                 return true
@@ -86,9 +92,9 @@ export const useTokenStore = defineStore(
         })
 
         /**
-                                                                         * 登录成功后处理逻辑
-                                                                         * @param tokenInfo 登录返回的token信息
-                                                                         */
+                                                                                                     * 登录成功后处理逻辑
+                                                                                                     * @param tokenInfo 登录返回的token信息
+                                                                                                     */
         async function _postLogin(tokenInfo: IAuthLoginRes) {
             setTokenInfo(tokenInfo)
             // const userStore = useUserStore()
@@ -96,12 +102,12 @@ export const useTokenStore = defineStore(
         }
 
         /**
-                                                                         * 用户登录
-                                                                         * 有的时候后端会用一个接口返回token和用户信息,有的时候会分开2个接口,一个获取token,一个获取用户信息
-                                                                         * (各有利弊,看业务场景和系统复杂度),这里使用2个接口返回的来模拟
-                                                                         * @param loginForm 登录参数
-                                                                         * @returns 登录结果
-                                                                         */
+                                                                                                     * 用户登录
+                                                                                                     * 有的时候后端会用一个接口返回token和用户信息,有的时候会分开2个接口,一个获取token,一个获取用户信息
+                                                                                                     * (各有利弊,看业务场景和系统复杂度),这里使用2个接口返回的来模拟
+                                                                                                     * @param loginForm 登录参数
+                                                                                                     * @returns 登录结果
+                                                                                                     */
         const login = async (loginForm: ILoginForm) => {
             try {
                 const res = await _login(loginForm)
@@ -124,11 +130,11 @@ export const useTokenStore = defineStore(
         }
 
         /**
-                                                                         * 微信登录
-                                                                         * 有的时候后端会用一个接口返回token和用户信息,有的时候会分开2个接口,一个获取token,一个获取用户信息
-                                                                         * (各有利弊,看业务场景和系统复杂度),这里使用2个接口返回的来模拟
-                                                                         * @returns 登录结果
-                                                                         */
+                                                                                                     * 微信登录
+                                                                                                     * 有的时候后端会用一个接口返回token和用户信息,有的时候会分开2个接口,一个获取token,一个获取用户信息
+                                                                                                     * (各有利弊,看业务场景和系统复杂度),这里使用2个接口返回的来模拟
+                                                                                                     * @returns 登录结果
+                                                                                                     */
         const wxLogin = async () => {
             try {
                 // 获取用户信息
@@ -138,6 +144,9 @@ export const useTokenStore = defineStore(
                 const code = await getWxCode()
                 console.log('微信登录-code: ', code.code)
                 const res = await _wxLogin(code.code)
+                if (isShareEnter.value) {
+                    await addInviteConversion(JSON.parse(uni.getStorageSync('shareParams')))
+                }
                 console.log('微信登录-res: ', res)
                 await _postLogin(res)
                 uni.showToast({
@@ -157,8 +166,8 @@ export const useTokenStore = defineStore(
         }
 
         /**
-                                                                         * 退出登录 并 删除用户信息
-                                                                         */
+                                                                                                     * 退出登录 并 删除用户信息
+                                                                                                     */
         const logout = async () => {
             try {
                 // TODO 实现自己的退出登录逻辑
@@ -189,9 +198,9 @@ export const useTokenStore = defineStore(
         }
 
         /**
-                                                                         * 刷新token
-                                                                         * @returns 刷新结果
-                                                                         */
+                                                                                                     * 刷新token
+                                                                                                     * @returns 刷新结果
+                                                                                                     */
         const refreshToken = async () => {
             if (!isDoubleTokenMode) {
                 console.error('单token模式不支持刷新token')
@@ -217,10 +226,10 @@ export const useTokenStore = defineStore(
         }
 
         /**
-                                                                         * 获取有效的token
-                                                                         * 注意:在computed中不直接调用异步函数,只做状态判断
-                                                                         * 实际的刷新操作应由调用方处理
-                                                                         */
+                                                                                                     * 获取有效的token
+                                                                                                     * 注意:在computed中不直接调用异步函数,只做状态判断
+                                                                                                     * 实际的刷新操作应由调用方处理
+                                                                                                     */
         const getValidToken = computed(() => {
             // token已过期,返回空
             if (isTokenExpired.value) {
@@ -236,8 +245,8 @@ export const useTokenStore = defineStore(
         })
 
         /**
-                                                                         * 检查是否有登录信息(不考虑token是否过期)
-                                                                         */
+                                                                                                     * 检查是否有登录信息(不考虑token是否过期)
+                                                                                                     */
         const hasLoginInfo = computed(() => {
             if (!tokenInfo.value) {
                 return false
@@ -251,17 +260,17 @@ export const useTokenStore = defineStore(
         })
 
         /**
-                         * 检查是否已登录且token有效
-                         */
+                                                     * 检查是否已登录且token有效
+                                                     */
         const hasValidLogin = computed(() => {
             console.log('hasValidLogin', hasLoginInfo.value && !isTokenExpired.value, hasLoginInfo.value, !isTokenExpired.value)
             return hasLoginInfo.value && !isTokenExpired.value
         })
 
         /**
-                     * 尝试获取有效的token,如果过期且可刷新,则刷新token
-                     * @returns 有效的token或空字符串
-                     */
+                                                 * 尝试获取有效的token,如果过期且可刷新,则刷新token
+                                                 * @returns 有效的token或空字符串
+                                                 */
         const tryGetValidToken = async (): Promise<string> => {
             if (!getValidToken.value && isDoubleTokenMode && !isRefreshTokenExpired.value) {
                 try {
@@ -275,6 +284,10 @@ export const useTokenStore = defineStore(
             }
             return getValidToken.value
         }
+        // 分享进入首页时,缓存分享参数
+        const cacheShareParams = (params: Record<string, string>) => {
+            uni.setStorageSync('shareParams', JSON.stringify(params))
+        }
 
         return {
             // 核心API方法
@@ -293,7 +306,8 @@ export const useTokenStore = defineStore(
             // 调试或特殊场景可能需要直接访问的信息
             tokenInfo,
             setTokenInfo,
-            cleanToken
+            cleanToken,
+            cacheShareParams
         }
     },
     {

+ 0 - 50
src/utils/shareMixin.ts

@@ -1,50 +0,0 @@
-import { useTokenStore } from '@/store/token'
-
-// 创建全局mixin
-export const shareMixin = {
-    onShareAppMessage() {
-        // 检查用户是否已登录
-        const tokenStore = useTokenStore()
-        if (!tokenStore.hasLogin) {
-            uni.showToast({
-                title: '请先登录后再分享',
-                icon: 'none',
-            })
-            return {
-                title: '',
-                path: '',
-                imageUrl: '',
-            }
-        }
-
-        console.log('全局分享给朋友拦截触发')
-        return {
-            title: '券中心',
-            path: '/pages/index/index',
-            imageUrl: '/static/logo.svg',
-        }
-    },
-
-    onShareTimeline() {
-        // 检查用户是否已登录
-        const tokenStore = useTokenStore()
-        if (!tokenStore.hasLogin) {
-            uni.showToast({
-                title: '请先登录后再分享',
-                icon: 'none',
-            })
-            return {
-                title: '',
-                path: '',
-                imageUrl: '',
-            }
-        }
-
-        console.log('全局分享到朋友圈拦截触发')
-        return {
-            title: '券中心',
-            path: '/pages/index/index',
-            imageUrl: '/static/logo.svg',
-        }
-    }
-}