分享功能和资质文件展示

This commit is contained in:
2026-07-28 00:31:31 +08:00
parent a49d8d99b6
commit 15c35c49de
7 changed files with 90 additions and 20 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 KiB

@@ -2,4 +2,6 @@ export default definePageConfig({
navigationBarTitleText: '我的',
enablePullDownRefresh: true,
backgroundTextStyle: 'dark',
enableShareAppMessage: true,
enableShareTimeline: true,
});
+32 -3
View File
@@ -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<boolean> {
if (profile?.hasWechat) return true;
if (!wxAuthorize) {
@@ -279,6 +300,7 @@ export default function MinePage() {
if (!authed) {
return (
<PageShell variant="tab" className="mine-page no-tab-header">
<WechatShareReady payload={sharePayload} />
<TabMainHeader title="我的" />
<View className="mine-header">
<View className="mine-header-texture" />
@@ -331,6 +353,7 @@ export default function MinePage() {
return (
<PageShell variant="tab" className="mine-page no-tab-header">
<WechatShareReady payload={sharePayload} />
<TabMainHeader title="我的" />
<View className="mine-header">
<View className="mine-header-texture" />
@@ -533,7 +556,13 @@ export default function MinePage() {
className="mine-qualification-mask"
onClick={() => setQualificationOpen(false)}
>
<ScrollView scrollY className="mine-qualification-scroll" enhanced showScrollbar>
<ScrollView
scrollY
className="mine-qualification-scroll"
style={{ height: '100%' }}
enhanced
showScrollbar
>
<Image
className="mine-qualification-img"
src={QUALIFICATION_DISCLOSURE_URL}
@@ -2,4 +2,6 @@ export default definePageConfig({
navigationBarTitleText: '门店',
enablePullDownRefresh: true,
backgroundTextStyle: 'dark',
enableShareAppMessage: true,
enableShareTimeline: true,
});
+23 -1
View File
@@ -1,8 +1,9 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import { View, Text, Image, Input } from '@tarojs/components';
import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro';
import Taro, { useDidShow, usePullDownRefresh, useShareAppMessage, useShareTimeline } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import TabMainHeader from '../../components/TabMainHeader';
import WechatShareReady from '../../components/WechatShareReady';
import RegionPicker from '../../components/RegionPicker';
import CategoryPicker, {
EMPTY_CATEGORY,
@@ -27,6 +28,11 @@ import {
import { FALLBACK_CITY_CODE } from '../../lib/product-images';
import { formatDistanceMeters } from '../../lib/geo';
import { request, toast } from '../../lib/api';
import {
DEFAULT_SHARE_DESC,
DEFAULT_SHARE_TITLE,
toWeappShareMessage,
} from '../../lib/wechat-share';
type Store = {
id: string;
@@ -176,8 +182,24 @@ export default function StoresPage() {
return parts.length ? `营业时间: ${parts.join('')}` : '营业时间: 10:00-22:00';
}
const sharePayload = useMemo(
() => ({
title: '杜康好客门店',
desc: DEFAULT_SHARE_DESC,
path: '/pages/stores/index',
}),
[],
);
useShareAppMessage(() => toWeappShareMessage(sharePayload));
useShareTimeline(() => ({
title: sharePayload.title || DEFAULT_SHARE_TITLE,
query: '',
}));
return (
<PageShell variant="tab" className="store-page no-tab-header">
<WechatShareReady payload={sharePayload} />
<TabMainHeader title="门店" />
<View className="store-filter">
+18 -9
View File
@@ -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;
}
@@ -1,9 +1,11 @@
/**
* 上传小程序「资质公示」静态图到 OSSstatic/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);