diff --git a/apps/mini-user/src/assets/qualification-disclosure.png b/apps/mini-user/src/assets/qualification-disclosure.png deleted file mode 100644 index d41c73a..0000000 Binary files a/apps/mini-user/src/assets/qualification-disclosure.png and /dev/null differ diff --git a/apps/mini-user/src/pages/mine/index.config.ts b/apps/mini-user/src/pages/mine/index.config.ts index 08e8af0..a41cf20 100644 --- a/apps/mini-user/src/pages/mine/index.config.ts +++ b/apps/mini-user/src/pages/mine/index.config.ts @@ -2,4 +2,6 @@ export default definePageConfig({ navigationBarTitleText: '我的', enablePullDownRefresh: true, backgroundTextStyle: 'dark', + enableShareAppMessage: true, + enableShareTimeline: true, }); diff --git a/apps/mini-user/src/pages/mine/index.tsx b/apps/mini-user/src/pages/mine/index.tsx index 5cc8bb1..92aaf6e 100644 --- a/apps/mini-user/src/pages/mine/index.tsx +++ b/apps/mini-user/src/pages/mine/index.tsx @@ -1,6 +1,6 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { View, Text, Image, Button, Input, ScrollView } from '@tarojs/components'; -import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro'; +import Taro, { useDidShow, usePullDownRefresh, useShareAppMessage, useShareTimeline } from '@tarojs/taro'; import { BRAND_LOGO_MARK_URL, QUALIFICATION_DISCLOSURE_URL, @@ -9,6 +9,7 @@ import { } from '@dukang/shared-types'; import PageShell from '../../components/PageShell'; import TabMainHeader from '../../components/TabMainHeader'; +import WechatShareReady from '../../components/WechatShareReady'; import UserTabBar, { shouldRenderPageTabBar, syncTabBarSelected } from '../../components/UserTabBar'; import { goLogin } from '../../lib/auth-nav'; import { bindWechatForUser } from '../../lib/wechat-auth'; @@ -22,6 +23,11 @@ import { } from '../../lib/mini-wechat-profile'; import { isLoggedIn, logout, request, toast, type UserProfile } from '../../lib/api'; import { isWechatEnv } from '../../lib/weixin'; +import { + DEFAULT_SHARE_DESC, + DEFAULT_SHARE_TITLE, + toWeappShareMessage, +} from '../../lib/wechat-share'; const ORDER_SHORTCUTS = [ { tab: 'pending_pay', icon: '付', label: '待付款' }, @@ -132,6 +138,21 @@ export default function MinePage() { .catch(() => setWxAuthorize(true)); }, []); + const sharePayload = useMemo( + () => ({ + title: '杜康好客 · 我的', + desc: DEFAULT_SHARE_DESC, + path: '/pages/mine/index', + }), + [], + ); + + useShareAppMessage(() => toWeappShareMessage(sharePayload)); + useShareTimeline(() => ({ + title: sharePayload.title || DEFAULT_SHARE_TITLE, + query: '', + })); + async function ensureWechatBound(): Promise { if (profile?.hasWechat) return true; if (!wxAuthorize) { @@ -279,6 +300,7 @@ export default function MinePage() { if (!authed) { return ( + @@ -331,6 +353,7 @@ export default function MinePage() { return ( + @@ -533,7 +556,13 @@ export default function MinePage() { className="mine-qualification-mask" onClick={() => setQualificationOpen(false)} > - + ({ + title: '杜康好客门店', + desc: DEFAULT_SHARE_DESC, + path: '/pages/stores/index', + }), + [], + ); + + useShareAppMessage(() => toWeappShareMessage(sharePayload)); + useShareTimeline(() => ({ + title: sharePayload.title || DEFAULT_SHARE_TITLE, + query: '', + })); + return ( + diff --git a/apps/mini-user/src/styles/mine.css b/apps/mini-user/src/styles/mine.css index ac484b9..922cf38 100644 --- a/apps/mini-user/src/styles/mine.css +++ b/apps/mini-user/src/styles/mine.css @@ -505,31 +505,40 @@ z-index: 1200; display: flex; flex-direction: column; - align-items: center; - justify-content: center; - gap: 10px; - padding: 24px 16px; - background: rgba(0, 0, 0, 0.72); + width: 100%; + height: 100%; + padding: 0; + margin: 0; + background: #000; box-sizing: border-box; } .mine-qualification-scroll { + flex: 1; width: 100%; - max-width: 420px; - max-height: calc(86vh - 36px); - border-radius: 8px; + height: 100%; + max-width: none; + max-height: none; + border-radius: 0; overflow: hidden; - background: #fff; + background: #000; } .mine-qualification-img { display: block; width: 100%; + min-height: 100%; pointer-events: none; } .mine-qualification-hint { + position: absolute; + left: 0; + right: 0; + bottom: calc(12px + env(safe-area-inset-bottom, 0px)); + z-index: 1; text-align: center; font-size: 12px; color: rgba(255, 255, 255, 0.82); + pointer-events: none; } diff --git a/server/dukang-api/scripts/upload-qualification-disclosure.mjs b/server/dukang-api/scripts/upload-qualification-disclosure.mjs index 6611a13..b038abc 100644 --- a/server/dukang-api/scripts/upload-qualification-disclosure.mjs +++ b/server/dukang-api/scripts/upload-qualification-disclosure.mjs @@ -1,9 +1,11 @@ /** * 上传小程序「资质公示」静态图到 OSS:static/mini-user/qualification-disclosure.png - * 用法(在 server/dukang-api): node scripts/upload-qualification-disclosure.mjs + * 用法(在 server/dukang-api): + * node scripts/upload-qualification-disclosure.mjs [本地 png 路径] + * 也可设环境变量 QUALIFICATION_DISCLOSURE_LOCAL。 */ import { readFileSync, existsSync } from 'fs'; -import { resolve, dirname } from 'path'; +import { resolve, dirname, isAbsolute } from 'path'; import { fileURLToPath } from 'url'; import { createRequire } from 'module'; @@ -12,7 +14,6 @@ const OSS = require('ali-oss'); const __dirname = dirname(fileURLToPath(import.meta.url)); const apiRoot = resolve(__dirname, '..'); -const repoRoot = resolve(apiRoot, '../..'); function loadEnvFile(path) { if (!existsSync(path)) return {}; @@ -49,10 +50,15 @@ if (!accessKeyId || !accessKeySecret || !bucket) { process.exit(1); } -const localFile = resolve( - repoRoot, - 'apps/mini-user/src/assets/qualification-disclosure.png', -); +const argPath = process.argv[2]?.trim() || env.QUALIFICATION_DISCLOSURE_LOCAL?.trim() || ''; +if (!argPath) { + console.error( + '请传入本地 png 路径,例如:\n node scripts/upload-qualification-disclosure.mjs D:/tmp/qualification-disclosure.png', + ); + process.exit(1); +} + +const localFile = isAbsolute(argPath) ? argPath : resolve(process.cwd(), argPath); if (!existsSync(localFile)) { console.error('本地文件不存在:', localFile); process.exit(1);