<template>
  <view class="page-container">
    <!-- 顶部背景装饰 -->
    <view class="bg-decoration"></view>

    <!-- 自定义 tabBar (仅抖音小程序) -->
    <!-- #ifdef MP-TOUTIAO -->
    <customTabBarToutiao />
    <!-- #endif -->

    <!-- 头部区域 -->
    <view class="header-section">
      <view class="user-info-card glass-card">
        <view class="user-main">
          <view class="avatar-wrapper" @click="handleEditAvatar" v-if="nickname">
            <image class="avatar" :src="avatar || '/static/logo.png'" mode="aspectFill"></image>
            <view class="avatar-edit-badge">
              <text class="edit-icon">📷</text>
            </view>
          </view>
          <image v-else class="avatar" :src="avatar || '/static/logo.png'" mode="aspectFill"></image>
          <view class="user-meta">
            <view class="name-row" @click="handleEditNickname" v-if="nickname">
              <text class="nickname">{{ nickname || '未登录' }}</text>
              <text class="edit-nickname-icon">✏️</text>
              <view class="level-badge" v-if="title">
                <image class="level-icon" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRjZCMDAiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNNiAzSDE4TDIxIDlMOSAyMSAzIDlMNiAzWiIgLz48L3N2Zz4=" mode="aspectFit"></image>
                <text class="level-text">Lv1 {{ title }}</text>
              </view>
            </view>
            <view class="name-row" v-else>
              <text class="nickname">{{ nickname || '未登录' }}</text>
              <view class="level-badge" v-if="title">
                <image class="level-icon" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRjZCMDAiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNNiAzSDE4TDIxIDlMOSAyMSAzIDlMNiAzWiIgLz48L3N2Zz4=" mode="aspectFit"></image>
                <text class="level-text">Lv1 {{ title }}</text>
              </view>
            </view>
            <!-- 绑定的抖音号 -->
            <view class="douyin-id-row" v-if="douyinUserId">
              <text class="douyin-id-label">抖音号：</text>
              <text class="douyin-id-value">{{ douyinUserId }}</text>
            </view>
            <view class="userid" v-if="userId">ID: {{ userId }}</view>
            <!-- <view class="progress-container" v-if="nickname">
              <view class="progress-bar">
                <view class="progress-fill" style="width: 20%;"></view>
              </view>
              <text class="progress-text">100/5000 升级Lv2</text>
            </view> -->
            <!-- <view class="userid" v-else>ID: {{ userId || '-' }}</view> -->
          </view>
          <view class="join-btn" @click="handleJoin" v-if="!nickname">立即登录</view>
        </view>
        
        <!-- 数据统计栏 -->
        <view class="stats-row">
          <view class="stat-item" @click="toPointsPage">
            <text class="stat-num">{{ formatPoints(pointsBalance) }}</text>
            <text class="stat-label">积分</text>
          </view>
          <view class="stat-divider"></view>
          <view class="stat-item" @click="toCouponsPage">
            <text class="stat-num">{{ stats.coupon_count || 0 }}</text>
            <text class="stat-label">优惠券</text>
          </view>
          <view class="stat-divider"></view>
          <view class="stat-item" @click="toItemCardsPage">
            <text class="stat-num">{{ stats.item_card_count || 0 }}</text>
            <text class="stat-label">道具卡</text>
          </view>
        </view>
      </view>
    </view>

    <!-- #ifdef MP-WEIXIN -->
    <view class="invite-banner glass-card">
      <view class="invite-content">
        <view class="invite-text-group">
          <view class="invite-title-row">
            <text class="invite-tag">好礼相送</text>
            <text class="invite-title">邀请好友送好礼</text>
          </view>
          <text class="invite-desc" @tap="copyInviteCode">我的邀请码：{{ getInviteCode() || '-' }}（点击复制）</text>
        </view>
        <button class="invite-action-btn invite-share-btn" open-type="share">
          <image class="invite-share-icon" src="/static/logo.png" mode="aspectFit"></image>
          <text>立即邀请</text>
          <text class="invite-arrow">›</text>
        </button>
      </view>
      <image class="invite-bg-icon" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRjZCMDAiIHN0cm9rZS13aWR0aD0iMSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMjEgMTF2OGEyIDIgMCAwIDEtMiAySDVhMiAyIDAgMCAwIDEtMiAyVjdsOS02IDkgNnoiIC8+PC9zdmc+" mode="aspectFit"></image>
    </view>
    <!-- #endif -->

    <!-- 我的订单 -->
    <view class="section-card glass-card">
      <view class="section-header">
        <text class="section-title">我的订单</text>
        <text class="section-more" @click="toOrders('all')">全部订单 ›</text>
      </view>
      <view class="grid-row">
        <!-- 1. 待付款 -->
        <view class="grid-item" @click="toOrders('pending')">
          <view class="icon-wrapper">
             <image class="grid-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRjZCMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHg9IjEiIHk9IjQiIHdpZHRoPSIyMiIgaGVpZ2h0PSIxNiIgcng9IjIiIHJ5PSIyIj48L3JlY3Q+PGxpbmUgeDE9IjEiIHkxPSIxMCIgeDI9IjIzIiB5Mj0iMTAiPjwvbGluZT48L3N2Zz4=" mode="aspectFit"></image>
          </view>
          <text class="grid-label">待付款</text>
        </view>
        <!-- 2. 待发货 (Jump to Cabinet Tab 1) -->
        <view class="grid-item" @click="toCabinetTab(1)">
          <view class="icon-wrapper">
            <image class="grid-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRjZCMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xMiAyMmg1LjlhMiAyIDAgMCAwIDEuOS0xLjQybDMuMTMtMTEuMDlhMiAyIDAgMCAwLTEuOS0yLjUxaC00LjE2IiAvPjxwYXRoIGQ9Ik0xOC40MiA5aC02LjMyIiAvPjxwYXRoIGQ9Ik0xNSA2VjNhMSAxIDAgMCAwLTEtMUg2YTEgMSAwIDAgMC0xIDF2MTQiIC8+PHBhdGggZD0iTTkgMTNoNyIgLz48L3N2Zz4=" mode="aspectFit"></image>
          </view>
          <text class="grid-label">待发货</text>
        </view>
        <!-- 3. 已发货 (Jump to Cabinet Tab 1) -->
        <view class="grid-item" @click="toCabinetTab(1)">
          <view class="icon-wrapper">
            <image class="grid-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRjZCMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHg9IjEiIHk9IjMiIHdpZHRoPSIxNSIgaGVpZ2h0PSIxMyIgcng9IjIiIHJ5PSIyIj48L3JlY3Q+PHBvbHlsaW5lIHBvaW50cz0iMTYgOCAyMCA4IDIwIDIxIDIgMjEgMiAxNiA2IDE2IiAvPjwvc3ZnPg==" mode="aspectFit"></image>
          </view>
          <text class="grid-label">已发货</text>
        </view>
        <!-- 4. 全部订单 (Was Box Cabinet) -->
        <view class="grid-item" @click="toOrders('completed')">
          <view class="icon-wrapper">
             <image class="grid-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRjZCMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMSA4YTIgMiAwIDAgMC0xLTEuNzNsLTctNGEyIDIgMCAwIDAtMiAwbC03IDRBMiAyIDAgMCAwIDMgOHY4YTIgMiAwIDAgMCAxIDEuNzNsNyA0YTIgMiAwIDAgMCAyIDBsNy00QTIgMiAwIDAgMCAyMSAxNlY4eiIvPjxwYXRoIGQ9Ik0zLjI3IDYuOTZMMTIgMTIuMDFsMTAgLTUuMDUiLz48cGF0aCBkPSJNMTIgMjIuMDhWMTIiLz48L3N2Zz4=" mode="aspectFit"></image>
          </view>
          <text class="grid-label">全部订单</text>
        </view>
      </view>
    </view>
    
    <!-- 功能菜单 -->
    <view class="section-card glass-card">
      <view class="section-header">
        <text class="section-title">常用功能</text>
      </view>
      <view class="grid-menu">
        <view class="menu-item" @click="toCouponsPage">
          <view class="menu-icon-box">
             <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMSA2SDNhMiAyIDAgMCAwLTIgMnY4YTIgMiAwIDAgMCAyIDJoMThhMiAyIDAgMCAwIDItMnYtOGEyIDIgMCAwIDAtMi0yWiIgLz48cGF0aCBkPSJNNiAxMnYtMiIgLz48cGF0aCBkPSJNNiAxNnYtMiIgLz48cGF0aCBkPSJNMTYgNnYxMiIgLz48L3N2Zz4=" mode="aspectFit"></image>
          </view>
          <text class="menu-label">优惠券</text>
        </view>
        <view class="menu-item" @click="toItemCardsPage">
          <view class="menu-icon-box">
            <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHg9IjMiIHk9IjMiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgcng9IjIiIHJ5PSIyIj48L3JlY3Q+PGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iNCIgLz48cGF0aCBkPSJNMjEgMTVsLTUuNDMtMy4yM2EyIDIgMCAwIDAtMS44NCAwbC0yLjMxIDEuMzciIC8+PC9zdmc+" mode="aspectFit"></image>
          </view>
          <text class="menu-label">道具卡</text>
        </view>
        <view class="menu-item" @click="toTasksPage">
          <view class="menu-icon-box">
            <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik05IDExbDMgM0wyMiA0Ii8+PHBhdGggZD0iTTIxIDEydjdhMiAyIDAgMCAxLTIgMkg1YTIgMiAwIDAgMS0yLTJWNWEyIDIgMCAwIDEgMi0yaDExIi8+PC9zdmc+" mode="aspectFit"></image>
          </view>
          <text class="menu-label">任务中心</text>
        </view>
        <view class="menu-item" @click="toInvitesPage">
          <view class="menu-icon-box">
             <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xNyAyMXYtMmE0IDQgMCAwIDAtNC00SDdhNCA0IDAgMCAwLTQgNHYyIj48L3BhdGg+PGNpcmNsZSBjeD0iMTAiIGN5PSI3IiByPSI0Ij48L2NpcmNsZT48cGF0aCBkPSJNMjMgMjF2LTJhNCA0IDAgMCAwLTMtMy4yNyI+PC9wYXRoPjxwYXRoIGQ9Ik0xNiAzLjEzYTQgNCAwIDAgMSAwIDcuNzUiPjwvcGF0aD48L3N2Zz4=" mode="aspectFit"></image>
          </view>
          <text class="menu-label">邀请记录</text>
        </view>
        <view class="menu-item" @click="toAddresses">
          <view class="menu-icon-box">
             <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMSAxMGMwIDctOSAxMy05IDEzcy05LTYtOS0xM2E5IDkgMCAwIDEgMTggMHoiIC8+PGNpcmNsZSBjeD0iMTIiIGN5PSIxMCIgcj0iMyIgLz48L3N2Zz4=" mode="aspectFit"></image>
          </view>
          <text class="menu-label">收货地址</text>
        </view>
         <view class="menu-item" @click="toHelp">
            <view class="menu-icon-box">
              <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjEwIi8+PHBhdGggZD0iTTkuMDkgOWEzIDMgMCAwIDEgNS44MyAxYzAgMi0zIDMtMyAzIi8+PHBhdGggZD0iTTEyIDE3aC4wMSIvPjwvc3ZnPg==" mode="aspectFit"></image>
            </view>
            <text class="menu-label">帮助中心</text>
         </view>
         <view class="menu-item" @click="toBindDouyinOrder">
            <view class="menu-icon-box">
              <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik05IDExVjlhMyAzIDAgMCAxIDMtM2g0YTMgMyAwIDAgMSAzIDN2Mm0tMTAtM2gtNGEzIDMgMCAwIDAtMyAzdi04YTIgMiAwIDAgMSAyLTJoMTRhMiAyIDAgMCAxIDIgMnY4YTIgMiAwIDAgMS0yIDJoLTRhMyAzIDAgMCAxLTMtM3oiLz48Y2lyY2xlIGN4PSIxMiIgY3k9IjEzIiByPSIzIi8+PC9zdmc+" mode="aspectFit"></image>
            </view>
            <text class="menu-label">{{ douyinUserId ? '已绑定' : '绑定抖音' }}</text>
         </view>
         <view class="menu-item" @click="handleSyncDouyinOrders">
            <view class="menu-icon-box">
              <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMSAxMmE5IDkgMCAxIDEtMi42NC02LjM2Ii8+PHBvbHlsaW5lIHBvaW50cz0iMjEgMyAyMSA5IDE1IDkiLz48cGF0aCBkPSJNMyAxMmE5IDkgMCAxIDAgMi42NCA2LjM2Ii8+PHBvbHlsaW5lIHBvaW50cz0iMyAyMSAzIDE1IDkgMTUiLz48L3N2Zz4=" mode="aspectFit"></image>
            </view>
            <text class="menu-label">{{ douyinSyncing ? '同步中...' : '同步订单' }}</text>
         </view>
         <!-- #ifdef MP-TOUTIAO -->

         <button
           open-type="im"
           :data-im-id="customerServiceId"
           @im="onImCallback"
           @error="onImError"
           class="menu-item customer-service-btn"
         >
            <view class="menu-icon-box">
              <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMSAxNWMwIDMtMyA1LTMgNXMtNS0yLTUtNXYtNGEzIDMgMCAwIDEgMy0zaDRhMyAzIDAgMCAxIDMgM3Y0eiIvPjxwYXRoIGQ9Ik0zIDdoMThhMiAyIDAgMCAwIDItMnY1YTIgMiAwIDAgMS0yIDJINGEyIDMgMCAwIDEtMi0ydjVhMiAyIDAgMCAxIDIgMnoiLz48cGF0aCBkPSJNMTIgMTF2NiIvPjxwYXRoIGQ9Ik05IDE0aDZtLTMgM2g2Ii8+PC9zdmc+" mode="aspectFit"></image>
            </view>
            <text class="menu-label">联系抖店客服</text>
         </button>
         <!-- #endif -->
         <!-- #ifdef MP-TOUTIAO -->
         <view class="menu-item" @click="toMinesweeper">
            <view class="menu-icon-box">
              <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xMCAxNGwtNiA2Ii8+PHBhdGggZD0iTTE0IDEwbDYgLTYiLz48cGF0aCBkPSJNMTEuNSAxMmwzIDNsLTMgM2wtMy0zeiIvPjxwYXRoIGQ9Ik0xMCAxNGw2IDZtLTItMmwtNiA2bTYtNjYgNm0tMi0ybDItMiIvPjwvc3ZnPg==" mode="aspectFit"></image>
            </view>
            <text class="menu-label">扫雷</text>
         </view>
         <!-- #endif -->

         <view class="menu-item" @click="toSettings">
            <view class="menu-icon-box">
              <image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjMiLz48cGF0aCBkPSJNMTIgMTV2M20wLTZ2MyIvPjxwYXRoIGQ9Ik0xOS40IDE1YTEsMSAwIDAsMC0uMTc4LjM4OWwtMTAuNSA3LjJhMSwxIDAsMCwwLTEuMTg5LS4xODlsLTQuNS04LjVhMSwxIDAsMCwwIC4xNzgtMS4xODlsOC41LTQuNWExLDEgMCAwLDEgLjM4OS4xNzhsNC41IDguNTE5YTEsMSAwIDAsMC0uMTc4LjM4OXoiLz48L3N2Zz4=" mode="aspectFit"></image>
            </view>
            <text class="menu-label">设置</text>
         </view>
      </view>
    </view>

    <!-- 弹窗组件保持原有逻辑 -->
    <!-- 积分明细弹窗 -->
    <view class="popup-mask" v-if="pointsVisible" @tap="closePointsPopup">
      <view class="popup-content" @tap.stop>
        <view class="popup-header">
          <text class="popup-title">积分明细</text>
          <text class="close-btn" @tap="closePointsPopup">×</text>
        </view>
        
        <scroll-view scroll-y class="points-list" @scrolltolower="loadMorePoints">
          <view v-if="pointsLoading && pointsList.length === 0" class="status-text">加载中...</view>
          <view v-else-if="!pointsList || pointsList.length === 0" class="status-text">暂无积分记录</view>
          
          <view v-for="(item, index) in pointsList" :key="index" class="point-item">
            <view class="point-left">
              <text class="point-desc">{{ getActionText(item.action) }}</text>
              <text class="point-time">{{ formatDate(item.created_at) }}</text>
            </view>
            <view class="point-right">
              <text class="point-amount" :class="{ 'positive': Number(item.points) > 0, 'negative': Number(item.points) < 0 }">
                {{ Number(item.points) > 0 ? '+' : '' }}{{ formatPoints(item.points) }}
              </text>
            </view>
          </view>
          
          <view v-if="pointsLoading && pointsList.length > 0" class="loading-more">加载更多...</view>
          <view v-if="!pointsHasMore && pointsList.length > 0" class="no-more">没有更多了</view>
        </scroll-view>
      </view>
    </view>

    <!-- 优惠券弹窗 -->
    <view class="popup-mask" v-if="couponsVisible" @tap="closeCouponsPopup">
      <view class="popup-content coupon-popup" @tap.stop>
        <view class="popup-header">
          <text class="popup-title">我的优惠券</text>
          <text class="close-btn" @tap="closeCouponsPopup">×</text>
        </view>
        
        <view class="popup-tabs coupon-tabs-2">
          <view class="popup-tab" :class="{ active: couponsTab === 1 }" @tap="switchCouponsTab(1)">有效</view>
          <view class="popup-tab" :class="{ active: couponsTab === 2 }" @tap="switchCouponsTab(2)">已失效</view>
        </view>
        
        <scroll-view scroll-y class="coupon-scroll" @scrolltolower="loadMoreCoupons">
          <view v-if="couponsLoading && couponsList.length === 0" class="status-text">加载中...</view>
          <view v-else-if="!couponsList || couponsList.length === 0" class="empty-state">
            <text class="empty-icon">🎟️</text>
            <text class="empty-text">{{ getCouponEmptyText() }}</text>
          </view>
          
          <view v-for="(item, index) in couponsList" :key="item.id || index" class="coupon-ticket-v2" :class="getCouponCardClass(item)">
            <!-- 左侧金额区域 -->
            <view class="coupon-left-v2">
              <view class="coupon-remaining">
                <text class="coupon-symbol">¥</text>
                <text class="coupon-amount-num">{{ formatCouponValue(item.remaining ?? item.amount ?? 0) }}</text>
              </view>
              <text class="coupon-label" :class="getCouponLabelClass(item)">{{ item.status_desc || '可用' }}</text>
            </view>
            
            <!-- 中间分割线 -->
            <view class="coupon-divider-v2">
              <view class="divider-notch top"></view>
              <view class="divider-dash"></view>
              <view class="divider-notch bottom"></view>
            </view>
            
            <!-- 右侧信息区域 -->
            <view class="coupon-right-v2">
              <view class="coupon-header-row">
                <text class="coupon-name-v2">{{ item.name || '优惠券' }}</text>
                <view class="coupon-original" v-if="item.amount && item.remaining !== undefined && item.remaining !== item.amount">
                  <text>原值 ¥{{ formatCouponValue(item.amount) }}</text>
                </view>
              </view>
              
              <text class="coupon-rules">{{ formatCouponRules(item.rules) }}</text>
              
              <!-- 使用进度条 (仅当有使用记录时显示) -->
              <view class="coupon-progress-wrap" v-if="item.amount && item.remaining !== undefined && item.remaining < item.amount">
                <view class="coupon-progress-bar">
                  <view class="coupon-progress-fill" :style="{ width: getCouponUsedPercent(item) + '%' }"></view>
                </view>
                <text class="coupon-progress-text">已用 {{ formatCouponValue(item.amount - item.remaining) }} ({{ getCouponUsedPercent(item) }}%)</text>
              </view>
              
              <view class="coupon-footer-row">
                <view class="coupon-footer-left">
                  <text class="coupon-expire-v2">{{ formatCouponExpiry(item) }}</text>
                  <!-- 使用时间 (已使用状态) -->
                  <text class="coupon-used-time" v-if="couponsTab === 2 && item.used_at">使用时间：{{ formatDateTime(item.used_at) }}</text>
                </view>
                
                <view class="coupon-action-v2" v-if="couponsTab === 1">
                  <view class="use-btn-v2">去使用</view>
                </view>
                <view class="coupon-status-v2" v-else>
                  <text class="status-tag" :class="getCouponStatusTagClass(item)">{{ item.status_desc || '已失效' }}</text>
                </view>
              </view>
            </view>
          </view>
          
          <view v-if="couponsLoading && couponsList.length > 0" class="loading-more">加载更多...</view>
          <view v-if="!couponsHasMore && couponsList.length > 0" class="no-more">没有更多了</view>
        </scroll-view>
      </view>
    </view>

    <!-- 道具卡弹窗 -->
    <view class="popup-mask" v-if="itemCardsVisible" @tap="closeItemCardsPopup">
      <view class="popup-content item-cards-popup" @tap.stop>
        <view class="popup-header">
          <text class="popup-title">我的道具卡</text>
          <text class="close-btn" @tap="closeItemCardsPopup">×</text>
        </view>
        
        <view class="popup-tabs">
          <view class="popup-tab" :class="{ active: itemCardsTab === 0 }" @tap="switchItemCardsTab(0)">未使用</view>
          <view class="popup-tab" :class="{ active: itemCardsTab === 1 }" @tap="switchItemCardsTab(1)">已使用</view>
        </view>
        
        <scroll-view scroll-y class="item-cards-scroll">
          <view v-if="itemCardsLoading && itemCardsList.length === 0" class="status-text">加载中...</view>
          <view v-else-if="!itemCardsList || itemCardsList.length === 0" class="empty-state">
            <text class="empty-icon">🃏</text>
            <text class="empty-text">{{ itemCardsTab === 0 ? '暂无可用道具卡' : '暂无使用记录' }}</text>
          </view>
          
          <view class="item-cards-grid">
            <view v-for="(item, index) in itemCardsList" :key="index" class="item-card" :class="{ 'used': itemCardsTab === 1 }">
              <view class="card-icon-wrap">
                <text class="card-icon">{{ getCardIcon(item.type || item.name) }}</text>
              </view>
              <view class="card-info">
                <text class="card-name">{{ item.name || item.title || '道具卡' }}</text>
                <text class="card-desc">{{ item.description || item.rules || '可在抽奖时使用' }}</text>
                <text class="card-use-time" v-if="itemCardsTab === 1 && item.used_at">使用时间：{{ formatDateTimeSeconds(item.used_at) }}</text>
              </view>
              <view class="card-count-badge" v-if="itemCardsTab === 0">
                <text class="count-num">×{{ item.remaining ?? item.count ?? 1 }}</text>
              </view>
              <view class="card-used-badge" v-else>
                <text class="used-text">已使用</text>
              </view>
            </view>
          </view>
        </scroll-view>
      </view>
    </view>
    
    <!-- 任务中心弹窗 -->
    <view class="popup-mask" v-if="tasksVisible" @tap="closeTasksPopup">
      <view class="popup-content task-center-popup" @tap.stop>
        <view class="popup-header">
          <text class="popup-title">任务中心</text>
          <text class="close-btn" @tap="closeTasksPopup">×</text>
        </view>
        
        <view class="task-hero">
          <view class="hero-top">
            <view class="hero-left">
              <text class="hero-title">总完成率</text>
              <view class="hero-percent-row">
                <text class="hero-percent">{{ getOverallProgress() }}</text>
                <text class="hero-percent-unit">%</text>
              </view>
              <view class="hero-progress">
                <view class="hero-progress-fill" :style="{ width: getOverallProgress() + '%' }"></view>
              </view>
            </view>
            <view class="hero-right">
              <view class="hero-chip done">
                <text class="chip-num">{{ tasksStats.done }}</text>
                <text class="chip-label">已完成</text>
              </view>
              <view class="hero-chip ongoing">
                <text class="chip-num">{{ tasksStats.ongoing }}</text>
                <text class="chip-label">进行中</text>
              </view>
              <view class="hero-chip waiting">
                <text class="chip-num">{{ tasksStats.waiting }}</text>
                <text class="chip-label">未开始</text>
              </view>
            </view>
          </view>
        </view>
        
        <scroll-view scroll-y class="task-list-scroll">
           <view v-if="tasksLoading" class="task-skeleton-list">
             <view v-for="i in 3" :key="i" class="task-skeleton">
               <view class="sk-left">
                 <view class="sk-icon"></view>
                 <view class="sk-text">
                   <view class="sk-line sk-line-title"></view>
                   <view class="sk-line sk-line-desc"></view>
                 </view>
               </view>
               <view class="sk-btn"></view>
             </view>
           </view>
           <view v-else-if="!tasksList.length" class="empty-state">
             <text class="empty-icon">📝</text>
             <text class="empty-text">暂无任务</text>
           </view>
           
           <view v-for="(task, index) in tasksList" :key="index" class="task-card" :class="getTaskClass(task)">
             <view class="task-card-left">
               <view class="task-icon-bubble" :class="getTaskClass(task)">
                 <text class="task-icon">{{ getTaskIcon(task.type || task.title || task.name) }}</text>
               </view>
               <view class="task-text">
                 <view class="task-title-row">
                   <text class="task-name">{{ task.title }}</text>
                   <text class="task-status-tag" :class="getTaskClass(task)">{{ getTaskStatusText(task) }}</text>
                 </view>
                 <text class="task-desc">{{ task.description }}</text>
                <view class="task-meta">
                  <view class="task-reward-chip" v-if="task.reward">
                    <text class="reward-icon">🏆</text>
                    <text class="reward-text">{{ task.reward }}</text>
                  </view>
                  <view class="task-progress-wrap">
                    <view class="task-progress-bar">
                      <view class="task-progress-fill" :class="getTaskClass(task)" :style="{ width: getTaskProgress(task).percent + '%' }"></view>
                    </view>
                    <text class="task-progress-text">{{ getTaskProgressText(task) }}</text>
                  </view>
                </view>
               </view>
             </view>
             <view class="task-card-right">
               <view class="task-action-btn" :class="getTaskClass(task)" @tap="handleTask(task)">
                 {{ getTaskBtnText(task) }}
               </view>
             </view>
           </view>
        </scroll-view>
      </view>
    </view>
    
    <!-- 邀请记录弹窗 -->
    <view class="popup-mask" v-if="invitesVisible" @tap="closeInvitesPopup">
       <view class="popup-content" @tap.stop>
         <view class="popup-header">
           <text class="popup-title">我的邀请</text>
           <text class="close-btn" @tap="closeInvitesPopup">×</text>
         </view>
         <view class="invite-summary">
           <view class="summary-item">
             <text class="summary-num">{{ invitesList.length }}</text>
             <text class="summary-label">邀请人数</text>
           </view>
           <view class="summary-item">
             <text class="summary-num">{{ getInviteRewardsTotal() }}</text>
             <text class="summary-label">累计奖励</text>
           </view>
         </view>
         <scroll-view scroll-y class="invite-list-scroll">
           <view v-if="invitesLoading" class="status-text">加载中...</view>
           <view v-else-if="!invitesList.length" class="empty-state">
             <text class="empty-icon">👥</text>
             <text class="empty-text">暂无邀请记录</text>
           </view>
           <view v-for="(item, index) in invitesList" :key="index" class="invite-item">
             <image class="invite-avatar" :src="item.avatar || '/static/logo.png'" mode="aspectFill"></image>
             <view class="invite-info">
               <text class="invite-name">{{ item.nickname || '用户' + item.id }}</text>
               <text class="invite-time">{{ formatDate(item.created_at) }}</text>
             </view>
             <view class="invite-status">已邀请</view>
           </view>
         </scroll-view>
       </view>
    </view>

  </view>
</template>

<script>
import {
  getUserInfo, getUserStats, getPointsBalance, getUserPoints, getUserCoupons, getItemCards,
  getUserTasks, getTaskProgress, getInviteRecords, modifyUser, getUserProfile, bindDouyinID, syncMyDouyinOrders, getPublicConfig
} from '../../api/appUser.js'
// #ifdef MP-TOUTIAO
import customTabBarToutiao from '@/components/app-tab-bar-toutiao.vue'
// #endif

export default {
  components: {
    // #ifdef MP-TOUTIAO
    customTabBarToutiao,
    // #endif
  },
  data() {
    return {
      userId: '',
      nickname: '',
      avatar: '',
      title: '', // 用户头衔
      inviteCode: '',
      inviterId: 0,
      inviterNickname: '',
      inviterAvatar: '',
      
      mobile: '', // 手机号
      douyinUserId: '', // 抖音用户ID
      douyinSyncing: false,
      customerServiceQrCode: '', // 客服二维码
      customerServiceId: '0071112x', // 抖音IM客服账号
      pointsBalance: 0,
      
      stats: {
        coupon_count: 0,
        item_card_count: 0,
        pending_payment: 0,
        pending_shipment: 0,
        shipped: 0
      },
      
      // Points Popup
      pointsVisible: false,
      pointsList: [],
      pointsPage: 1,
      pointsLoading: false,
      pointsHasMore: true,
      
      // Coupons Popup
      couponsVisible: false,
      couponsList: [],
      couponsTab: 1, // 1=unused, 2=used, 3=expired
      couponsPage: 1,
      couponsLoading: false,
      couponsHasMore: true,

      // Item Cards Popup
      itemCardsVisible: false,
      itemCardsList: [],
      itemCardsTab: 0, // 0=unused, 1=used
      itemCardsLoading: false,
      
      // Tasks Popup
      tasksVisible: false,
      tasksList: [],
      tasksLoading: false,
      tasksStats: { done: 0, ongoing: 0, waiting: 0 },
      tasksProgressMap: {},
      
      // Invites Popup
      invitesVisible: false,
      invitesList: [],
      invitesLoading: false
    }
  },
  onLoad(opts) {
    const code = (opts && (opts.invite_code || opts.inviteCode)) || ''
    const v = String(code || '').trim()
    if (v) {
      try { uni.setStorageSync('inviter_code', v) } catch (_) {}
      const token = uni.getStorageSync('token')
      if (!token) {
        uni.navigateTo({ url: '/pages/login/index' })
      }
    }

    
    // 获取公共配置（客服二维码）
    getPublicConfig().then(res => {
      if (res && res.contact_service_qrcode) {
        this.customerServiceQrCode = res.contact_service_qrcode
      }
    }).catch(console.error)
  },
  onShow() {
    this.loadUserInfo()
  },
  onShareAppMessage() {
    const inviteCode = uni.getStorageSync('invite_code') || (uni.getStorageSync('user_info') || {}).invite_code || ''
    return {
      title: '🎁 好友邀请你一起玩，快来领福利！',
      path: inviteCode ? `/pages-user/invite/landing?invite_code=${inviteCode}` : '/pages-user/invite/landing',
      imageUrl: '/static/share_invite.png'
    }
  },
  onShareTimeline() {
    const inviteCode = uni.getStorageSync('invite_code') || (uni.getStorageSync('user_info') || {}).invite_code || ''
    return {
      title: '🎁 好友邀请你一起玩，快来领福利！',
      query: inviteCode ? `invite_code=${inviteCode}` : '',
      imageUrl: '/static/share_invite.png'
    }
  },
  methods: {
    checkPhoneBound() {
      if (!this.mobile) {
        uni.showModal({
          title: '需要绑定手机号',
          content: '为了账号安全，请先绑定手机号',
          showCancel: true,
          cancelText: '取消',
          confirmText: '去绑定',
          success: (res) => {
            if (res.confirm) {
              uni.navigateTo({ url: '/pages/login/index?mode=sms' })
            }
          }
        })
        return false
      }
      return true
    },

    // 修改头像
    handleEditAvatar() {
      if (!this.userId) {
        uni.showToast({ title: '请先登录', icon: 'none' })
        return
      }

      if (!this.checkPhoneBound()) return

      // 检查冷却时间
      const cooldownKey = 'avatar_update_cooldown'
      const lastUpdate = uni.getStorageSync(cooldownKey)
      const now = Date.now()
      const cooldownDays = 7

      if (lastUpdate && now - lastUpdate < cooldownDays * 24 * 60 * 60 * 1000) {
        const daysRemaining = Math.ceil((cooldownDays * 24 * 60 * 60 * 1000 - (now - lastUpdate)) / (24 * 60 * 60 * 1000))
        uni.showToast({
          title: `头像修改冷却中，还需${daysRemaining}天`,
          icon: 'none'
        })
        return
      }

      uni.chooseImage({
        count: 1,
        sizeType: ['compressed'], // 选择压缩图
        sourceType: ['album', 'camera'],
        success: (res) => {
          const tempFilePath = res.tempFilePaths[0]
          this.uploadAvatar(tempFilePath)
        }
      })
    },

    // 上传头像并转换为 base64
    async uploadAvatar(filePath) {
      uni.showLoading({ title: '上传中...' })

      try {
        // 将图片转换为 base64
        const base64 = await this.fileToBase64(filePath)

        // 调用修改用户信息接口
        const data = await modifyUser(this.userId, { avatar: base64 })

        // 更新本地存储
        uni.setStorageSync('avatar', data.avatar || base64)
        this.avatar = data.avatar || base64

        const userInfo = uni.getStorageSync('user_info') || {}
        userInfo.avatar = data.avatar || base64
        uni.setStorageSync('user_info', userInfo)

        // 记录修改时间（7天冷却）
        uni.setStorageSync('avatar_update_cooldown', Date.now())

        uni.hideLoading()
        uni.showToast({ title: '头像修改成功', icon: 'success' })
      } catch (err) {
        uni.hideLoading()
        uni.showToast({ title: err.message || '上传失败', icon: 'none' })
      }
    },

    // 文件转 base64
    fileToBase64(filePath) {
      return new Promise((resolve, reject) => {
        uni.getFileSystemManager().readFile({
          filePath: filePath,
          encoding: 'base64',
          success: (res) => {
            // 判断文件类型并添加 data URI 前缀
            const ext = filePath.split('.').pop().toLowerCase()
            let mimeType = 'image/jpeg'
            if (ext === 'png') mimeType = 'image/png'
            if (ext === 'gif') mimeType = 'image/gif'
            if (ext === 'webp') mimeType = 'image/webp'

            resolve(`data:${mimeType};base64,${res.data}`)
          },
          fail: (err) => {
            reject(err)
          }
        })
      })
    },

    // 修改昵称
    handleEditNickname() {
      if (!this.userId) {
        uni.showToast({ title: '请先登录', icon: 'none' })
        return
      }

      // 检查冷却时间
      const cooldownKey = 'nickname_update_cooldown'
      const lastUpdate = uni.getStorageSync(cooldownKey)
      const now = Date.now()
      const cooldownDays = 7

      if (lastUpdate && now - lastUpdate < cooldownDays * 24 * 60 * 60 * 1000) {
        const daysRemaining = Math.ceil((cooldownDays * 24 * 60 * 60 * 1000 - (now - lastUpdate)) / (24 * 60 * 60 * 1000))
        uni.showToast({
          title: `昵称修改冷却中，还需${daysRemaining}天`,
          icon: 'none'
        })
        return
      }

      uni.showModal({
        title: '修改昵称',
        editable: true,
        placeholderText: '请输入新昵称',
        content: this.nickname,
        success: async (res) => {
          if (res.confirm) {
            const newNickname = res.content?.trim()
            if (!newNickname) {
              uni.showToast({ title: '昵称不能为空', icon: 'none' })
              return
            }

            if (newNickname.length > 20) {
              uni.showToast({ title: '昵称不能超过20个字符', icon: 'none' })
              return
            }

            try {
              uni.showLoading({ title: '修改中...' })

              // 调用修改用户信息接口
              const data = await modifyUser(this.userId, { nickname: newNickname })

              // 更新本地存储
              uni.setStorageSync('nickname', data.nickname || newNickname)
              this.nickname = data.nickname || newNickname

              const userInfo = uni.getStorageSync('user_info') || {}
              userInfo.nickname = data.nickname || newNickname
              uni.setStorageSync('user_info', userInfo)

              // 记录修改时间（7天冷却）
              uni.setStorageSync('nickname_update_cooldown', Date.now())

              uni.hideLoading()
              uni.showToast({ title: '昵称修改成功', icon: 'success' })
            } catch (err) {
              uni.hideLoading()
              uni.showToast({ title: err.message || '修改失败', icon: 'none' })
            }
          }
        }
      })
    },

    handleContactService() {
      if (!this.customerServiceQrCode) return
      uni.previewImage({
        urls: [this.customerServiceQrCode],
        current: this.customerServiceQrCode
      }) 
    },

    getInviteCode() {
      const v = this.inviteCode || uni.getStorageSync('invite_code') || (uni.getStorageSync('user_info') || {}).invite_code || ''
      return String(v || '').trim()
    },
    formatPoints(v) {
      // 后端已返回积分单位（分 * rate / 100），直接显示
      const n = Number(v) || 0
      if (n === 0) return '0.0'
      return n.toFixed(1)
    },
    copyInviteCode() {
      const code = this.getInviteCode()
      if (!code) {
        uni.showToast({ title: '暂无邀请码', icon: 'none' })
        return
      }
      uni.setClipboardData({
        data: code,
        success: () => {
          uni.showToast({ title: '邀请码已复制', icon: 'none' })
        }
      })
    },
    getInviteSharePath() {
      const code = this.getInviteCode()
      return code ? `/pages-user/invite/landing?invite_code=${encodeURIComponent(code)}` : '/pages-user/invite/landing'
    },
    normalizePointsBalance(v) {
      if (v && typeof v === 'object') {
        const nested = v.balance ?? v.points_balance ?? v.value
        const n1 = Number(nested)
        return Number.isFinite(n1) ? n1 : 0
      }
      const n2 = Number(v)
      return Number.isFinite(n2) ? n2 : 0
    },
    async loadUserInfo() {
      const token = uni.getStorageSync('token')
      if (!token) {
        this.resetUser()
        return
      }
      try {
        // 优先使用新的 profile API
        let profile = null
        try {
          profile = await getUserProfile()
        } catch (err) {
          console.warn('[Mine] getUserProfile 调用失败，将尝试降级逻辑:', err)
        }

        if (profile) {
          console.log('[Mine] 从 profile API 获取用户信息:', profile)
          this.userId = profile.id
          this.nickname = profile.nickname
          this.avatar = profile.avatar
          this.title = profile.title || ''
          this.inviteCode = profile.invite_code
          this.inviterId = profile.inviter_id || 0
          this.inviterNickname = profile.inviter_nickname || ''
          this.inviterAvatar = profile.inviter_avatar || ''
          this.pointsBalance = this.normalizePointsBalance(profile.balance)
          this.mobile = profile.mobile || ''
          this.douyinUserId = profile.douyin_user_id || ''

          // 更新缓存
          const cachedUser = uni.getStorageSync('user_info') || {}
          cachedUser.id = profile.id
          cachedUser.nickname = profile.nickname
          cachedUser.avatar = profile.avatar
          cachedUser.title = profile.title
          cachedUser.invite_code = profile.invite_code
          cachedUser.inviter_id = profile.inviter_id
          cachedUser.inviter_nickname = profile.inviter_nickname
          cachedUser.inviter_avatar = profile.inviter_avatar
          cachedUser.mobile = profile.mobile
          cachedUser.points_balance = this.pointsBalance
          uni.setStorageSync('user_info', cachedUser)
          uni.setStorageSync('user_id', profile.id)

          // 如果有手机号，更新缓存
          if (profile.mobile) {
            uni.setStorageSync('phone_number', profile.mobile)
          }

          // Load stats
          const s = await getUserStats(profile.id)
          if (s) this.stats = { ...this.stats, ...s }

          return
        }

        // 降级到旧逻辑 (通常不会走到这里，除非 API 挂了)
        // ... (省略部分降级代码，或者保持原样)
        // 简单起见，如果 profile 失败，降级逻辑里可能拿不到 inviterId，
        // 但为了保持健壮性，这里保留原有的逻辑，只是不再去更新 inviterId（因为旧逻辑拿不到）
        
        console.log('[Mine] profile API 无数据，使用降级逻辑')
        const cachedUser = uni.getStorageSync('user_info')
        const cachedUserId = uni.getStorageSync('user_id')

        if (cachedUser) {
          this.userId = cachedUser.id || cachedUserId
          this.nickname = cachedUser.nickname
          this.avatar = cachedUser.avatar
          this.inviteCode = cachedUser.invite_code
          // 缓存里可能有 inviter 信息
          this.inviterId = cachedUser.inviter_id || 0
          this.inviterNickname = cachedUser.inviter_nickname || ''
          this.inviterAvatar = cachedUser.inviter_avatar || ''
          
          this.title = cachedUser.title || ''
          this.pointsBalance = this.normalizePointsBalance(cachedUser.points_balance)
          this.mobile = cachedUser.mobile || cachedUser.phone || cachedUser.phone_number || ''
          this.douyinUserId = cachedUser.douyin_user_id || ''
        } else if (cachedUserId) {
          this.userId = cachedUserId
        }
        
        // ... 继续原有加载 stats 逻辑
        if (this.userId) {
             const s = await getUserStats(this.userId)
             if (s) this.stats = { ...this.stats, ...s }
        }

      } catch (e) {
        console.error('[Mine] loadUserInfo 错误:', e)
      }
    },

    resetUser() {
      this.userId = ''
      this.nickname = ''
      this.avatar = ''
      this.title = ''
      this.pointsBalance = 0
      this.douyinUserId = ''
      this.stats = { coupon_count: 0, item_card_count: 0 }
    },
    handleJoin() {
      uni.navigateTo({ url: '/pages/login/index' })
    },
    toOrders(status) {
      if (!this.checkPhoneBound()) return
      uni.navigateTo({ url: `/pages-user/orders/index?status=${status}` })
    },
    toCabinetTab(tabIndex) {
      if (!this.checkPhoneBound()) return
      uni.setStorageSync('cabinet_target_tab', tabIndex)
      uni.switchTab({ url: '/pages/cabinet/index' })
    },
    toAddresses() {
      if (!this.checkPhoneBound()) return
      uni.navigateTo({ url: '/pages-user/address/index' })
    },
    toPointsPage() {
      if (!this.checkPhoneBound()) return
      uni.navigateTo({ url: '/pages-user/points/index' })
    },
    toCouponsPage() {
      if (!this.checkPhoneBound()) return
      uni.navigateTo({ url: '/pages-user/coupons/index' })
    },
    toItemCardsPage() {
      if (!this.checkPhoneBound()) return
      uni.navigateTo({ url: '/pages-user/item-cards/index' })
    },
    toInvitesPage() {
      if (!this.checkPhoneBound()) return
      uni.navigateTo({ url: '/pages-user/invites/index' })
    },
    toTasksPage() {
      if (!this.checkPhoneBound()) return
      uni.navigateTo({ url: '/pages-user/tasks/index' })
    },
    toHelp() {
      const items = ['购买协议', '用户协议']
      if (this.customerServiceQrCode) {
        items.push('联系客服')
      }

      uni.showActionSheet({
        itemList: items,
        success: (res) => {
          const idx = Number(res && res.tapIndex)
          const item = items[idx]

          if (item === '购买协议') {
            uni.navigateTo({ url: '/pages-user/agreement/purchase' })
          } else if (item === '用户协议') {
             uni.navigateTo({ url: '/pages-user/agreement/user' })
          } else if (item === '联系客服') {
            this.handleContactService()
          }
        }
      })
    },
    toBindDouyinOrder() {
      if (!this.checkPhoneBound()) return

      // 检查是否已绑定
      if (this.douyinUserId) {
        uni.showToast({
          title: '您已绑定抖音账号，暂不支持换绑',
          icon: 'none'
        })
        return
      }

      uni.showModal({
        title: '绑定抖音',
        content: '',
        editable: true,
        placeholderText: '请输入您的抖音号',
        success: async (res) => {
          if (res.confirm) {
            const douyinId = res.content?.trim()
            if (!douyinId) {
              uni.showToast({ title: '抖音号不能为空', icon: 'none' })
              return
            }

            try {
              uni.showLoading({ title: '绑定中...' })
              const data = await bindDouyinID(douyinId)
              this.douyinUserId = data.douyin_id

              // 更新缓存
              const userInfo = uni.getStorageSync('user_info') || {}
              userInfo.douyin_user_id = data.douyin_id
              uni.setStorageSync('user_info', userInfo)

              uni.hideLoading()
              uni.showToast({ title: '绑定成功', icon: 'success' })
            } catch (err) {
              uni.hideLoading()
              uni.showToast({ title: err.message || '绑定失败', icon: 'none' })
            }
          }
        }
      })
    },
    async handleSyncDouyinOrders() {
      if (!this.checkPhoneBound()) return
      if (this.douyinSyncing) return

      if (!this.douyinUserId) {
        uni.showToast({
          title: '请先绑定抖音号',
          icon: 'none'
        })
        return
      }

      this.douyinSyncing = true
      try {
        uni.showLoading({ title: '同步中...' })
        const data = await syncMyDouyinOrders()
        await this.loadUserInfo()
        uni.hideLoading()

        uni.showModal({
          title: '同步完成',
          content: `抖音号：${data.douyin_user_id || this.douyinUserId}\n抓取订单：${data.total_fetched || 0} 笔\n新增订单：${data.new_orders || 0} 笔`,
          showCancel: false
        })
      } catch (err) {
        uni.hideLoading()
        uni.showToast({
          title: err.message || '同步失败',
          icon: 'none'
        })
      } finally {
        this.douyinSyncing = false
      }
    },
    toMinesweeper() {
      if (!this.checkPhoneBound()) return
      uni.navigateTo({ url: '/pages-game/game/minesweeper/index' })
    },
    toSettings() {
      uni.navigateTo({ url: '/pages-user/settings/index' })
    },
    // 抖音IM客服回调
    onImCallback(e) {
      console.log('[Douyin IM] 跳转IM客服成功', e.detail)
    },
    onImError(e) {
      console.log('[Douyin IM] 拉起IM客服失败', e.detail)
      uni.showToast({
        title: '打开客服失败',
        icon: 'none'
      })
    },
    handleInvite() {
      const code = this.getInviteCode()
      const path = this.getInviteSharePath()

      try { if (code) uni.setStorageSync('inviter_code', code) } catch (_) {}

      // #ifdef MP-WEIXIN
      try { uni.showShareMenu({ withShareTicket: true }) } catch (_) {}
      uni.showModal({
        title: '邀请好友',
        content: '请点击「立即邀请」进行分享。',
        showCancel: true,
        cancelText: '复制链接',
        confirmText: '知道了',
        success: (res) => {
          if (res.cancel) {
            const data = path
            uni.setClipboardData({ data })
          }
        }
      })
      return
      // #endif

      // #ifdef APP-PLUS
      if (typeof uni.share === 'function') {
        const summary = code ? `给你一个宝藏应用，快来！邀请码：${code}` : '给你一个宝藏应用，快来！'
        uni.share({
          provider: 'weixin',
          scene: 'WXSceneSession',
          type: 1,
          summary,
          fail: () => {
            uni.setClipboardData({ data: path })
          }
        })
        return
      }
      // #endif

      // #ifdef H5
      const url = `${location.origin}${location.pathname}#${path}`
      const text = '给你一个宝藏应用，快来！'
      if (typeof navigator !== 'undefined' && navigator.share) {
        navigator.share({ title: text, text, url }).catch(() => {
          uni.setClipboardData({ data: url })
        })
      } else {
        uni.setClipboardData({ data: url })
      }
      // #endif

      // #ifndef MP-WEIXIN
      // #ifndef APP-PLUS
      // #ifndef H5
      uni.setClipboardData({ data: path })
      // #endif
      // #endif
      // #endif
    },
    
    // --- Points Logic ---
    async showPointsPopup() {
      if (!this.checkPhoneBound()) return
      this.pointsVisible = true
      this.pointsList = []
      this.pointsPage = 1
      this.pointsHasMore = true
      await this.loadMorePoints()
    },
    closePointsPopup() { this.pointsVisible = false },
    async loadMorePoints() {
      if (this.pointsLoading || !this.pointsHasMore) return
      this.pointsLoading = true
      try {
        const res = await getUserPoints(this.userId, this.pointsPage, 10)
        const list = res.list || res.data || []
        if (list.length < 10) this.pointsHasMore = false
        this.pointsList = [...this.pointsList, ...list]
        this.pointsPage++
      } catch (e) {
        this.pointsHasMore = false
      } finally {
        this.pointsLoading = false
      }
    },
    getActionText(action) {
      const map = {
        'login': '每日登录',
        'register': '注册赠送',
        'invite': '邀请好友',
        'consume': '消费抵扣',
        'refund': '退款返还',
        'activity': '活动奖励'
      }
      return map[action] || '积分变动'
    },
    
    // --- Coupons Logic ---
    async showCouponsPopup() {
      if (!this.checkPhoneBound()) return
      this.couponsVisible = true
      this.couponsTab = 1
      this.couponsList = []
      this.couponsPage = 1
      this.couponsHasMore = true
      await this.loadMoreCoupons()
    },
    closeCouponsPopup() { this.couponsVisible = false },
    switchCouponsTab(tab) {
      if (this.couponsTab === tab) return
      this.couponsTab = tab
      this.couponsList = []
      this.couponsPage = 1
      this.couponsHasMore = true
      this.loadMoreCoupons()
    },
    async loadMoreCoupons() {
      if (this.couponsLoading || !this.couponsHasMore) return
      this.couponsLoading = true
      try {
        // status: 0=unused, 1=used, 2=expired
    // status: 1=有效, 2=已失效
        const res = await getUserCoupons(this.userId, this.couponsTab, this.couponsPage)
        const list = res.list || res.data || []
        if (list.length < 10) this.couponsHasMore = false
        this.couponsList = [...this.couponsList, ...list]
        this.couponsPage++
      } catch (e) {
        this.couponsHasMore = false
      } finally {
        this.couponsLoading = false
      }
    },
    getCouponEmptyText() {
      if (this.couponsTab === 1) return '暂无可用优惠券'
      return '暂无失效优惠券'
    },
    getCouponCardClass(item) {
      if (this.couponsTab === 2) return 'coupon-invalid'
      const sub = item?.sub_status || ''
      if (sub === 'in_use') return 'coupon-in-use'
      return ''
    },
    getCouponLabelClass(item) {
      const sub = item?.sub_status || ''
      if (sub === 'in_use') return 'label-in-use'
      if (sub === 'unused') return 'label-unused'
      return 'label-invalid'
    },
    getCouponStatusTagClass(item) {
      const sub = item?.sub_status || ''
      if (sub === 'expired') return 'expired'
      return 'used'
    },
    formatCouponValue(val) {
      return (Number(val) / 100).toFixed(0)
    },
    formatCouponRules(rules) {
      if (!rules) return '全场通用'
      // 将"XXX分"替换为"¥X.XX元"格式
      return rules.replace(/(\d+)分/g, (match, p1) => {
        const yuan = (Number(p1) / 100).toFixed(2)
        // 去掉末尾的.00
        const formatted = yuan.endsWith('.00') ? yuan.slice(0, -3) : yuan
        return `¥${formatted}元`
      })
    },
    formatCouponExpiry(item) {
      if (!item.end_time) return '长期有效'
      return `有效期至 ${this.formatDate(item.end_time)}`
    },
    getCouponUsedPercent(item) {
       if (!item.amount || !item.remaining) return 0
       const used = item.amount - item.remaining
       return Math.floor((used / item.amount) * 100)
    },
    
    // --- Item Cards Logic ---
    async showItemCardsPopup() {
      if (!this.checkPhoneBound()) return
      this.itemCardsVisible = true
      this.itemCardsTab = 0
      this.itemCardsList = []
      this.itemCardsLoading = true
      await this.loadItemCards()
    },
    closeItemCardsPopup() { this.itemCardsVisible = false },
    switchItemCardsTab(t) {
      if (this.itemCardsTab === t) return
      this.itemCardsTab = t
      this.loadItemCards()
    },
    async loadItemCards() {
      this.itemCardsLoading = true
      this.itemCardsList = []
      try {
        // Pass status: 0(tab)=>1(unused), 1(tab)=>2(used)
        const status = this.itemCardsTab === 0 ? 1 : 2
        const res = await getItemCards(this.userId, status) 
        
        // Robustly get the list (support res.list or res.data)
        let list = Array.isArray(res) ? res : (res.list || res.data || [])
        
        this.itemCardsList = list.map(item => {
          return {
            ...item,
            // Ensure count exists, default to 1 if undefined
            count: item.count ?? item.remaining ?? 1
          }
        })
        
        // For unused tab, filter out items with 0 count if any
        if (this.itemCardsTab === 0) {
           this.itemCardsList = this.itemCardsList.filter(i => i.count > 0)
        }
      } catch (e) {
        console.error('loadItemCards error:', e)
      } finally {
        this.itemCardsLoading = false
      }
    },
    getCardIcon(type) {
      if ((type || '').includes('透视')) return '👁️'
      if ((type || '').includes('提示')) return '💡'
      if ((type || '').includes('重置')) return '🔄'
      return '🃏'
    },
    
    // --- Tasks Logic ---
    async showTasksPopup() {
      if (!this.checkPhoneBound()) return
      this.tasksVisible = true
      this.tasksLoading = true
      try {
        const res = await getUserTasks(1, 20)
        this.tasksList = Array.isArray(res) ? res : (res.list || [])
      } catch (e) {
        this.tasksList = []
      } finally {
        this.recalcTasksStats()
        this.loadTasksProgress()
        this.tasksLoading = false
      }
    },
    closeTasksPopup() { this.tasksVisible = false },
    recalcTasksStats() {
      const list = Array.isArray(this.tasksList) ? this.tasksList : []
      let done = 0
      let ongoing = 0
      let waiting = 0
      for (let i = 0; i < list.length; i++) {
        const s = Number(list[i]?.status)
        if (s === 2) done += 1
        else if (s === 1) ongoing += 1
        else waiting += 1
      }
      this.tasksStats = { done, ongoing, waiting }
    },
    getOverallProgress() {
      const total = Array.isArray(this.tasksList) ? this.tasksList.length : 0
      if (!total) return 0
      return Math.floor((this.tasksStats.done / total) * 100)
    },
    getTaskClass(task) {
      const s = Number(task && task.status)
      if (s === 2) return 'task-done'
      if (s === 1) return 'task-ongoing'
      return 'task-waiting'
    },
    getTaskIcon(type) {
      const s = String(type || '').trim()
      if (!s) return '📌'
      if (s.includes('邀请') || s.includes('invite')) return '👥'
      if (s.includes('登录') || s.includes('login')) return '📅'
      if (s.includes('分享') || s.includes('share')) return '📣'
      if (s.includes('消费') || s.includes('consume')) return '🛒'
      if (s.includes('绑定') || s.includes('phone')) return '📱'
      if (s.includes('关注') || s.includes('follow')) return '⭐'
      return '📌'
    },
    getTaskStatusText(task) {
      const s = Number(task && task.status)
      if (s === 2) return '已完成'
      if (s === 1) return '进行中'
      return '未开始'
    },
    getTaskBtnText(task) {
      if (task.status === 2) return '已完成'
      if (task.status === 1) return '去完成'
      return '领取任务'
    },
    normalizeTaskProgress(res) {
      const raw = res && (res.data ?? res.result ?? res)
      if (!raw || typeof raw !== 'object') return null
      const current = raw.current ?? raw.progress ?? raw.done ?? raw.completed ?? raw.value ?? null
      const total = raw.total ?? raw.target ?? raw.required ?? raw.max ?? raw.goal ?? null
      const percentRaw = raw.percent ?? raw.percentage ?? raw.rate ?? raw.ratio ?? null
      let percent = null
      if (percentRaw !== null && percentRaw !== undefined && Number.isFinite(Number(percentRaw))) {
        const p = Number(percentRaw)
        percent = p <= 1 ? Math.round(p * 100) : Math.round(p)
      }
      if (percent === null && current !== null && total !== null) {
        const c = Number(current)
        const t = Number(total)
        if (Number.isFinite(c) && Number.isFinite(t) && t > 0) {
          percent = Math.round((c / t) * 100)
        }
      }
      if (percent === null) return null
      if (percent < 0) percent = 0
      if (percent > 100) percent = 100
      const currentNum = Number.isFinite(Number(current)) ? Number(current) : null
      const totalNum = Number.isFinite(Number(total)) ? Number(total) : null
      return { percent, current: currentNum, total: totalNum }
    },
    getTaskProgress(task) {
      const id = task && (task.id ?? task.task_id ?? task.taskId)
      const s = Number(task && task.status)
      if (s === 2) return { percent: 100, current: null, total: null }
      if (id === undefined || id === null || id === '') return { percent: 0, current: null, total: null }
      const p = this.tasksProgressMap[String(id)]
      if (p && Number.isFinite(Number(p.percent))) {
        const percent = Math.max(0, Math.min(100, Number(p.percent)))
        return { percent, current: p.current ?? null, total: p.total ?? null }
      }
      return { percent: 0, current: null, total: null }
    },
    getTaskProgressText(task) {
      const p = this.getTaskProgress(task)
      if (Number(task && task.status) === 2) return '进度 100%'
      if (p.current !== null && p.total !== null) return `进度 ${p.current}/${p.total}`
      return `进度 ${p.percent}%`
    },
    async loadTasksProgress() {
      const user_id = this.userId || uni.getStorageSync('user_id')
      const list = Array.isArray(this.tasksList) ? this.tasksList : []
      if (!user_id || list.length === 0) return
      const need = []
      for (let i = 0; i < list.length; i++) {
        const t = list[i]
        const id = t && (t.id ?? t.task_id ?? t.taskId)
        if (id === undefined || id === null || id === '') continue
        const key = String(id)
        if (this.tasksProgressMap[key]) continue
        need.push({ key, id })
      }
      if (need.length === 0) return
      const settled = await Promise.allSettled(need.map(it => getTaskProgress(it.id, user_id)))
      const next = { ...this.tasksProgressMap }
      for (let i = 0; i < settled.length; i++) {
        const it = need[i]
        const r = settled[i]
        if (r.status !== 'fulfilled') continue
        const normalized = this.normalizeTaskProgress(r.value)
        if (normalized) next[it.key] = normalized
      }
      this.tasksProgressMap = next
    },
    handleTask(task) {
      if (task.status === 2) return
      // Implement task action logic
      uni.showToast({ title: '任务进行中', icon: 'none' })
    },
    
    // --- Invites Logic ---
    async showInvitesPopup() {
      if (!this.checkPhoneBound()) return
      this.invitesVisible = true
      this.invitesLoading = true
      try {
        const res = await getInviteRecords(1, 20)
        this.invitesList = Array.isArray(res) ? res : (res.list || [])
      } catch (e) {
        this.invitesList = []
      } finally {
        this.invitesLoading = false
      }
    },
    closeInvitesPopup() { this.invitesVisible = false },
    getInviteRewardsTotal() {
      // Calculate total rewards from invitesList if available
      return '0'
    },
    
    // Utils
    toDate(input) {
      if (!input) return null
      if (input instanceof Date) return isNaN(input.getTime()) ? null : input
      if (typeof input === 'number') {
        if (!Number.isFinite(input)) return null
        const ms = input > 1e12 ? input : input * 1000
        const d = new Date(ms)
        return isNaN(d.getTime()) ? null : d
      }
      const s = String(input || '').trim()
      if (!s) return null
      if (/^\d+$/.test(s)) {
        const n = Number(s)
        return this.toDate(n)
      }
      const c1 = s
      const c2 = s.replace(/([+-]\d{2}):(\d{2})$/, '$1$2')
      const c3 = c2.replace(/-/g, '/').replace('T', ' ')
      const c4 = s.replace(/-/g, '/').replace('T', ' ')
      const candidates = [c1, c2, c3, c4]
      for (let i = 0; i < candidates.length; i++) {
        const d = new Date(candidates[i])
        if (!isNaN(d.getTime())) return d
      }
      return null
    },
    formatDate(ts) {
      const d = this.toDate(ts)
      if (!d) return ''
      return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`
    },
    formatDateTime(ts) {
      const d = this.toDate(ts)
      if (!d) return ''
      
      return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')} ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}`
    },
    formatDateTimeSeconds(ts) {
      const d = this.toDate(ts)
      if (!d) return ''

      return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')} ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}:${String(d.getSeconds()).padStart(2,'0')}`
    }
  }
}
</script>

<style lang="scss">
/* ============================================
   个人中心 - 视觉升级 (SCSS Integration)
   ============================================ */

.page-container {
  min-height: 100vh;
  background-color: $bg-page;
  padding-bottom: calc(env(safe-area-inset-bottom) + 120rpx); /* TabBar space */
  position: relative;
  overflow-x: hidden;
}

/* 背景装饰 - 漂浮光球 */
.bg-decoration {
  position: absolute;
  top: 0; left: 0; width: 100%; height: 100%;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;

  &::before {
    content: '';
    position: absolute;
    top: -100rpx; right: -100rpx;
    width: 600rpx; height: 600rpx;
    background: radial-gradient(circle, rgba($brand-primary, 0.15) 0%, transparent 70%);
    filter: blur(60rpx);
    border-radius: 50%;
    opacity: 0.8;
    animation: float 10s ease-in-out infinite;
  }

  &::after {
    content: '';
    position: absolute;
    top: 200rpx; left: -200rpx;
    width: 500rpx; height: 500rpx;
    background: radial-gradient(circle, rgba($brand-secondary, 0.1) 0%, transparent 70%);
    filter: blur(50rpx);
    border-radius: 50%;
    opacity: 0.6;
    animation: float 15s ease-in-out infinite reverse;
  }
}

@keyframes float {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(30rpx, 50rpx); }
}

/* 通用毛玻璃卡片 - Claymorphism */
.glass-card {
  background: linear-gradient(145deg, #ffffff, #f8f8f8);
  backdrop-filter: blur(20rpx);
  border: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow:
    10rpx 10rpx 20rpx rgba(0, 0, 0, 0.06),
    -10rpx -10rpx 20rpx rgba(255, 255, 255, 0.7),
    inset 3rpx 3rpx 6rpx rgba(255, 255, 255, 0.8),
    inset -3rpx -3rpx 6rpx rgba(0, 0, 0, 0.03);
  border-radius: $radius-lg;
  position: relative;
  z-index: 1;
}

/* 头部区域 */
.header-section {
  padding: 0 $spacing-lg;
  padding-top: calc(env(safe-area-inset-top) + 20rpx);
  margin-bottom: $spacing-lg;
}

.user-info-card {
  padding: $spacing-xl;
  background: linear-gradient(145deg, #ffffff, #f8f8f8);
  box-shadow:
    12rpx 12rpx 24rpx rgba(0, 0, 0, 0.06),
    -12rpx -12rpx 24rpx rgba(255, 255, 255, 0.7),
    inset 4rpx 4rpx 8rpx rgba(255, 255, 255, 0.85),
    inset -4rpx -4rpx 8rpx rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: $radius-xl;
}

.user-main {
  display: flex;
  align-items: center;
  margin-bottom: 40rpx;
}

.avatar {
  width: 120rpx; height: 120rpx;
  background: $bg-card;
  border-radius: 50%;
  border: 4rpx solid $bg-card;

  /* Claymorphism 凹陷效果 */
  box-shadow:
    inset 4rpx 4rpx 8rpx rgba(0, 0, 0, 0.1),
    inset -4rpx -4rpx 8rpx rgba(255, 255, 255, 0.9);
  margin-right: 24rpx;
}

.avatar-wrapper {
  position: relative;
  margin-right: 24rpx;
  cursor: pointer;

  .avatar {
    margin-right: 0;
  }

  .avatar-edit-badge {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 40rpx;
    height: 40rpx;
    background: linear-gradient(145deg, #FF9500, #FF6B00);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 3rpx solid $bg-card;

    /* Claymorphism 凸起效果 */
    box-shadow:
      4rpx 4rpx 8rpx rgba(255, 107, 0, 0.2),
      -4rpx -4rpx 8rpx rgba(255, 255, 255, 0.7),
      inset 2rpx 2rpx 4rpx rgba(255, 255, 255, 0.4),
      inset -2rpx -2rpx 4rpx rgba(0, 0, 0, 0.1);

    .edit-icon {
      font-size: 20rpx;
      line-height: 1;
    }
  }
}

.user-meta { flex: 1; }

.name-row {
  display: flex; align-items: center; margin-bottom: 12rpx;
  cursor: pointer;

  &:active {
    opacity: 0.7;
  }
}
.nickname {
  font-size: $font-xl; font-weight: 900; color: $text-main;
  margin-right: 16rpx;
}

.edit-nickname-icon {
  font-size: 28rpx;
  margin-right: 8rpx;
  opacity: 0.6;
}

.level-badge {
  background: linear-gradient(90deg, #333, #555);
  color: $accent-gold;
  font-size: $font-xs;
  padding: 4rpx 12rpx;
  border-radius: 100rpx;
  display: flex; align-items: center;
  box-shadow: 0 4rpx 8rpx rgba(0,0,0,0.2);
}
.level-icon { width: 24rpx; height: 24rpx; margin-right: 4rpx; }

.userid { font-size: $font-sm; color: $text-tertiary; font-family: monospace; }

/* 绑定的抖音号 */
.douyin-id-row {
  display: flex;
  align-items: center;
  margin-top: 8rpx;
  font-size: $font-sm;
}
.douyin-id-label {
  color: $text-tertiary;
  margin-right: 8rpx;
}
.douyin-id-value {
  color: $brand-primary;
  font-weight: 600;
  font-family: monospace;
}

.join-btn {
  background: $text-main;
  color: $text-inverse;
  padding: 12rpx 32rpx;
  border-radius: 100rpx;
  font-size: 26rpx;
  font-weight: 700;
  box-shadow: $shadow-sm;
}

/* 进度条 */
.progress-container {
  width: 100%;
}
.progress-bar {
  height: 8rpx;
  background: $border-color-light;
  border-radius: 100rpx;
  overflow: hidden;
  margin-bottom: 6rpx;
}
.progress-fill {
  height: 100%;
  background: $gradient-brand;
  border-radius: 100rpx;
}
.progress-text {
  font-size: $font-xs; color: $text-sub;
}

/* 数据统计 */
.stats-row {
  display: flex; align-items: center; justify-content: space-around;
  padding-top: 20rpx;
  border-top: 1px solid rgba(0,0,0,0.03);
}
.stat-item {
  display: flex; flex-direction: column; align-items: center;
  flex: 1;
  &:active { opacity: 0.7; }
}
.stat-num {
  font-size: $font-xl; font-weight: 900; color: $text-main;
  font-family: 'DIN Alternate', sans-serif;
  margin-bottom: 4rpx;
}
.stat-label { font-size: $font-sm; color: $text-sub; }
.stat-divider { width: 1px; height: 30rpx; background: $border-color-light; }

/* 邀请Banner */
.invite-banner {
  margin: 0 $spacing-lg $spacing-lg;
  background: linear-gradient(135deg, $uni-bg-color-hover 0%, $bg-card 100%);
  border: 1px solid rgba($brand-primary, 0.1);
  padding: 30rpx;
  display: flex; align-items: center; justify-content: space-between;
  position: relative;
  overflow: hidden;
}
.invite-content { position: relative; z-index: 2; flex: 1; display: flex; align-items: center; justify-content: space-between; }
.invite-text-group { display: flex; flex-direction: column; }
.invite-title-row { display: flex; align-items: center; margin-bottom: 8rpx; }
.invite-tag { 
  background: $accent-red; color: $text-inverse; font-size: 18rpx; padding: 2rpx 8rpx; border-radius: 4rpx; margin-right: 12rpx;
}
.invite-title { font-size: 30rpx; font-weight: 800; color: #5D3A20; }
.invite-desc { font-size: $font-xs; color: #9E7D60; }
.invite-action-btn {
  background: $gradient-brand;
  color: $text-inverse;
  padding: 10rpx 24rpx;
  border-radius: 100rpx;
  font-size: $font-sm;
  font-weight: 700;
  display: flex; align-items: center;
  box-shadow: 0 4rpx 12rpx rgba($brand-primary, 0.2);
}
.invite-share-btn {
  line-height: 1;
  margin: 0;
}
.invite-share-btn::after { border: none; }
.invite-share-icon {
  width: 30rpx;
  height: 30rpx;
  margin-right: 10rpx;
  border-radius: 8rpx;
}
.invite-arrow { font-size: 28rpx; margin-left: 4rpx; line-height: 1; }
.invite-bg-icon {
  position: absolute; right: -20rpx; bottom: -20rpx;
  width: 140rpx; height: 140rpx;
  opacity: 0.1;
  transform: rotate(-15deg);
}

/* 常用功能 & 订单 - Claymorphism */
.section-card {
  margin: 0 $spacing-lg $spacing-lg;
  padding: 30rpx;
  background: linear-gradient(145deg, #ffffff, #f8f8f8);
  box-shadow:
    10rpx 10rpx 20rpx rgba(0, 0, 0, 0.05),
    -10rpx -10rpx 20rpx rgba(255, 255, 255, 0.7),
    inset 3rpx 3rpx 6rpx rgba(255, 255, 255, 0.8),
    inset -3rpx -3rpx 6rpx rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: $radius-lg;
}
.section-header {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 30rpx;
}
.section-title { font-size: 30rpx; font-weight: 800; color: $text-main; }
.section-more { font-size: $font-sm; color: $text-sub; }

.grid-row, .grid-menu {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20rpx;
}
.grid-item, .menu-item {
  display: flex; flex-direction: column; align-items: center;
  position: relative;
  &:active { transform: scale(0.96); transition: 0.1s; }
}
.icon-wrapper, .menu-icon-box {
  width: 80rpx; height: 80rpx;
  background: linear-gradient(145deg, #f8f8f8, #e8e8e8);
  border-radius: 24rpx;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 12rpx;
  transition: all 0.3s;

  /* Claymorphism 凹陷效果 */
  box-shadow:
    inset 3rpx 3rpx 6rpx rgba(0, 0, 0, 0.06),
    inset -3rpx -3rpx 6rpx rgba(255, 255, 255, 0.9);
}
.grid-item:active .icon-wrapper, .menu-item:active .menu-icon-box {
  background: linear-gradient(145deg, #e8e8e8, #d8d8d8);
  box-shadow:
    inset 4rpx 4rpx 8rpx rgba(0, 0, 0, 0.1),
    inset -4rpx -4rpx 8rpx rgba(255, 255, 255, 0.7);
}
.grid-icon-img, .menu-icon-img { width: 44rpx; height: 44rpx; }
.grid-label, .menu-label { font-size: $font-sm; color: $text-main; }

/* 抖音IM客服按钮样式重置 */
.customer-service-btn {
  padding: 0;
  margin: 0;
  background: transparent;
  border: none;
  line-height: inherit;
  &::after {
    border: none;
  }
}

/* 弹窗通用样式 */
.popup-mask {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,0.6);
  backdrop-filter: blur(5rpx);
  z-index: 999;
  display: flex; align-items: center; justify-content: center;
  animation: fadeIn 0.2s;
}
.popup-content {
  width: 640rpx;
  max-height: 80vh;
  background: $bg-card;
  border-radius: $radius-xl;
  display: flex; flex-direction: column;
  overflow: hidden;
  animation: zoomIn 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}
.popup-header {
  padding: 30rpx;
  text-align: center;
  position: relative;
  border-bottom: 1px solid $border-color-light;
}
.popup-title { font-size: $font-lg; font-weight: 800; }
.close-btn {
  position: absolute; right: 30rpx; top: 30rpx;
  font-size: 40rpx; color: $text-tertiary;
  line-height: 1;
  padding: 10rpx;
}

.status-text, .empty-state {
  padding: 60rpx; text-align: center; color: $text-sub; font-size: 26rpx;
}
.empty-icon { font-size: 80rpx; display: block; margin-bottom: 20rpx; }

.no-more {
  text-align: center;
  font-size: 24rpx;
  color: $text-tertiary;
  padding: 30rpx 0;
  display: flex;
  align-items: center;
  justify-content: center;
  
  .text {
    margin: 0 16rpx;
  }
  
  .divider {
    width: 60rpx;
    height: 1px;
    background: #e0e0e0;
  }
}

/* 弹窗 Tab 栏 */
.popup-tabs {
  display: flex;
  justify-content: space-around;
  padding: 0 20rpx;
  background: #fff;
  border-bottom: 1rpx solid $border-color-light;
  margin-bottom: 20rpx;
}
.popup-tab {
  flex: 1;
  text-align: center;
  font-size: 28rpx;
  color: $text-sub;
  padding: 24rpx 0;
  position: relative;
  font-weight: 500;
  transition: all 0.2s;
}
.popup-tab.active {
  color: $text-main;
  font-weight: 700;
}
.popup-tab.active::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 40rpx;
  height: 6rpx;
  background: $brand-primary;
  border-radius: 6rpx;
}

/* 列表滚动区 */
.points-list, .coupon-scroll, .item-cards-scroll, .task-list-scroll, .invite-list-scroll {
  flex: 1; min-height: 400rpx; background: $bg-grey; padding: 20rpx;
}

/* 积分明细 */
.point-item {
  background: $bg-card; padding: 24rpx; border-radius: $radius-md; margin-bottom: 20rpx;
  display: flex; justify-content: space-between; align-items: center;
  box-shadow: $shadow-sm;
}
.point-desc { font-size: $font-md; color: $text-main; margin-bottom: 6rpx; display: block; }
.point-time { font-size: $font-xs; color: $text-tertiary; }
.point-amount { font-size: $font-lg; font-weight: 700; color: $text-main; }
.point-amount.positive { color: $brand-primary; }
.point-amount.negative { color: $text-main; }

/* 优惠券 V2样式 */
.coupon-ticket-v2 {
  background: #fff; border-radius: 16rpx; margin-bottom: 20rpx;
  display: flex; overflow: hidden; box-shadow: $shadow-sm;
  position: relative;
}
.coupon-left-v2 {
  width: 180rpx; background: linear-gradient(135deg, #FFF5E6, #fff);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 20rpx;
  position: relative;
}
.coupon-remaining { color: $brand-primary; font-weight: 900; }
.coupon-symbol { font-size: 24rpx; }
.coupon-amount-num { font-size: 56rpx; line-height: 1; }
.coupon-label { font-size: 20rpx; color: $brand-primary; margin-top: 8rpx; border: 1px solid $brand-primary; padding: 2rpx 8rpx; border-radius: 6rpx; }

/* 优惠券分割线 */
.coupon-divider-v2 {
  width: 30rpx;
  position: relative;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.divider-notch {
  width: 24rpx;
  height: 24rpx;
  background: $bg-grey; /* Match scroll container bg */
  border-radius: 50%;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
}
.divider-notch.top { top: -12rpx; }
.divider-notch.bottom { bottom: -12rpx; }
.divider-dash {
  width: 0;
  height: 80%;
  border-left: 2rpx dashed #eee;
}

.coupon-right-v2 { 
  flex: 1; 
  padding: 24rpx; 
  display: flex; 
  flex-direction: column; 
  justify-content: space-between; 
  overflow: hidden; /* Ensure content stays inside */
}
.coupon-name-v2 { 
  font-size: $font-md; 
  font-weight: 700; 
  color: $text-main; 
  margin-bottom: 8rpx; 
  white-space: nowrap; 
  overflow: hidden; 
  text-overflow: ellipsis; 
}
.coupon-original { font-size: 20rpx; color: $text-tertiary; text-decoration: line-through; margin-left: 8rpx; display: inline-block; }
.coupon-rules { font-size: $font-xs; color: $text-sub; margin-bottom: 16rpx; }

/* 优惠券进度条 */
.coupon-progress-wrap {
  margin-bottom: 12rpx;
}
.coupon-progress-bar {
  height: 6rpx;
  background: $bg-secondary;
  border-radius: 100rpx;
  overflow: hidden;
  margin-bottom: 4rpx;
}
.coupon-progress-fill {
  height: 100%;
  background: $brand-primary;
  border-radius: 100rpx;
}
.coupon-progress-text {
  font-size: 18rpx;
  color: $text-tertiary;
}

.coupon-footer-row { display: flex; justify-content: space-between; align-items: center; margin-top: auto; }
.coupon-footer-left { display: flex; flex-direction: column; }
.coupon-expire-v2 { font-size: 20rpx; color: $text-tertiary; }
.use-btn-v2 { 
  background: $brand-primary; 
  color: #fff; 
  font-size: 22rpx; 
  padding: 8rpx 24rpx; 
  border-radius: 100rpx; 
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: normal;
}
.status-tag { font-size: 22rpx; color: $text-tertiary; background: #F5F5F5; padding: 4rpx 12rpx; border-radius: 6rpx; }
.coupon-used-time { font-size: 18rpx; color: $text-tertiary; margin-top: 4rpx; text-align: left; }

/* 失效/使用中状态 */
.coupon-invalid .coupon-left-v2 {
  background: #f9f9f9;
}
.coupon-invalid .coupon-remaining,
.coupon-invalid .coupon-label {
  color: $text-tertiary;
  border-color: $text-tertiary;
}
.coupon-invalid .coupon-name-v2 {
  color: $text-sub;
}
.coupon-in-use .coupon-left-v2 {
  background: linear-gradient(135deg, #FFF3E0, #fff);
}
.label-unused { color: $brand-primary; border: 1px solid $brand-primary; }
.label-in-use { color: #FF8D3F; border: 1px solid #FF8D3F; }
.label-invalid { color: $text-tertiary; border: 1px solid $text-tertiary; }

/* 道具卡 */
.item-cards-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20rpx; }
.item-card {
  background: #fff; border-radius: 20rpx; padding: 24rpx;
  position: relative; overflow: hidden; box-shadow: $shadow-sm;
  border: 1px solid transparent;
}
.item-card:active { transform: scale(0.98); }
.card-icon-wrap { width: 80rpx; height: 80rpx; background: #F0F8FF; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 16rpx; }
.card-icon { font-size: 40rpx; }
.card-name { font-size: $font-md; font-weight: 700; margin-bottom: 8rpx; display: block; }
.card-desc { font-size: $font-xs; color: $text-sub; display: block; margin-bottom: 16rpx; line-height: 1.4; }
.card-count-badge { position: absolute; top: 20rpx; right: 20rpx; background: rgba(0,0,0,0.05); padding: 4rpx 12rpx; border-radius: 100rpx; }
.count-num { font-size: 22rpx; font-weight: 700; color: $text-main; }

/* 道具卡已使用状态 */
.item-card.used {
  background: #fafafa;
}
.item-card.used .card-name {
  color: $text-sub;
}
.item-card.used .card-desc {
  color: $text-tertiary;
}
.item-card.used .card-icon-wrap {
  background: #f0f0f0;
  opacity: 0.6;
}
.card-used-badge {
  position: absolute;
  top: 20rpx;
  right: 20rpx;
  background: #eee;
  padding: 4rpx 12rpx;
  border-radius: 100rpx;
}
.used-text {
  font-size: 22rpx;
  color: $text-tertiary;
}
.card-use-time {
  font-size: 18rpx;
  color: $text-tertiary;
  margin-top: 12rpx;
  display: block;
  border-top: 1rpx dashed #eee;
  padding-top: 8rpx;
}

/* 任务中心弹窗 */
.task-center-popup { background: $bg-page; }
.task-hero {
  margin: 20rpx;
  border-radius: 24rpx;
  overflow: hidden;
  background: $gradient-brand;
  box-shadow: $shadow-warm;
}
.hero-top {
  padding: 28rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20rpx;
}
.hero-left { flex: 1; }
.hero-title { font-size: 22rpx; color: rgba(255,255,255,0.9); display: block; }
.hero-percent-row { display: flex; align-items: baseline; margin-top: 10rpx; }
.hero-percent { font-size: 54rpx; font-weight: 900; color: #fff; line-height: 1; }
.hero-percent-unit { font-size: 22rpx; font-weight: 700; color: rgba(255,255,255,0.95); margin-left: 8rpx; }
.hero-progress {
  margin-top: 16rpx;
  height: 10rpx;
  background: rgba(255,255,255,0.25);
  border-radius: 100rpx;
  overflow: hidden;
}
.hero-progress-fill {
  height: 100%;
  background: rgba(255,255,255,0.95);
  border-radius: 100rpx;
}
.hero-right {
  display: flex;
  flex-direction: column;
  gap: 12rpx;
  align-items: flex-end;
}
.hero-chip {
  min-width: 140rpx;
  padding: 10rpx 14rpx;
  border-radius: 18rpx;
  background: rgba(255,255,255,0.16);
  border: 1rpx solid rgba(255,255,255,0.22);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10rpx;
}
.chip-num { font-size: 28rpx; font-weight: 900; color: #fff; }
.chip-label { font-size: 20rpx; color: rgba(255,255,255,0.9); }
.task-skeleton-list { padding: 10rpx 0; }
.task-skeleton {
  background: $bg-card;
  border-radius: 20rpx;
  padding: 24rpx;
  margin: 0 20rpx 16rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: $shadow-sm;
}
.sk-left { display: flex; align-items: center; gap: 16rpx; flex: 1; }
.sk-icon { width: 68rpx; height: 68rpx; border-radius: 18rpx; background: rgba(0,0,0,0.06); }
.sk-text { flex: 1; display: flex; flex-direction: column; gap: 12rpx; }
.sk-line { height: 18rpx; border-radius: 10rpx; background: rgba(0,0,0,0.06); }
.sk-line-title { width: 58%; }
.sk-line-desc { width: 78%; }
.sk-btn { width: 140rpx; height: 56rpx; border-radius: 100rpx; background: rgba(0,0,0,0.06); }

.task-card {
  background: $bg-card;
  margin: 0 20rpx 16rpx;
  padding: 24rpx;
  border-radius: 20rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: $shadow-sm;
  border: 1rpx solid rgba(0,0,0,0.02);
}
.task-card:active { transform: scale(0.99); }
.task-card-left { display: flex; align-items: flex-start; gap: 16rpx; flex: 1; min-width: 0; }
.task-icon-bubble {
  width: 72rpx;
  height: 72rpx;
  border-radius: 22rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: rgba($brand-primary, 0.12);
}
.task-ongoing .task-icon-bubble { background: rgba($brand-primary, 0.12); }
.task-waiting .task-icon-bubble { background: rgba(0,0,0,0.06); }
.task-done .task-icon-bubble { background: rgba(16,185,129,0.12); }
.task-icon { font-size: 36rpx; }
.task-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.task-title-row { display: flex; align-items: center; justify-content: space-between; gap: 12rpx; }
.task-name { font-size: $font-md; font-weight: 800; color: $text-main; max-width: 420rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.task-status-tag {
  font-size: 20rpx;
  padding: 4rpx 12rpx;
  border-radius: 100rpx;
  flex-shrink: 0;
}
.task-ongoing .task-status-tag { background: rgba($brand-primary, 0.12); color: $brand-primary; }
.task-waiting .task-status-tag { background: rgba(0,0,0,0.06); color: $text-sub; }
.task-done .task-status-tag { background: rgba(16,185,129,0.12); color: #10B981; }
.task-desc {
  font-size: $font-xs;
  color: $text-sub;
  margin-top: 8rpx;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.task-meta { margin-top: 10rpx; display: flex; gap: 10rpx; flex-wrap: wrap; }
.task-progress-wrap {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 6rpx;
}
.task-progress-bar {
  height: 8rpx;
  background: rgba(0,0,0,0.06);
  border-radius: 100rpx;
  overflow: hidden;
}
.task-progress-fill {
  height: 100%;
  width: 0;
  border-radius: 100rpx;
  background: rgba($brand-primary, 0.9);
}
.task-progress-fill.task-done { background: rgba(16,185,129,0.9); }
.task-progress-fill.task-waiting { background: rgba($brand-primary, 0.4); }
.task-progress-text {
  font-size: 20rpx;
  color: $text-tertiary;
}
.task-reward-chip {
  padding: 4rpx 10rpx;
  border-radius: 10rpx;
  background: #FFF7E6;
  color: #D97706;
  display: flex;
  align-items: center;
  gap: 6rpx;
}
.reward-icon { font-size: 18rpx; }
.reward-text { font-size: 20rpx; font-weight: 700; }
.task-card-right { display: flex; flex-direction: column; align-items: flex-end; gap: 10rpx; margin-left: 16rpx; }
.task-action-btn {
  min-width: 140rpx;
  text-align: center;
  padding: 12rpx 18rpx;
  border-radius: 100rpx;
  font-size: 24rpx;
  font-weight: 700;
  background: $gradient-brand;
  color: #fff;
  box-shadow: $shadow-warm;
}
.task-waiting .task-action-btn { background: rgba($brand-primary, 0.12); color: $brand-primary; box-shadow: none; }
.task-done .task-action-btn { background: #F2F2F2; color: $text-tertiary; box-shadow: none; }

/* 邀请记录 */
.invite-summary { display: flex; padding: 30rpx; background: #fff; margin-bottom: 20rpx; }
.summary-item { flex: 1; display: flex; flex-direction: column; align-items: center; border-right: 1px solid #eee; }
.summary-item:last-child { border: none; }
.summary-num { font-size: 36rpx; font-weight: 900; color: $brand-primary; }
.summary-label { font-size: 22rpx; color: $text-sub; }
.invite-item {
  background: #fff; padding: 20rpx; border-radius: 12rpx; margin-bottom: 16rpx;
  display: flex; align-items: center;
}
.invite-avatar { width: 80rpx; height: 80rpx; border-radius: 50%; margin-right: 20rpx; background: #f0f0f0; }
.invite-info { flex: 1; display: flex; flex-direction: column; }
.invite-name { font-size: $font-md; font-weight: 700; }
.invite-time { font-size: 22rpx; color: $text-tertiary; margin-top: 4rpx; }
.invite-status { font-size: 24rpx; color: #10B981; }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes zoomIn { from { transform: scale(0.9); opacity: 0; } to { transform: scale(1); opacity: 1; } }
</style>
