feat(assoc): v4.0.1 合伙人关联码、分佣账单与 H5 用户管理

订单佣金只认关联用户;合伙人备注写入独立表;H5 增加用户管理与首页统计。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-30 14:35:39 +08:00
parent 3b669f7e38
commit 9c8d5f2cad
125 changed files with 6355 additions and 1436 deletions
+38 -3
View File
@@ -9,10 +9,13 @@ import Taro, {
} from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import TabMainHeader from '../../components/TabMainHeader';
import CouponBadge from '../../components/CouponBadge';
import BenefitSloganBar from '../../components/BenefitSloganBar';
import { BENEFIT_GIFT_TAG, BENEFIT_TAG } from '../../lib/benefit-copy';
import WechatShareReady from '../../components/WechatShareReady';
import UserTabBar, { shouldRenderPageTabBar, syncTabBarSelected } from '../../components/UserTabBar';
import JiuzuSplash from '../../components/JiuzuSplash';
import { goLogin } from '../../lib/auth-nav';
import { hasJiuzuSplashPlayed } from '../../lib/jiuzu-splash';
import { getToken, isLoggedIn, request, toast } from '../../lib/api';
import {
getHomeCatalogCache,
@@ -36,6 +39,7 @@ import {
toWeappShareTimeline,
} from '../../lib/wechat-share';
import { trackPageView } from '../../lib/analytics';
import iconStoreBenefit from '../../assets/icons/store-benefit-y.png';
type Product = {
id: string;
name: string;
@@ -71,7 +75,15 @@ function aromaSectionId(key: AromaKey) {
return `aroma-section-${key}`;
}
/** 商品图左上角权益角标:权益额 = benefitDisplay ?? price */
function formatBenefitCorner(p: Product): string {
const n = Number(p.benefitDisplay ?? p.price);
if (!Number.isFinite(n) || n <= 0) return '';
return String(Math.round(n));
}
export default function HomePage() {
const [showSplash, setShowSplash] = useState(() => !hasJiuzuSplashPlayed());
const [activeAroma, setActiveAroma] = useState<AromaKey>('QINGXIANG');
const [products, setProducts] = useState<Product[]>([]);
const [loading, setLoading] = useState(true);
@@ -282,6 +294,7 @@ export default function HomePage() {
function renderProductCard(p: Product) {
const thumb = getProductMainImage(p);
const spec = p.subtitle || p.spec || '';
const benefitCorner = formatBenefitCorner(p);
return (
<View key={p.id} className="home-product-card">
<View className="home-product-card-inner" onClick={() => openProductDetail(p.id)}>
@@ -291,6 +304,20 @@ export default function HomePage() {
) : (
<View className="home-product-thumb home-product-thumb--empty" />
)}
{benefitCorner ? (
<View className="home-benefit-ribbon-clip">
<View className="home-benefit-ribbon">
<View className="home-benefit-ribbon-dk">
<Image
className="home-benefit-ribbon-dk-icon"
src={iconStoreBenefit}
mode="aspectFit"
/>
</View>
<Text className="home-benefit-ribbon-num">{benefitCorner}</Text>
</View>
</View>
) : null}
</View>
<View className="home-product-main">
<View className="home-product-row">
@@ -299,7 +326,10 @@ export default function HomePage() {
</View>
{spec ? <Text className="home-product-sub">{spec}</Text> : null}
<View className="home-product-footer">
<CouponBadge amount={p.benefitDisplay ?? p.price} label="好客权益" />
<View className="home-product-tags">
<Text className="home-gift-tag">{BENEFIT_GIFT_TAG}</Text>
{/* <Text className="home-benefit-tag">{BENEFIT_TAG}</Text> */}
</View>
</View>
<View className="home-product-actions">
{canPickupOnSite(p) ? (
@@ -354,6 +384,10 @@ export default function HomePage() {
</View>
) : null}
<View className="home-slogan-wrap">
<BenefitSloganBar />
</View>
<View className="home-aroma-nav">
<View className="home-aroma-tabs">
{visibleAromaTabs.map((t) => (
@@ -393,7 +427,8 @@ export default function HomePage() {
</View>
) : null}
{shouldRenderPageTabBar() ? <UserTabBar selected={0} /> : null}
{shouldRenderPageTabBar() && !showSplash ? <UserTabBar selected={0} /> : null}
{showSplash ? <JiuzuSplash onDone={() => setShowSplash(false)} /> : null}
</PageShell>
);
}