feat(v3.4.13): partner column, version release cascade, client UX fixes
- HQ stores: partner column uses companyName/name/phone via partnerOptionLabel - Dev plan: version RELEASED auto-marks tasks RELEASED and tickets PUBLISHED with releasedVersionNo - mini-user/h5-shop/h5-partner v3.4.13 UX fixes (store UI, iOS scan OAuth, partner login guard) - Docs: v3.4.13 dev doc + status audit updates Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { View, Text, Image } from '@tarojs/components';
|
||||
import { View, Text, Image, ScrollView } from '@tarojs/components';
|
||||
import Taro, {
|
||||
useDidShow,
|
||||
useLoad,
|
||||
@@ -156,10 +156,14 @@ export default function StoreDetailPage() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [loadError, setLoadError] = useState('');
|
||||
const [headerSolid, setHeaderSolid] = useState(false);
|
||||
const [expandedPackages, setExpandedPackages] = useState<Record<number, boolean>>({});
|
||||
const [activePackageIndex, setActivePackageIndex] = useState(0);
|
||||
const storeRef = useRef<Store | null>(null);
|
||||
storeRef.current = store;
|
||||
|
||||
useEffect(() => {
|
||||
setActivePackageIndex(0);
|
||||
}, [store?.id]);
|
||||
|
||||
usePageScroll(({ scrollTop }) => {
|
||||
setHeaderSolid(scrollTop > 100);
|
||||
});
|
||||
@@ -321,6 +325,8 @@ export default function StoreDetailPage() {
|
||||
|
||||
const envPhotos = envPhotoUrls(store);
|
||||
const heroImages = uniqueUrls([store.coverUrl, ...(store.carouselUrls || [])]);
|
||||
const packages = store.packages ?? [];
|
||||
const activePackage = packages[activePackageIndex] ?? packages[0];
|
||||
|
||||
const intro = store.intro?.trim() || '';
|
||||
const benefitRuleRaw = store.benefitUsageRule?.trim() || '';
|
||||
@@ -402,44 +408,49 @@ export default function StoreDetailPage() {
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{store.packages && store.packages.length > 0 ? (
|
||||
<View className="store-detail-section">
|
||||
{packages.length > 0 && activePackage ? (
|
||||
<View className="store-detail-section store-detail-section--packages">
|
||||
<Text className="store-detail-section-title">门店套餐</Text>
|
||||
{store.packages.map((pkg, index) => {
|
||||
const expanded = !!expandedPackages[index];
|
||||
const bodyText = `${formatRedeemAmountYuan(pkg.price)} 元 · ${pkg.dishes}`;
|
||||
const longBody = bodyText.length > 48 || (pkg.otherNotes?.length ?? 0) > 40;
|
||||
return (
|
||||
<View
|
||||
key={`${pkg.name}-${index}`}
|
||||
className={`store-detail-package-card${expanded || !longBody ? '' : ' store-detail-package-card--collapsed'}`}
|
||||
>
|
||||
{pkg.imageUrl ? (
|
||||
<Image className="store-detail-package-img" src={pkg.imageUrl} mode="aspectFill" />
|
||||
) : null}
|
||||
<View className="store-detail-package-head">
|
||||
<Text className="store-detail-package-name">{pkg.name}</Text>
|
||||
{longBody ? (
|
||||
<Text
|
||||
className="store-detail-package-toggle"
|
||||
onClick={() =>
|
||||
setExpandedPackages((prev) => ({ ...prev, [index]: !prev[index] }))
|
||||
}
|
||||
{packages.length > 1 ? (
|
||||
<ScrollView className="store-detail-package-tabs" scrollX showScrollbar={false} enhanced>
|
||||
<View className="store-detail-package-tabs-inner">
|
||||
{packages.map((pkg, index) => (
|
||||
<View
|
||||
key={`${pkg.name}-${index}`}
|
||||
className={`store-detail-package-tab${
|
||||
index === activePackageIndex ? ' store-detail-package-tab--active' : ''
|
||||
}`}
|
||||
onClick={() => setActivePackageIndex(index)}
|
||||
>
|
||||
{expanded ? '收起' : '展开'}
|
||||
</Text>
|
||||
) : null}
|
||||
<Text className="store-detail-package-tab-text">{pkg.name}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
<Text className="store-detail-package-body">{bodyText}</Text>
|
||||
{pkg.usableTime ? (
|
||||
<Text className="store-detail-package-meta">使用时间:{pkg.usableTime}</Text>
|
||||
</ScrollView>
|
||||
) : null}
|
||||
<View className="store-detail-package-panel">
|
||||
{activePackage.imageUrl ? (
|
||||
<Image
|
||||
className="store-detail-package-thumb"
|
||||
src={activePackage.imageUrl}
|
||||
mode="aspectFill"
|
||||
/>
|
||||
) : null}
|
||||
<View className="store-detail-package-panel-body">
|
||||
{packages.length === 1 ? (
|
||||
<Text className="store-detail-package-name">{activePackage.name}</Text>
|
||||
) : null}
|
||||
{pkg.otherNotes ? (
|
||||
<Text className="store-detail-package-meta">说明:{pkg.otherNotes}</Text>
|
||||
<Text className="store-detail-package-body">
|
||||
{formatRedeemAmountYuan(activePackage.price)} 元 · {activePackage.dishes}
|
||||
</Text>
|
||||
{activePackage.usableTime ? (
|
||||
<Text className="store-detail-package-meta">使用时间:{activePackage.usableTime}</Text>
|
||||
) : null}
|
||||
{activePackage.otherNotes ? (
|
||||
<Text className="store-detail-package-meta">说明:{activePackage.otherNotes}</Text>
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user