zhb пре 3 месеци
родитељ
комит
9066771620

+ 18 - 4
pages.json

@@ -123,14 +123,28 @@
       }
     },
     {
-      "path": "pages/customer/index",
+      "path": "pages/activities/index",
+      "style": {
+        "navigationBarTitleText": "",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/activities/content",
+      "style": {
+        "navigationBarTitleText": "",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/activities/detail",
       "style": {
         "navigationBarTitleText": "",
         "navigationStyle": "custom"
       }
     },
     {
-      "path": "pages/customer/activities",
+      "path": "pages/customer/index",
       "style": {
         "navigationBarTitleText": "",
         "navigationStyle": "custom"
@@ -157,14 +171,14 @@
         "navigationStyle": "custom"
       }
     },
-    { 
+    {
       "path": "pages/mine/notice",
       "style": {
         "navigationBarTitleText": "",
         "navigationStyle": "custom"
       }
     },
-    { 
+    {
       "path": "pages/mine/new",
       "style": {
         "navigationBarTitleText": "",

+ 263 - 0
pages/activities/components/ActivityCard.vue

@@ -0,0 +1,263 @@
+<template>
+    <view class="active-box">
+        <!-- 热门标签 -->
+        <view v-if="config.hot" class="btn-tag-star">
+            <uni-icons type="star-filled" size="16" color="#ffd700"></uni-icons>
+        </view>
+
+        <!-- 图片区域 -->
+        <view class="img crm-cursor" @click="handleClick">
+            <image :src="imageSrc" mode="aspectFill" />
+            <view v-if="config.imageTitle" class="imgTitle">{{ t(config.imageTitle) }}</view>
+        </view>
+
+        <!-- 内容区域 -->
+        <view class="content">
+            <view class="title">
+                <span class="name crm-cursor crm-one-font" @click="handleClick">
+                    {{ t(config.title) }}
+                </span>
+                <span v-if="config.time" class="time">{{ config.time }}</span>
+            </view>
+
+            <view v-if="config.description" class="des crm-one-font">
+                {{ t(config.description) }}
+            </view>
+
+            <!-- 按钮区域 -->
+            <view class="bottom">
+                <template v-for="(btn, index) in config.buttons" :key="index">
+                    <!-- 动态条件按钮 -->
+                    <span v-if="shouldShowButton(btn)" :class="['btn', getButtonType(btn)]" @click="handleButtonClick(btn)">
+                        {{ t(btn.text) }}
+                        <template v-if="btn.suffix && state && state[btn.suffix]">
+                            {{ state[btn.suffix] }}
+                        </template>
+                        <template v-if="btn.suffixText">
+                            {{ t(btn.suffixText) }}
+                        </template>
+                    </span>
+
+                    <!-- else 情况 -->
+                    <span v-else-if="btn.elseType && btn.condition" :class="['btn', btn.elseType]">
+                        {{ t(btn.text) }}
+                    </span>
+                </template>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+import { useI18n } from "vue-i18n"
+
+const { t, locale } = useI18n()
+
+const props = defineProps<{
+    config: any
+    state?: Record<string, any>
+}>()
+
+const emit = defineEmits(['action'])
+
+// 图片源
+const imageSrc = computed(() => {
+    if (typeof props.config.image === 'object') {
+        const lang = locale.value || 'en'
+        return props.config.image[lang] || props.config.image.default
+    }
+    return props.config.image
+})
+
+// 判断按钮是否显示
+const shouldShowButton = (btn: any): boolean => {
+    if (!btn.condition) return true
+    
+    // 从 state 中获取值
+    if (!props.state) return false
+    
+    try {
+        // 解析条件表达式
+        const conditionStr = btn.condition
+        // 替换变量为实际值
+        const evalStr = conditionStr.replace(/([a-zA-Z_][a-zA-Z0-9_.]*)/g, (match) => {
+            if (match.includes('.')) {
+                const parts = match.split('.')
+                let value: any = props.state
+                for (const part of parts) {
+                    value = value?.[part]
+                }
+                return JSON.stringify(value)
+            }
+            return JSON.stringify(props.state[match])
+        })
+        
+        // 使用 Function 构造函数安全评估
+        const fn = new Function(`return ${evalStr}`)
+        return fn()
+    } catch (error) {
+        console.error('按钮条件评估失败:', error, btn.condition)
+        return false
+    }
+}
+
+// 获取按钮类型
+const getButtonType = (btn: any): string => {
+    if (btn.type === 'dynamic') {
+        return shouldShowButton(btn) ? 'red' : 'gray'
+    }
+    return btn.type
+}
+
+// 处理点击事件
+const handleClick = () => {
+    if (props.config.onClick) {
+        emit('action', {
+            type: props.config.onClick,
+            params: props.config.onClickParams || []
+        })
+    }
+}
+
+// 处理按钮点击
+const handleButtonClick = (btn: any) => {
+    if (btn.action && btn.action !== 'disabled') {
+        emit('action', {
+            type: btn.action,
+            params: btn.params || []
+        })
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.active-box {
+    position: relative;
+    display: flex;
+    background-color: #fff;
+    border-radius: 16rpx;
+    padding: 30rpx;
+    margin-bottom: 20rpx;
+    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
+
+    .btn-tag-star {
+        position: absolute;
+        top: 0;
+        left: 0;
+        z-index: 1;
+    }
+
+    .img {
+        width: 200rpx;
+        height: 200rpx;
+        margin-right: 30rpx;
+        border-radius: 12rpx;
+        overflow: hidden;
+        position: relative;
+
+        image {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+        }
+
+        .imgTitle {
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            right: 0;
+            background: rgba(0, 0, 0, 0.5);
+            color: #fff;
+            font-size: 24rpx;
+            padding: 8rpx;
+            text-align: center;
+        }
+    }
+
+    .content {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+
+        .title {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            margin-bottom: 10rpx;
+
+            .name {
+                font-size: 32rpx;
+                font-weight: bold;
+                color: #333;
+                flex: 1;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+            }
+
+            .time {
+                font-size: 24rpx;
+                color: #999;
+                margin-left: 16rpx;
+                white-space: nowrap;
+            }
+        }
+
+        .des {
+            font-size: 28rpx;
+            color: #666;
+            margin-bottom: 20rpx;
+            display: -webkit-box;
+            -webkit-line-clamp: 2;
+            -webkit-box-orient: vertical;
+            overflow: hidden;
+            line-height: 1.4;
+        }
+
+        .bottom {
+            display: flex;
+            flex-wrap: wrap;
+            gap: 16rpx;
+
+            .btn {
+                padding: 10rpx 24rpx;
+                border-radius: 40rpx;
+                font-size: 24rpx;
+                font-weight: 500;
+                transition: all 0.3s;
+                display: inline-flex;
+                align-items: center;
+                justify-content: center;
+                white-space: nowrap;
+
+                &.red {
+                    background-color: #ff4d4f;
+                    color: #fff;
+                    border: 1rpx solid #ff4d4f;
+
+                    &:active {
+                        opacity: 0.8;
+                    }
+                }
+
+                &.gray {
+                    background-color: #f5f5f5;
+                    color: #999;
+                    border: 1rpx solid #e5e5e5;
+                }
+
+                &.check {
+                    background-color: #e6f7ff;
+                    color: #1890ff;
+                    border: 1rpx solid #91d5ff;
+
+                    &:active {
+                        opacity: 0.8;
+                    }
+                }
+            }
+        }
+    }
+}
+</style>

+ 429 - 0
pages/activities/composables/activities.ts

@@ -0,0 +1,429 @@
+// 静态活动配置
+export const staticActivityConfigs = [
+    {
+        id: 'NewYear24',
+        title: 'news_add_field1.NewYear24.item1',
+        description: 'news_add_field1.NewYear24.item2',
+        image: '/static/images/cwg-menu-icons-13.jpg',
+        showCondition: 'tableDataNewYear24Flag',
+        hot: true,
+        buttons: [
+            {
+                type: 'red',
+                text: 'news_add_field1.NewYear24.item4',
+                action: 'openCalculator'
+            },
+            {
+                type: 'red',
+                text: 'news_add_field1.NewYear24.item9',
+                action: 'toSingle',
+                params: ['NewYear24']
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.NewYear24.item3',
+                action: 'openPdf',
+                pdf: {
+                    cn: '/pdf/pdf3/pdf-cn.pdf',
+                    zhHant: '/pdf/pdf3/pdf-zhHant.pdf',
+                    default: '/pdf/pdf3/pdf-en.pdf'
+                }
+            }
+        ]
+    },
+    {
+        id: 'monthlyGift',
+        title: 'MonthlyActivities.item1',
+        description: 'MonthlyActivities.item1_1',
+        image: '/static/images/yue.jpg',
+        showCondition: "country === 'CN'",
+        hot: true,
+        buttons: [
+            {
+                type: 'dynamic',
+                text: 'news_add_field1.activities10_trading_aoyun.item3',
+                action: 'openSurplusActivityDialog1',
+                condition: 'monthlyGive'
+            },
+            {
+                type: 'check',
+                text: 'wallet.item15',
+                action: 'openPdf',
+                pdf: '/pdf/pdf13/CWG Prime Bonus-cn.pdf'
+            },
+            {
+                type: 'check',
+                text: 'Transfer.item7',
+                action: 'openPdf',
+                pdf: '/pdf/pdf13/CWG Markets Prime Bonus Application Process-cn.pdf'
+            },
+            {
+                type: 'check',
+                text: 'wallet.item14',
+                action: 'goMonthlyTaskList'
+            }
+        ]
+    },
+    {
+        id: 'bonusGift',
+        title: 'surplusList.item1',
+        description: 'surplusList.item2',
+        image: '/static/images/su.png',
+        hot: true,
+        buttons: [
+            {
+                type: 'dynamic',
+                text: 'news_add_field1.activities10_trading_aoyun.item3',
+                action: 'openSurplusActivityDialog',
+                condition: 'surplusGive'
+            },
+            {
+                type: 'check',
+                text: 'wallet.item15',
+                action: 'openPdf',
+                pdf: {
+                    dynamic: true,
+                    path: '/pdf/pdf12/CWG Prime Bonus-{lang}.pdf'
+                }
+            },
+            {
+                type: 'check',
+                text: 'Transfer.item7',
+                action: 'openPdf',
+                pdf: {
+                    dynamic: true,
+                    path: '/pdf/pdf12/CWG Markets Prime Bonus Application Process-{lang}.pdf',
+                    fallback: '/pdf/pdf12/CWG Markets Prime Bonus Application Process-en.pdf',
+                    supportedLangs: ['cn', 'zhHant', 'en']
+                }
+            },
+            {
+                type: 'check',
+                text: 'wallet.item14',
+                action: 'goSurplusTaskList'
+            }
+        ]
+    },
+    {
+        id: 'cashCarnival',
+        title: 'wallet.item8',
+        description: 'wallet.item9',
+        image: '/static/images/cash-carnival.webp',
+        imageTitle: 'wallet.item8',
+        showCondition: 'choujiaClose',
+        hot: true,
+        onClick: 'toSingle',
+        onClickParams: ['23jnhcj'],
+        buttons: [
+            {
+                type: 'red',
+                text: 'wallet.item10',
+                action: 'toHistoryLuckyDraw',
+                suffix: 'LuckyDrawsNumber',
+                suffixText: 'wallet.item11'
+            },
+            {
+                type: 'check',
+                text: 'wallet.item12',
+                action: 'toOpenTask'
+            },
+            {
+                type: 'dynamic',
+                text: 'wallet.item13',
+                action: 'toNewTask',
+                condition: 'newTask',
+                elseType: 'gray'
+            },
+            {
+                type: 'check',
+                text: 'wallet.item14',
+                action: 'toTaskList'
+            },
+            {
+                type: 'check',
+                text: 'wallet.item15',
+                action: 'openPdf',
+                pdf: {
+                    dynamic: true,
+                    langMap: {
+                        ar: '/pdf/pdf5/ar.pdf',
+                        cn: '/pdf/pdf5/cn.pdf',
+                        de: '/pdf/pdf5/en.pdf',
+                        en: '/pdf/pdf5/en.pdf',
+                        es: '/pdf/pdf5/es.pdf',
+                        fa: '/pdf/pdf5/en.pdf',
+                        id: '/pdf/pdf5/en.pdf',
+                        ko: '/pdf/pdf5/ko.pdf',
+                        ms: '/pdf/pdf5/en.pdf',
+                        pt: '/pdf/pdf5/pt.pdf',
+                        th: '/pdf/pdf5/th.pdf',
+                        tr: '/pdf/pdf5/en.pdf',
+                        vn: '/pdf/pdf5/vn.pdf',
+                        zhHant: '/pdf/pdf5/zhHant.pdf'
+                    }
+                }
+            }
+        ]
+    },
+    {
+        id: 'noWorries',
+        title: 'news_add_field1.activitiesNoWorries.item1',
+        description: 'news_add_field1.activitiesNoWorries.item2',
+        image: '/static/images/jihua.png',
+        showCondition: 'tableDataNoWorriesFlag',
+        hot: true,
+        onClick: 'toSingle',
+        onClickParams: ['NoWorries'],
+        buttons: [
+            {
+                type: 'red',
+                text: 'news_add_field1.activitiesNoWorries.item3',
+                action: 'toApplyNoWorriesOpen',
+                condition: 'tableDataNoWorries === true'
+            },
+            {
+                type: 'red',
+                text: 'news_add_field1.activitiesNoWorries.item4',
+                action: 'toRealizationNoWorries',
+                condition: 'isRealizationNoWorries === 1',
+                elseType: 'gray'
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.activitiesNoWorries.item5',
+                action: 'toSingle',
+                params: ['NoWorries']
+            }
+        ]
+    },
+    {
+        id: 'standardRewards',
+        title: 'news_add_field1.activities10_trading_aoyun.item5',
+        description: 'news_add_field1.activities10_trading_aoyun.item6',
+        image: '/static/images/trading-rewards.webp',
+        showCondition: 'standard',
+        buttons: [
+            {
+                type: 'red',
+                text: 'news_add_field1.activities10_trading_aoyun.item3',
+                action: 'toActivity24Trading'
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.activities10_trading_aoyun.item4',
+                action: 'openPdf',
+                pdf: {
+                    dynamic: true,
+                    langMap: {
+                        ar: '/pdf/pdf1/ar.pdf',
+                        cn: '/pdf/pdf1/cn.pdf',
+                        de: '/pdf/pdf1/en.pdf',
+                        en: '/pdf/pdf1/en.pdf',
+                        es: '/pdf/pdf1/es.pdf',
+                        fa: '/pdf/pdf1/en.pdf',
+                        id: '/pdf/pdf1/en.pdf',
+                        ko: '/pdf/pdf1/ko.pdf',
+                        ms: '/pdf/pdf1/en.pdf',
+                        pt: '/pdf/pdf1/pt.pdf',
+                        th: '/pdf/pdf1/th.pdf',
+                        tr: '/pdf/pdf1/en.pdf',
+                        vn: '/pdf/pdf1/vn.pdf',
+                        zhHant: '/pdf/pdf1/zhHant.pdf'
+                    }
+                }
+            }
+        ]
+    },
+    {
+        id: 'bonus10',
+        title: 'news_add_field1.activities10_trading_aoyun.item1',
+        description: 'news_add_field1.activities10_trading_aoyun.item2_1',
+        image: '/static/images/10-bonus.webp',
+        showCondition: '!isAfterSeptember30() && !isSupportedCountry',
+        buttons: [
+            {
+                type: 'red',
+                text: 'news_add_field1.activities10_trading_aoyun.item3',
+                action: 'toActivity24nianzhong'
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.activities10_trading_aoyun.item4',
+                action: 'openPdf',
+                pdf: {
+                    dynamic: true,
+                    path: '/pdf/pdf4/{lang}.pdf'
+                }
+            }
+        ]
+    },
+    {
+        id: 'bonus100',
+        title: 'news_add_field1.activities10_trading_aoyun.item1_2',
+        description: 'news_add_field1.activities10_trading_aoyun.item2_12',
+        image: '/static/images/100-bonus.webp',
+        showCondition: '!isAfterSeptember30() && isSupportedCountry',
+        buttons: [
+            {
+                type: 'red',
+                text: 'news_add_field1.activities10_trading_aoyun.item3',
+                action: 'toActivity24nianzhong'
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.activities10_trading_aoyun.item4',
+                action: 'openPdf',
+                pdf: {
+                    dynamic: true,
+                    path: '/pdf/pdf4/100Bonus-{lang}.pdf'
+                }
+            }
+        ]
+    },
+    {
+        id: 'welcome2023',
+        title: 'news_add_field1.activities.item8',
+        description: '',
+        image: {
+            cn: '/static/images/23ActiveCn.jpg',
+            zhHant: '/static/images/23ActiveCn1.jpg',
+            default: '/static/images/23ActiveEn.jpg'
+        },
+        showCondition: 'tableData2Flag',
+        hot: true,
+        onClick: 'toSingle',
+        onClickParams: ['23yx'],
+        buttons: [
+            {
+                type: 'red',
+                text: 'news_add_field1.activities.item4',
+                action: 'toApply23Open',
+                condition: 'tableData2 === true'
+            },
+            {
+                type: 'gray',
+                text: 'news_add_field1.activities.item4',
+                condition: 'tableData2 === false'
+            },
+            {
+                type: 'gray',
+                text: 'news_add_field1.activities.item5',
+                condition: 'typeof tableData2 === "object"'
+            },
+            {
+                type: 'red',
+                text: 'news_add_field1.activities.item9',
+                action: 'toTransform',
+                condition: 'isTransform === 1'
+            },
+            {
+                type: 'gray',
+                text: 'news_add_field1.activities.item9',
+                condition: 'isTransform === 2'
+            },
+            {
+                type: 'red',
+                text: 'news_add_field1.activities.item0',
+                action: 'toRealization',
+                condition: 'isRealization === 1'
+            },
+            {
+                type: 'gray',
+                text: 'news_add_field1.activities.item0',
+                condition: 'isRealization === 2'
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.activities.item7',
+                action: 'toSingle',
+                params: ['23yx']
+            }
+        ]
+    },
+    {
+        id: 'tradingCompetition',
+        title: 'news_add_field1.activitiesJYDS2025.item1',
+        description: 'news_add_field1.activitiesJYDS2025.item2',
+        image: '/static/images/banner.jpg',
+        showCondition: 'tableDataCptFlag',
+        hot: true,
+        onClick: 'toSingle',
+        onClickParams: ['23xinjia'],
+        buttons: [
+            {
+                type: 'red',
+                text: 'news_add_field1.activitiesJYDS.item3',
+                action: 'toApplyCptOpen',
+                condition: 'tableDataCpt.signStatus === 0'
+            },
+            {
+                type: 'gray',
+                text: 'news_add_field1.activitiesJYDS.item3_1',
+                condition: 'tableDataCpt.signStatus === 1'
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.activitiesJYDS.item4',
+                action: 'toSingle',
+                params: ['23xinjia']
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.activitiesJYDS.item4_1',
+                action: 'toOpenSingle',
+                params: ['tableDataCpt.pageAddress']
+            }
+        ]
+    },
+    {
+        id: 'eliteCup24',
+        title: 'news_add_field1.activitiesJYB.item1',
+        description: 'news_add_field1.activitiesJYB.item2',
+        image: '/static/images/jyb.jpg',
+        showCondition: 'tableData3FlagJYB',
+        onClick: 'toSingle',
+        onClickParams: ['24JYB'],
+        buttons: [
+            {
+                type: 'red',
+                text: 'news_add_field1.activitiesJYB.item3',
+                action: 'toApply24JYBOpenVip',
+                condition: 'tableData3JYB.show === 1 && timeExpireJx(tableData3JYB.applicationEndTime)'
+            },
+            {
+                type: 'gray',
+                text: 'news_add_field1.activitiesJYB.item3',
+                action: 'openDialog',
+                params: ['dialogChinaUnionPayJX'],
+                condition: 'tableData3JYB.show === 1 && !timeExpireJx(tableData3JYB.applicationEndTime)'
+            },
+            {
+                type: 'red',
+                text: 'news_add_field1.activitiesJYB.item4',
+                action: 'toRealization24JYBVip',
+                condition: 'isRealizationJxJYB === 1'
+            },
+            {
+                type: 'gray',
+                text: 'news_add_field1.activitiesJYB.item4',
+                condition: 'isRealizationJxJYB === 2'
+            },
+            {
+                type: 'check',
+                text: 'news_add_field1.activitiesJYB.item5',
+                action: 'toSingle',
+                params: ['24JYB']
+            }
+        ]
+    }
+]
+export const countries = [
+    "DZ", "AO", "BJ", "BW", "BF", "CM", "CG", "CD", "CI", "DJ", "EG", "ET", "GA", "GM", "GH", "GN", "KE",
+    "MG", "MW", "ML", "MR", "MA", "MZ", "NA", "NE", "NG", "RW", "SN", "SL", "SO", "ZA", "SS", "SD", "TZ",
+    "TG", "TN", "UG", "ZM", "ZW", "LS", "BH", "IR", "IQ", "IL", "JO", "KW", "LB", "OM", "PS", "QA", "SA",
+    "SY", "TR", "AE", "YE", "AR", "BO", "BR", "CL", "CO", "EC", "GY", "PY", "PE", "SR", "UY", "VE", "BZ",
+    "CR", "SV", "GT", "HN", "NI", "PA", "AU", "CA", "AL", "AD", "AM", "AT", "AZ", "BY", "BE", "BA", "BG",
+    "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "GE", "DE", "GR", "HU", "IS", "IE", "IT", "XK", "LV", "LI",
+    "LT", "LU", "MT", "MD", "MC", "ME", "NL", "MK", "NO", "PL", "PT", "RO", "RU", "SM", "RS", "SK", "SI",
+    "ES", "SE", "CH", "UA", "VA"
+]

+ 25 - 0
pages/activities/composables/evaluate.ts

@@ -0,0 +1,25 @@
+// utils/evaluate.ts
+export function createConditionEvaluator(component: any) {
+    return (condition: string): boolean => {
+        if (!condition) return true
+        
+        try {
+            // 使用 with 语句创建一个作用域,包含组件实例的所有属性
+            const fn = new Function('component', `
+                with (component) {
+                    try {
+                        return ${condition}
+                    } catch (e) {
+                        console.error('条件执行错误:', e)
+                        return false
+                    }
+                }
+            `)
+            
+            return fn(component)
+        } catch (error) {
+            console.error('条件评估失败:', error, condition)
+            return false
+        }
+    }
+}

+ 0 - 0
pages/customer/activities.vue → pages/activities/content.vue


+ 0 - 0
pages/activities/detail.vue


+ 1787 - 0
pages/activities/index.vue

@@ -0,0 +1,1787 @@
+<template>
+    <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
+        <view class="custom_activities">
+            <view class="info-card">
+                <view class="content-title">
+                    <view v-t="'Home.page_customer.item6'"></view>
+                </view>
+
+                <!-- 主要内容 -->
+                <view class="main-content">
+                    <scroll-view class="tab" scroll-y :scroll-top="scrollTop" @scrolltolower="loadMore"
+                        refresher-enabled :refresher-triggered="refreshing" @refresherrefresh="onRefresh">
+                        <!-- 遍历静态活动配置 -->
+                        <ActivityCard v-for="activity in visibleStaticActivities" :key="activity.id" :config="activity"
+                            :state="activityState" @action="handleActivityAction" />
+
+                        <!-- 动态活动列表 -->
+                        <ActivityCard v-for="item in tableData" :key="'dynamic-' + item.id"
+                            :config="createDynamicConfig(item)" :state="activityState" @action="handleActivityAction" />
+
+                        <!-- 赠送活动列表 -->
+                        <ActivityCard v-for="item in tableDataGive" :key="'give-' + item.id"
+                            :config="createGiveConfig(item)" :state="activityState" @action="handleActivityAction" />
+
+                        <!-- 加载更多状态 -->
+                        <view v-if="loadingMore" class="loading-more">
+                            <uni-icons type="spinner-cycle" size="20" color="#999" class="spin"></uni-icons>
+                            <text>{{ t('common.loadingMore') }}</text>
+                        </view>
+
+                        <!-- 没有更多数据 -->
+                        <view v-if="!hasMore && tableData.length > 0" class="no-more">
+                            <text>{{ t('common.noMore') }}</text>
+                        </view>
+                    </scroll-view>
+                </view>
+
+                <!-- 活动申请弹窗 -->
+                <uni-popup ref="popupApply" type="center" :mask-click="false">
+                    <view class="popup-content">
+                        <view class="popup-header">
+                            <text class="popup-title">{{ t('Custom.Activity.Apply') }}</text>
+                            <uni-icons type="closeempty" size="20" color="#999" @click="closeApplyPopup"></uni-icons>
+                        </view>
+                        <scroll-view class="popup-body" scroll-y>
+                            <view class="form-item">
+                                <text class="form-label">{{ t('Label.TradingAccount') }}</text>
+                                <picker mode="selector" :range="loginOptions" range-key="login" @change="onLoginChange">
+                                    <view class="picker-value">{{ selectedLogin ? selectedLogin.login :
+                                        t('placeholder.choose')
+                                    }}</view>
+                                </picker>
+                            </view>
+                        </scroll-view>
+                        <view class="popup-footer">
+                            <button class="btn-cancel" @click="closeApplyPopup">{{ t('Btn.Cancel') }}</button>
+                            <button class="btn-confirm" type="primary" @click="confirmApply">{{ t('Btn.Confirm')
+                            }}</button>
+                        </view>
+                    </view>
+                </uni-popup>
+
+                <!-- Surplus活动弹框 -->
+                <uni-popup ref="popupSurplusActivity" type="center" :mask-click="false">
+                    <view class="popup-content" style="width: 650rpx;">
+                        <view class="popup-header">
+                            <text class="popup-title">{{ t('surplusList.item1') }}</text>
+                            <uni-icons type="closeempty" size="20" color="#999"
+                                @click="closeSurplusActivityDialog"></uni-icons>
+                        </view>
+                        <scroll-view class="popup-body" scroll-y style="max-height: 800rpx;">
+                            <view class="form-item">
+                                <text class="form-label">{{ t('Custom.Deposit.Title1') }}:</text>
+                                <picker mode="selector" :range="loginOptions1" range-key="login"
+                                    @change="onLogin1Change">
+                                    <view class="picker-value">{{ selectedAccount ? selectedAccount.login :
+                                        t('placeholder.choose')
+                                    }}</view>
+                                </picker>
+                            </view>
+                            <view class="form-item" v-if="selectedAccount">
+                                <text class="form-label">{{ t('surplusList.item3') }}:</text>
+                                <picker mode="selector" :range="surplusActivityOptions" range-key="label"
+                                    @change="onSurplusActivityChange">
+                                    <view class="picker-value">{{ selectedSurplusActivityLabel ||
+                                        t('placeholder.choose') }}</view>
+                                </picker>
+                            </view>
+                        </scroll-view>
+                        <view class="popup-footer">
+                            <button class="btn-cancel" @click="closeSurplusActivityDialog">{{ t('Btn.Cancel')
+                            }}</button>
+                            <button class="btn-confirm" type="primary" @click="confirmSurplusActivity"
+                                :disabled="!selectedSurplusActivity || !selectedAccount">{{ t('Btn.Confirm') }}</button>
+                        </view>
+                    </view>
+                </uni-popup>
+
+                <!-- 月赏礼遇弹框 -->
+                <uni-popup ref="popupMonthlyActivity" type="center" :mask-click="false">
+                    <view class="popup-content" style="width: 650rpx;">
+                        <view class="popup-header">
+                            <text class="popup-title">{{ t('MonthlyActivities.item1') }}</text>
+                            <uni-icons type="closeempty" size="20" color="#999"
+                                @click="closeSurplusActivityDialog1"></uni-icons>
+                        </view>
+                        <scroll-view class="popup-body" scroll-y>
+                            <view class="form-item">
+                                <text class="form-label" style="font-size: 32rpx; font-weight: bold;">{{
+                                    t('MonthlyActivities.item8') }}</text>
+                            </view>
+                        </scroll-view>
+                        <view class="popup-footer">
+                            <button class="btn-cancel" @click="closeSurplusActivityDialog1">{{ t('Btn.Cancel')
+                            }}</button>
+                            <button class="btn-confirm" type="primary" @click="confirmSurplusActivity1">{{
+                                t('Btn.Confirm') }}</button>
+                        </view>
+                    </view>
+                </uni-popup>
+
+                <!-- 收益模拟器弹框 -->
+                <uni-popup ref="popupCalculator" type="center" :mask-click="false">
+                    <view class="popup-content" style="width: 650rpx;">
+                        <view class="popup-header">
+                            <text class="popup-title">{{ t('news_add_field1.NewYear24.item4') }}</text>
+                            <uni-icons type="closeempty" size="20" color="#999" @click="closeCalculator"></uni-icons>
+                        </view>
+                        <view class="popup-body">
+                            <view class="form-item">
+                                <text class="form-label">{{ t('news_add_field1.NewYear24.item5') }}</text>
+                                <input type="number" v-model="NewYear24DataBalance" class="calculator-input"
+                                    :placeholder="t('placeholder.input')" />
+                            </view>
+                            <view class="calculator-tip">
+                                <text>{{ t('news_add_field1.NewYear24.item6') }}</text>
+                                <text class="red">${{ NewYear24Data.balance }}</text>
+                                <text>{{ t('news_add_field1.NewYear24.item7') }}</text>
+                                <text class="red">${{ NewYear24Data.income }}</text>
+                                <text>{{ t('news_add_field1.NewYear24.item8') }}</text>
+                            </view>
+                        </view>
+                        <view class="popup-footer">
+                            <button class="btn-cancel" @click="closeCalculator">{{
+                                t('news_add_field1.NewYear24.item8_2') }}</button>
+                            <button class="btn-confirm" type="primary" @click="calculateIncome">{{
+                                t('news_add_field1.NewYear24.item8_1') }}</button>
+                        </view>
+                    </view>
+                </uni-popup>
+
+                <!-- 新任务弹框 -->
+                <uni-popup ref="popupNewTask" type="center" :mask-click="false">
+                    <view class="popup-content" style="width: 650rpx;">
+                        <view class="popup-header">
+                            <text class="popup-title">{{ t('wallet.item16') }}</text>
+                            <uni-icons type="closeempty" size="20" color="#999" @click="closeNewTask"></uni-icons>
+                        </view>
+                        <view class="popup-body">
+                            <view class="task-info">
+                                <text>{{ t('wallet.item17') }}{{ newTaskList.endTime }}</text>
+                                <text>{{ t('wallet.item18') }}{{ newTaskList.tradeVolume }}</text>
+                                <text>{{ t('wallet.item19') }}{{ newTaskList.raffleNumber }}</text>
+                                <text>{{ t('wallet.item20') }}</text>
+                            </view>
+                        </view>
+                        <view class="popup-footer">
+                            <button class="btn-cancel" @click="closeNewTask">{{ t('Home.msg.item3') }}</button>
+                            <button class="btn-confirm" type="primary" @click="closeNewTask">{{ t('Btn.Confirm')
+                            }}</button>
+                        </view>
+                    </view>
+                </uni-popup>
+
+                <!-- 过期提示弹框 -->
+                <uni-popup ref="popupExpired" type="center" :mask-click="false">
+                    <view class="popup-content" style="width: 650rpx;">
+                        <view class="popup-header">
+                            <text class="popup-title">{{ t('common.tip') }}</text>
+                            <uni-icons type="closeempty" size="20" color="#999" @click="closeExpiredPopup"></uni-icons>
+                        </view>
+                        <view class="popup-body">
+                            <text class="expired-text">{{ t('news_add_field1.activitiesJX.item24') }}</text>
+                        </view>
+                        <view class="popup-footer">
+                            <button class="btn-cancel" @click="closeExpiredPopup">{{ t('Btn.Cancel') }}</button>
+                            <button class="btn-confirm" type="primary" @click="closeExpiredPopup">{{ t('Btn.Confirm')
+                            }}</button>
+                        </view>
+                    </view>
+                </uni-popup>
+            </view>
+        </view>
+    </cwg-page-wrapper>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, computed, onMounted } from 'vue'
+import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
+import { useI18n } from 'vue-i18n'
+import ActivityCard from './components/ActivityCard.vue'
+import { staticActivityConfigs, countries } from './composables/activities'
+import { activityApi } from '@/service/activity'
+import { customApi } from '@/service/custom'
+import Config from '@/config/index'
+
+const { t, locale } = useI18n()
+const { Code, Host80 } = Config
+
+// ==================== 状态变量 ====================
+// 用户信息
+const userInfo = computed(() => {
+    try {
+        return JSON.parse(uni.getStorageSync('user') || '{}')
+    } catch {
+        return { customInfo: {} }
+    }
+})
+const country = computed(() => userInfo.value.customInfo?.country || '')
+const myCid = computed(() => userInfo.value.customInfo?.cId || '')
+
+// 加载状态
+const pictLoading = ref(false)
+const refreshing = ref(false)
+const loadingMore = ref(false)
+const scrollTop = ref(0)
+const hasMore = ref(true)
+const pageNum = ref(1)
+const pageSize = ref(10)
+
+// 活动数据
+const tableData = ref<any[]>([])
+const tableDataGive = ref<any[]>([])
+const loginOptions = ref<any[]>([])
+const loginOptions1 = ref<any[]>([])
+const selectedLogin = ref<any>(null)
+const selectedAccount = ref<any>(null)
+const selectedSurplusActivity = ref<any>(null)
+const selectedSurplusActivityLabel = ref('')
+const surplusActivityOptions = ref<any[]>([])
+const surplusActivityLoading = ref(false)
+
+// ==================== 活动特定状态 ====================
+const tableDataNewYear24Flag = ref(false)
+const tableDataNewYear24 = ref<any>({})
+const choujiaClose = ref(false)
+const tableDataNoWorriesFlag = ref(false)
+const tableDataNoWorries = ref<any>(false)
+const isRealizationNoWorries = ref(0)
+const standard = ref(false)
+const tableData2Flag = ref(false)
+const tableData2 = ref<any>(false)
+const isTransform = ref(0)
+const isRealization = ref(0)
+const tableDataCptFlag = ref(false)
+const tableDataCpt = ref<any>({})
+const tableDataCptFlagCode = ref('')
+const tableData3FlagJYB = ref(false)
+const tableData3JYB = ref<any>({})
+const isRealizationJxJYB = ref(0)
+const tableData3Flag = ref(false)
+const tableData3 = ref<any>({})
+const isRealizationJx = ref(0)
+const tableData3FlagVip = ref(false)
+const tableData3Vip = ref<any>({})
+const isRealizationJxVip = ref(0)
+const tableData4Flag = ref(false)
+const tableData4 = ref<any>({})
+const tableData4TwoFlag = ref(false)
+const tableData4Two = ref<any>({})
+const monthlyGive = ref(false)
+const surplusGive = ref(false)
+const newTask = ref(false)
+const newTaskList = ref({ endTime: '', tradeVolume: '', raffleNumber: '' })
+const LuckyDrawsNumber = ref('0')
+const isCountDown = ref('')
+const isCashBack = ref(false)
+const anshiClose = ref(true)
+const limitedStatus = ref(null)
+const activityShowsInfo = ref<any>(null)
+
+// 新年庆典相关
+const NewYear24DataBalance = ref('')
+const NewYear24Data = ref({ balance: 0, income: 0 })
+
+// ==================== 弹窗引用 ====================
+const popupApply = ref<any>(null)
+const popupSurplusActivity = ref<any>(null)
+const popupMonthlyActivity = ref<any>(null)
+const popupCalculator = ref<any>(null)
+const popupNewTask = ref<any>(null)
+const popupExpired = ref<any>(null)
+
+// ==================== 计算属性 ====================
+// 传递给子组件的状态对象
+const activityState = computed(() => ({
+    country: country.value,
+    lang: locale.value,
+    monthlyGive: monthlyGive.value,
+    surplusGive: surplusGive.value,
+    newTask: newTask.value,
+    LuckyDrawsNumber: LuckyDrawsNumber.value,
+    tableDataNoWorries: tableDataNoWorries.value,
+    isRealizationNoWorries: isRealizationNoWorries.value,
+    tableData2: tableData2.value,
+    isTransform: isTransform.value,
+    isRealization: isRealization.value,
+    tableDataCpt: tableDataCpt.value,
+    tableData3JYB: tableData3JYB.value,
+    isRealizationJxJYB: isRealizationJxJYB.value
+}))
+
+// 可见的静态活动
+const visibleStaticActivities = computed(() => {
+    return staticActivityConfigs.filter(config => {
+        if (!config.showCondition) return true
+
+        // 根据条件字符串判断
+        switch (config.showCondition) {
+            case 'tableDataNewYear24Flag':
+                return tableDataNewYear24Flag.value
+            case "country === 'CN'":
+                return country.value === 'CN'
+            case 'choujiaClose':
+                return choujiaClose.value
+            case 'tableDataNoWorriesFlag':
+                return tableDataNoWorriesFlag.value
+            case 'standard':
+                return standard.value
+            case 'tableData2Flag':
+                return tableData2Flag.value
+            case 'tableDataCptFlag':
+                return true
+            case 'tableData3FlagJYB':
+                return tableData3FlagJYB.value
+            case '!isAfterSeptember30() && !isSupportedCountry':
+                return !isAfterSeptember30() && !isSupportedCountry.value
+            case '!isAfterSeptember30() && isSupportedCountry':
+                return !isAfterSeptember30() && isSupportedCountry.value
+            default:
+                return true
+        }
+    })
+})
+
+// 是否支持的国家
+const isSupportedCountry = computed(() => {
+    return countries.includes(country.value)
+})
+
+// ==================== 工具方法 ====================
+// 获取当前时间(带时区)
+const getCurrentTime = () => {
+    const timezone = 2 // 东3区
+    const offset_GMT = new Date().getTimezoneOffset()
+    const nowDate = new Date().getTime()
+    return new Date(nowDate + offset_GMT * 60 * 1000 + timezone * 60 * 60 * 1000)
+}
+
+// 判断是否在9月30日之后
+const isAfterSeptember30 = () => {
+    // const currentDate = new Date();
+    // const september30 = new Date(
+    //   currentDate.getFullYear(),
+    //   8,
+    //   30,
+    //   23,
+    //   59,
+    //   59
+    // );
+    // return currentDate > september30;
+    return true
+}
+
+// 判断活动是否过期
+const timeExpireJx = (endTime: string) => {
+    if (!endTime) return false
+    const endTime1 = endTime.replace(/-/g, '/').split(' ')[0]
+    const now = getCurrentTime().getTime()
+    const end = new Date(endTime1).getTime()
+    return now < end
+}
+
+// 判断活动是否在有效期内
+const overdue = (startTime: string, endTime: string) => {
+    if (!startTime || !endTime) return false
+    const startTime1 = startTime.replace(/-/g, '/').split(' ')[0]
+    const endTime1 = endTime.replace(/-/g, '/').split(' ')[0]
+    const now = getCurrentTime().getTime()
+    const start = new Date(startTime1).getTime()
+    const end = new Date(endTime1).getTime()
+    return start < now && now < end
+}
+
+// 时间补0
+const getzero = (time: number) => {
+    return time > 9 ? time : '0' + time
+}
+
+// 时间格式转换
+const timeConvert = (val: string) => {
+    if (val) {
+        const datetime = new Date(val.replace(/-/g, '/'))
+        const year = datetime.getFullYear()
+        let month: any = datetime.getMonth() + 1
+        let date: any = datetime.getDate()
+        if (month < 10) month = '0' + month
+        if (date < 10) date = '0' + date
+        return year + '年' + month + '月' + date + '日'
+    }
+    return ''
+}
+
+// 货币符号
+const groupCurrency = (type: string) => {
+    if (type == 'GBP') return ': £'
+    if (type == 'USD') return ': $'
+    if (type == 'EUR') return ': €'
+    if (type == 'USC') return ': ¢'
+    return ': $'
+}
+
+// 账户类型名称
+const groupTypeName = (type: string) => {
+    if (type == '1') return t('AccountType.ClassicAccount')
+    if (type == '2') return t('AccountType.SeniorAccount')
+    if (type == '3') return t('AccountType.AgencyAccount')
+    if (type == '5') return t('AccountType.SpeedAccount')
+    if (type == '6') return t('AccountType.SpeedAccount')
+    if (type == '7') return t('AccountType.StandardAccount')
+    if (type == '8') return t('AccountType.CentAccount')
+    return ''
+}
+
+// ==================== 数据加载方法 ====================
+// 获取账户信息
+const getDateList = async () => {
+    try {
+        const res = await customApi.DropdownlusActivityOptions({ platform: '' })
+        if (res.code == Code.StatusOK) {
+            loginOptions1.value = res.data
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取账户信息失败', error)
+    }
+}
+
+// 获取活动列表
+const searchFunc = async () => {
+    pictLoading.value = true
+    try {
+        const res = await activityApi.ActivityExtensionIist({
+            hot: '',
+            tag: 1,
+            lang: ['cn', 'zhHant'].includes(locale.value) ? 'cn' : 'en',
+            page: {
+                current: pageNum.value,
+                row: pageSize.value
+            }
+        })
+
+        if (res.code == Code.StatusOK) {
+            tableData.value = res.data
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取活动列表失败', error)
+    } finally {
+        pictLoading.value = false
+    }
+}
+
+// 获取赠送活动列表
+const searchFunc1 = async () => {
+    try {
+        const res = await activityApi.ActivityExtensionGiveList({
+            page: {
+                current: pageNum.value,
+                row: pageSize.value
+            }
+        })
+        if (res.code == Code.StatusOK) {
+            tableDataGive.value = res.data
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取赠送活动列表失败', error)
+    }
+}
+
+// 20赠金活动数据
+const getActivityPercentageGiveInfo = async () => {
+    try {
+        const res = await activityApi.ActivityPercentageGiveInfo({})
+        if (res.code == Code.StatusOK) {
+            tableData1.value = res.data
+            if (typeof tableData1.value == 'object') {
+                const startTime = new Date(tableData1.value.activityStartTime.replace(/-/g, '/')).getTime()
+                const nowTime = getCurrentTime().getTime()
+
+                if (nowTime < startTime) {
+                    // 开始倒计时
+                    const interval = setInterval(() => {
+                        const now = getCurrentTime().getTime()
+                        const time = startTime - now
+                        const day = Math.floor(time / (24 * 60 * 60 * 1000))
+                        const hour = Math.floor((time % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000))
+                        const min = Math.floor((time % (60 * 60 * 1000)) / (60 * 1000))
+                        const sec = Math.floor((time % (60 * 1000)) / 1000)
+                        isCountDown.value = `${getzero(day)}${t('Label.Day')}${getzero(hour)}:${getzero(min)}:${getzero(sec)}`
+
+                        if (now >= startTime) {
+                            clearInterval(interval)
+                            getActivityPercentageGiveInfo()
+                        }
+                    }, 1000)
+                } else if (nowTime > startTime && tableData1.value.status == 0) {
+                    isCashBack.value = true
+                }
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取20赠金活动数据失败', error)
+    }
+}
+
+// 2023迎新活动数据
+const Activity23HundredInfo = async () => {
+    try {
+        const res = await activityApi.Activity23HundredInfo({})
+        if (res.code == Code.StatusOK) {
+            tableData2.value = res.data
+            if (typeof tableData2.value == 'object') {
+                tableData2Flag.value = true
+                const nowTime = getCurrentTime().getTime()
+                const startTime = new Date(tableData2.value.activityStartTime.replace(/-/g, '/')).getTime()
+                const endTime = new Date(tableData2.value.activityEndTime.replace(/-/g, '/')).getTime()
+
+                if (nowTime < endTime && nowTime > startTime) {
+                    if (tableData2.value.status == 2 && tableData2.value.activityStatus == 0) {
+                        isTransform.value = 1
+                    } else if (tableData2.value.status == 2 &&
+                        (tableData2.value.activityStatus == 1 ||
+                            (tableData2.value.balanceStatus != 2 && tableData2.value.creditStatus != 2))) {
+                        isTransform.value = 2
+                    } else if (tableData2.value.status == 2 && tableData2.value.activityStatus == 3) {
+                        isTransform.value = 2
+                    }
+                } else {
+                    isTransform.value = 2
+                }
+
+                if (tableData2.value.status == 2 && tableData2.value.activityStatus == 2) {
+                    isTransform.value = null
+                    if (tableData2.value.realizationStatus == 0) {
+                        isRealization.value = 1
+                    } else if (tableData2.value.realizationStatus == 1 ||
+                        (tableData2.value.realizationCreditStatus != 2 && tableData2.value.realizationBalanceStatus != 2)) {
+                        isRealization.value = 2
+                    } else if (tableData2.value.realizationStatus == 3) {
+                        isRealization.value = 2
+                    }
+                } else {
+                    isRealization.value = null
+                }
+            } else {
+                if (tableData2.value) {
+                    tableData2Flag.value = true
+                }
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+            tableData2.value = true
+        }
+    } catch (error) {
+        console.error('获取2023迎新活动数据失败', error)
+    }
+}
+
+// 2023匠鑫活动数据
+const Activity23JiangxinInfo = async () => {
+    try {
+        const res = await activityApi.Activity23JiangxinInfo({})
+        if (res.code == Code.StatusOK) {
+            tableData3.value = res.data
+            if (tableData3.value.show == 1) {
+                tableData3Flag.value = true
+            } else if (tableData3.value.show == 0) {
+                tableData3Flag.value = false
+            } else if (!tableData3.value.show) {
+                tableData3Flag.value = true
+                const nowTime = getCurrentTime().getTime()
+                const endTime = tableData3.value.activityEndTime
+                    ? new Date(tableData3.value.activityEndTime.replace(/-/g, '/')).getTime()
+                    : null
+                if (tableData3.value.status == 2 && tableData3.value.realizationStatus == 0 && endTime && nowTime > endTime) {
+                    isRealizationJx.value = 1
+                } else {
+                    isRealizationJx.value = 2
+                }
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取2023匠鑫活动数据失败', error)
+    }
+}
+
+// 2023匠鑫活动数据Vip
+const Activity23JiangxinInfoVip = async () => {
+    try {
+        const res = await activityApi.Activity23JiangxinInfoVip({})
+        if (res.code == Code.StatusOK) {
+            tableData3Vip.value = res.data
+            if (tableData3Vip.value.show == 1) {
+                tableData3FlagVip.value = true
+            } else if (tableData3Vip.value.show == 0) {
+                tableData3FlagVip.value = false
+            } else if (!tableData3Vip.value.show) {
+                tableData3FlagVip.value = true
+                const nowTime = getCurrentTime().getTime()
+                const endTime = tableData3Vip.value.activityEndTime
+                    ? new Date(tableData3Vip.value.activityEndTime.replace(/-/g, '/')).getTime()
+                    : null
+                if (tableData3Vip.value.status == 2 && tableData3Vip.value.realizationStatus == 0 && endTime && nowTime > endTime) {
+                    isRealizationJxVip.value = 1
+                } else {
+                    isRealizationJxVip.value = 2
+                }
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取2023匠鑫活动数据Vip失败', error)
+    }
+}
+
+// 2023年中赠金活动数据-10
+const Activity24nianzhongInfo = async () => {
+    try {
+        const res = await activityApi.Activity23nianzhongInfo({})
+        if (res.code == Code.StatusOK) {
+            tableData4.value = res.data
+            if (tableData4.value.show == 1) {
+                tableData4Flag.value = true
+            } else if (tableData4.value.show == 0) {
+                tableData4Flag.value = false
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取年中赠金活动数据失败', error)
+    }
+}
+
+// 2023年中赠金活动数据-20
+const Activity24nianzhongTwoInfo = async () => {
+    try {
+        const res = await activityApi.Activity23nianzhongTwoInfo({})
+        if (res.code == Code.StatusOK) {
+            tableData4Two.value = res.data
+            if (tableData4Two.value.show == 1) {
+                tableData4TwoFlag.value = true
+            } else if (tableData4Two.value.show == 0) {
+                tableData4TwoFlag.value = false
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取年中赠金活动数据-20失败', error)
+    }
+}
+
+// 交易大赛数据-参数
+const GetActivityCptCode = async () => {
+    try {
+        const res = await activityApi.ActivityCptinfoGetCode({})
+        if (res.code == Code.StatusOK) {
+            tableDataCptFlagCode.value = res.data.code
+            if (tableDataCptFlagCode.value) {
+                ActivityCptInfo(tableDataCptFlagCode.value)
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取交易大赛参数失败', error)
+    }
+}
+
+// 交易大赛数据
+const ActivityCptInfo = async (code: string) => {
+    try {
+        const res = await activityApi.ActivityCptinfoCode({
+            infoCode: code
+        })
+        if (res.code == Code.StatusOK) {
+            tableDataCpt.value = res.data
+            tableDataCptFlag.value = !!tableDataCpt.value
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取交易大赛数据失败', error)
+    }
+}
+
+// 24精英杯活动
+const Activity24JYBInfoVip = async () => {
+    try {
+        const res = await activityApi.Activity24JYBInfoVip({})
+        if (res.code == Code.StatusOK) {
+            tableData3JYB.value = res.data
+            if (tableData3JYB.value.show == 1) {
+                tableData3FlagJYB.value = true
+            } else if (tableData3JYB.value.show == 0) {
+                tableData3FlagJYB.value = false
+            } else if (!tableData3JYB.value.show) {
+                tableData3FlagJYB.value = true
+                const nowTime = getCurrentTime().getTime()
+                const endTime = tableData3JYB.value.activityEndTime
+                    ? new Date(tableData3JYB.value.activityEndTime.replace(/-/g, '/')).getTime()
+                    : null
+                if (tableData3JYB.value.status == 2 && tableData3JYB.value.realizationStatus == 0 && endTime && nowTime > endTime) {
+                    isRealizationJxJYB.value = 1
+                } else {
+                    isRealizationJxJYB.value = 2
+                }
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取24精英杯活动数据失败', error)
+    }
+}
+
+// 24无忧交易
+const ActivityNoWorriesInfo = async () => {
+    try {
+        const res = await activityApi.ActivityNoWorriesInfo({})
+        if (res.code == Code.StatusOK) {
+            tableDataNoWorries.value = res.data
+            if (typeof tableDataNoWorries.value == 'object') {
+                tableDataNoWorriesFlag.value = true
+                const nowTime = getCurrentTime().getTime()
+                const startTime = new Date(tableDataNoWorries.value.compensateTime.replace(/-/g, '/')).getTime()
+                const endTime = new Date(tableDataNoWorries.value.revokeTime.replace(/-/g, '/')).getTime()
+
+                if (nowTime < endTime && nowTime > startTime &&
+                    (tableDataNoWorries.value.status == 0 || tableDataNoWorries.value.status == 3) &&
+                    tableDataNoWorries.value.compensateStatus == 2 &&
+                    tableDataNoWorries.value.activityStatus == 1) {
+                    isRealizationNoWorries.value = 1
+                } else {
+                    isRealizationNoWorries.value = null
+                }
+            } else {
+                if (tableDataNoWorries.value) {
+                    tableDataNoWorriesFlag.value = true
+                }
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取无忧交易数据失败', error)
+    }
+}
+
+// CWG 现金嘉年华-新任务
+const ActivitYdepositRaffleAim = async () => {
+    try {
+        const res = await activityApi.ActivitYdepositRaffleAim({})
+        if (res.code == Code.StatusOK) {
+            newTask.value = !!res.data
+            if (res.data) {
+                newTaskList.value = res.data
+            }
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取新任务数据失败', error)
+    }
+}
+
+// CWG 现金嘉年华-抽奖次数
+const ActivitYdepositRaffleinfo = async () => {
+    try {
+        const res = await activityApi.ActivitYdepositRaffleinfo({})
+        if (res.code == Code.StatusOK) {
+            LuckyDrawsNumber.value = res.data?.raffleResidueNumber || '0'
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取抽奖次数失败', error)
+    }
+}
+
+// 抽奖活动是否到期
+const isRaffleOpen = () => {
+    const endTime1 = '2025/9/30 23:59:59'
+    const startTime1 = '2025/7/1 00:00:00'
+
+    const now = getCurrentTime().getTime()
+    const end = new Date(endTime1).getTime()
+    const start = new Date(startTime1).getTime()
+
+    if (now < end && start < now) {
+        choujiaClose.value = true
+        ActivitYdepositRaffleAim()
+        ActivitYdepositRaffleinfo()
+    }
+}
+
+// 新年庆典是否到期
+const isNewYear24Open = () => {
+    const endTime1 = '2025/3/31 23:59:59'
+    const startTime1 = '2025/1/1 00:00:00'
+
+    const now = getCurrentTime().getTime()
+    const end = new Date(endTime1).getTime()
+    const start = new Date(startTime1).getTime()
+
+    if (now < end && start < now) {
+        ActivityNewYear24()
+    }
+}
+
+// 新年庆典数据
+const ActivityNewYear24 = async () => {
+    try {
+        const res = await activityApi.ActivityNewYear24({})
+        if (res.code == Code.StatusOK) {
+            tableDataNewYear24.value = res.data
+            tableDataNewYear24Flag.value = !!tableDataNewYear24.value
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取新年庆典数据失败', error)
+    }
+}
+
+// 限时活动
+const ActivityRequiteInfo = async () => {
+    try {
+        const res = await activityApi.ActivityRequiteInfo({})
+        if (res.code == Code.StatusOK) {
+            limitedStatus.value = res.data
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取限时活动数据失败', error)
+    }
+}
+
+// 获取活动显示信息
+const getActivityShowsInfo = async () => {
+    try {
+        const res = await activityApi.ActivityShowsInfo()
+        if (res.code == Code.StatusOK) {
+            activityShowsInfo.value = res.data
+            surplusGive.value = res.data.surplusGive || false
+            monthlyGive.value = res.data.monthlyGive || false
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+            surplusGive.value = false
+            monthlyGive.value = false
+        }
+    } catch (error) {
+        console.error('获取活动显示信息失败', error)
+        surplusGive.value = false
+        monthlyGive.value = false
+    }
+}
+
+// 20赠金是否到期
+const is20Open = () => {
+    const endTime1 = '2023/04/30 23:59:59'
+    const now = getCurrentTime().getTime()
+    const end = new Date(endTime1).getTime()
+
+    if (now > end) {
+        anshiClose.value = false
+    }
+}
+
+// ==================== 活动操作方法 ====================
+const handleActivityAction = ({ type, params }: { type: string; params?: any[] }) => {
+    switch (type) {
+        case 'toSingle':
+            toSingle(...(params || []))
+            break
+        case 'openCalculator':
+            openCalculator()
+            break
+        case 'openPdf':
+            openPdf(params?.[0] || type)
+            break
+        case 'openSurplusActivityDialog':
+            openSurplusActivityDialog()
+            break
+        case 'openSurplusActivityDialog1':
+            openSurplusActivityDialog1()
+            break
+        case 'goMonthlyTaskList':
+            goMonthlyTaskList()
+            break
+        case 'goSurplusTaskList':
+            goSurplusTaskList()
+            break
+        case 'toHistoryLuckyDraw':
+            toHistoryLuckyDraw()
+            break
+        case 'toOpenTask':
+            toOpenTask()
+            break
+        case 'toNewTask':
+            toNewTask()
+            break
+        case 'toTaskList':
+            toTaskList()
+            break
+        case 'toApplyNoWorriesOpen':
+            toApplyNoWorriesOpen()
+            break
+        case 'toRealizationNoWorries':
+            toRealizationNoWorries()
+            break
+        case 'toActivity24Trading':
+            toActivity24Trading()
+            break
+        case 'toActivity24nianzhong':
+            toActivity24nianzhong()
+            break
+        case 'toApply23Open':
+            toApply23Open()
+            break
+        case 'toTransform':
+            toTransform()
+            break
+        case 'toRealization':
+            toRealization()
+            break
+        case 'toApplyCptOpen':
+            toApplyCptOpen()
+            break
+        case 'toOpenSingle':
+            toOpenSingle(...(params || []))
+            break
+        case 'toApply24JYBOpenVip':
+            toApply24JYBOpenVip()
+            break
+        case 'toRealization24JYBVip':
+            toRealization24JYBVip()
+            break
+        case 'applications':
+            applications(...(params || []))
+            break
+        case 'checkActivity':
+            checkActivity(...(params || []))
+            break
+        case 'openDialog':
+            if (params?.[0] === 'dialogChinaUnionPayJX') {
+                popupExpired.value?.open()
+            }
+            break
+        case 'cashBack':
+            cashBack()
+            break
+        default:
+            console.warn('未知操作类型:', type)
+    }
+}
+
+// PDF打开方法
+const openPdf = (pdfConfig: any) => {
+    let url = ''
+
+    if (typeof pdfConfig === 'string') {
+        url = pdfConfig
+    } else if (pdfConfig.dynamic) {
+        if (pdfConfig.langMap) {
+            url = pdfConfig.langMap[locale.value] || pdfConfig.langMap.default
+        } else if (pdfConfig.path) {
+            url = pdfConfig.path.replace('{lang}', locale.value)
+            if (pdfConfig.supportedLangs && !pdfConfig.supportedLangs.includes(locale.value)) {
+                url = pdfConfig.fallback || url
+            }
+        }
+    } else if (pdfConfig.cn) {
+        url = pdfConfig[locale.value] || pdfConfig.default
+    }
+
+    if (url) {
+        // #ifdef H5
+        window.open(url, '_blank')
+        // #endif
+        // #ifdef APP-PLUS
+        plus.runtime.openURL(url)
+        // #endif
+        // #ifdef MP-WEIXIN
+        uni.downloadFile({
+            url: url,
+            success: (res) => {
+                if (res.statusCode === 200) {
+                    uni.openDocument({
+                        filePath: res.tempFilePath,
+                        success: () => {
+                            uni.showToast({ title: t('common.success'), icon: 'success' })
+                        }
+                    })
+                }
+            }
+        })
+        // #endif
+    }
+}
+
+// 跳转到详情
+const toSingle = (id: string | number, listID?: string | number) => {
+    if (typeof id === 'string' && id.startsWith('23')) {
+        uni.navigateTo({
+            url: `/pages/activities/content?id=&type=1&active=${id}`
+        })
+    } else if (id === 'newList') {
+        uni.navigateTo({
+            url: `/pages/activities/content?id=${listID}&type=1&active=newList`
+        })
+    } else {
+        uni.navigateTo({
+            url: `/pages/activities/content?id=${id}&type=1`
+        })
+    }
+}
+
+// 打开计算器
+const openCalculator = () => {
+    popupCalculator.value?.open()
+}
+
+// 关闭计算器
+const closeCalculator = () => {
+    popupCalculator.value?.close()
+}
+
+// 计算收益
+const calculateIncome = () => {
+    NewYear24Data.value.balance = Number(NewYear24DataBalance.value) || 0
+    let rate = 0
+    tableDataNewYear24.value.details?.forEach((item: any) => {
+        if (NewYear24Data.value.balance > item.min && NewYear24Data.value.balance <= item.max) {
+            rate = item.rate
+        } else if (NewYear24Data.value.balance > item.min && NewYear24Data.value.balance >= item.max && item.max == 0) {
+            rate = item.rate
+        }
+    })
+    NewYear24Data.value.income = ((NewYear24Data.value.balance * rate) / 100 / 365 * 30).toFixed(2)
+}
+
+// 打开 Surplus 活动弹窗
+const openSurplusActivityDialog = async () => {
+    if (!surplusGive.value) return
+    await getDateList()
+    popupSurplusActivity.value?.open()
+}
+
+// 打开月赏礼遇弹窗
+const openSurplusActivityDialog1 = () => {
+    if (!monthlyGive.value) return
+    popupMonthlyActivity.value?.open()
+}
+
+// 获取Surplus活动选项
+const getSurplusActivityOptions = async () => {
+    if (!selectedAccount.value) return
+    surplusActivityLoading.value = true
+    try {
+        const res = await activityApi.ActivitySurplusDepositAmount({
+            login: selectedAccount.value.login,
+            platform: selectedAccount.value.platform
+        })
+        if (res.code == Code.StatusOK) {
+            surplusActivityOptions.value = res.data.map((item: any, index: number) => ({
+                id: index,
+                value: item.level,
+                label: `${t('AmountLabel.item1')}: ${item.amount} | ${t('AmountLabel.item2')}: ${item.needVolume}`,
+                giveFlag: item.giveFlag
+            }))
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取Surplus活动选项失败', error)
+    } finally {
+        surplusActivityLoading.value = false
+    }
+}
+
+// 确认参加Surplus活动
+const confirmSurplusActivity = async () => {
+    if (!selectedAccount.value || !selectedSurplusActivity.value) return
+
+    surplusActivityLoading.value = true
+    try {
+        const res = await activityApi.ActivitySurplusAdd({
+            login: selectedAccount.value.login,
+            platform: selectedAccount.value.platform,
+            level: selectedSurplusActivity.value
+        })
+        if (res.code == Code.StatusOK) {
+            uni.showToast({ title: res.msg, icon: 'success' })
+            closeSurplusActivityDialog()
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('参加Surplus活动失败', error)
+    } finally {
+        surplusActivityLoading.value = false
+    }
+}
+
+// 关闭Surplus活动弹窗
+const closeSurplusActivityDialog = () => {
+    popupSurplusActivity.value?.close()
+    selectedAccount.value = null
+    selectedSurplusActivity.value = null
+    selectedSurplusActivityLabel.value = ''
+    surplusActivityOptions.value = []
+}
+
+// 确认参加月赏礼遇活动
+const confirmSurplusActivity1 = async () => {
+    try {
+        const res = await activityApi.ActivityMonthlyAdd({})
+        if (res.code == Code.StatusOK) {
+            uni.showToast({ title: res.msg, icon: 'success' })
+            closeSurplusActivityDialog1()
+            getActivityShowsInfo()
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('参加月赏礼遇活动失败', error)
+    }
+}
+
+// 关闭月赏礼遇弹窗
+const closeSurplusActivityDialog1 = () => {
+    popupMonthlyActivity.value?.close()
+}
+
+// 跳转到月赏任务列表
+const goMonthlyTaskList = () => {
+    uni.navigateTo({
+        url: '/pages/customer/monthly/list'
+    })
+}
+
+// 跳转到 Surplus 任务列表
+const goSurplusTaskList = () => {
+    uni.navigateTo({
+        url: '/pages/customer/surplus/list'
+    })
+}
+
+// 跳转到抽奖历史
+const toHistoryLuckyDraw = () => {
+    uni.navigateTo({
+        url: '/pages/customer/history/lucky/draw'
+    })
+}
+
+// 打开抽奖弹窗
+const toOpenTask = () => {
+    // 打开抽奖组件
+    uni.navigateTo({
+        url: '/pages/customer/lottery/draw'
+    })
+}
+
+// 打开新任务弹窗
+const toNewTask = () => {
+    popupNewTask.value?.open()
+}
+
+// 关闭新任务弹窗
+const closeNewTask = () => {
+    popupNewTask.value?.close()
+}
+
+// 关闭过期弹窗
+const closeExpiredPopup = () => {
+    popupExpired.value?.close()
+}
+
+// 跳转到任务列表
+const toTaskList = () => {
+    uni.navigateTo({
+        url: '/pages/customer/task/list'
+    })
+}
+
+// 打开无忧交易申请
+const toApplyNoWorriesOpen = async () => {
+    uni.showLoading({ title: t('common.loading') })
+    try {
+        const res = await activityApi.ActivityNoWorriesLogin({})
+        if (res.code === Code.StatusOK) {
+            loginOptions.value = res.data
+            popupApply.value?.open()
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取账户列表失败', error)
+    } finally {
+        uni.hideLoading()
+    }
+}
+const noWorriesLoginOptions = computed(() => {
+    if (!loginOptions.value) return []
+    return loginOptions.value.map((option: any) => ({
+        ...option,
+        text: `${option.login} (${groupTypeName(option.groupType)})`,
+        value: option.login
+    }))
+})
+
+// 无忧交易变现
+const toRealizationNoWorries = () => {
+    // 打开变现确认弹窗
+    uni.showModal({
+        title: t('common.tip'),
+        content: t('news_add_field1.activitiesNoWorries.item7'),
+        success: async (res) => {
+            if (res.confirm) {
+                uni.showLoading({ title: t('common.loading') })
+                try {
+                    const result = await activityApi.ActivityNoWorriesRealization({
+                        id: tableDataNoWorries.value.id
+                    })
+                    if (result.code == Code.StatusOK) {
+                        uni.showToast({ title: result.msg, icon: 'success' })
+                        ActivityNoWorriesInfo()
+                    } else {
+                        uni.showToast({ title: result.msg, icon: 'none' })
+                    }
+                } catch (error) {
+                    console.error('变现失败', error)
+                } finally {
+                    uni.hideLoading()
+                }
+            }
+        }
+    })
+}
+
+// 跳转到24交易奖励
+const toActivity24Trading = () => {
+    uni.navigateTo({
+        url: '/pages/customer/new'
+    })
+}
+
+// 跳转到年中赠金
+const toActivity24nianzhong = () => {
+    uni.navigateTo({
+        url: '/pages/customer/deposit'
+    })
+}
+
+// 打开23迎新活动申请
+const toApply23Open = async () => {
+    uni.showLoading({ title: t('common.loading') })
+    try {
+        const res = await activityApi.Activity23Login({})
+        if (res.code === Code.StatusOK) {
+            loginOptions.value = res.data
+            popupApply.value?.open()
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取账户列表失败', error)
+    } finally {
+        uni.hideLoading()
+    }
+}
+
+// 盈利转换
+const toTransform = () => {
+    uni.showModal({
+        title: t('common.tip'),
+        content: t('news_add_field1.activities.item11'),
+        success: async (res) => {
+            if (res.confirm) {
+                uni.showLoading({ title: t('common.loading') })
+                try {
+                    const result = await activityApi.Activity23HundredTransform({})
+                    if (result.code == Code.StatusOK) {
+                        uni.showToast({ title: result.msg, icon: 'success' })
+                        Activity23HundredInfo()
+                    } else {
+                        uni.showToast({ title: result.msg, icon: 'none' })
+                    }
+                } catch (error) {
+                    console.error('盈利转换失败', error)
+                } finally {
+                    uni.hideLoading()
+                }
+            }
+        }
+    })
+}
+
+// 盈利变现
+const toRealization = () => {
+    uni.showModal({
+        title: t('common.tip'),
+        content: t('news_add_field1.activities.item12'),
+        success: async (res) => {
+            if (res.confirm) {
+                uni.showLoading({ title: t('common.loading') })
+                try {
+                    const result = await activityApi.Activity23HundredRealization({})
+                    if (result.code == Code.StatusOK) {
+                        uni.showToast({ title: result.msg, icon: 'success' })
+                        Activity23HundredInfo()
+                    } else {
+                        uni.showToast({ title: result.msg, icon: 'none' })
+                    }
+                } catch (error) {
+                    console.error('盈利变现失败', error)
+                } finally {
+                    uni.hideLoading()
+                }
+            }
+        }
+    })
+}
+
+// 打开交易大赛申请
+const toApplyCptOpen = async () => {
+    uni.showLoading({ title: t('common.loading') })
+    try {
+        const res = await activityApi.ActivityCptInfoLogins({
+            cptId: tableDataCpt.value.id
+        })
+        if (res.code === Code.StatusOK) {
+            loginOptions.value = res.data
+            popupApply.value?.open()
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取账户列表失败', error)
+    } finally {
+        uni.hideLoading()
+    }
+}
+
+// 打开外部链接
+const toOpenSingle = (pageAddress: string) => {
+    let link = pageAddress
+    if (tableDataCptFlagCode.value) {
+        if (pageAddress.indexOf('html?') === -1) {
+            link = pageAddress + '?code=' + tableDataCptFlagCode.value
+        } else if (pageAddress.indexOf('code') === -1) {
+            link = pageAddress + '&code=' + tableDataCptFlagCode.value
+        }
+    }
+
+    // #ifdef H5
+    window.open(Host80 + link, '_blank')
+    // #endif
+    // #ifndef H5
+    plus.runtime.openURL(Host80 + link)
+    // #endif
+}
+
+// 打开24精英杯申请
+const toApply24JYBOpenVip = async () => {
+    uni.showLoading({ title: t('common.loading') })
+    try {
+        const res = await activityApi.Activity24JYBLoginVip({})
+        if (res.code === Code.StatusOK) {
+            loginOptions.value = res.data
+            popupApply.value?.open()
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('获取账户列表失败', error)
+    } finally {
+        uni.hideLoading()
+    }
+}
+
+// 24精英杯变现
+const toRealization24JYBVip = async () => {
+    uni.showLoading({ title: t('common.loading') })
+    try {
+        const res = await activityApi.Activity24JYBRealizationVip({
+            id: tableData3JYB.value.id
+        })
+        if (res.code === Code.StatusOK) {
+            uni.showToast({ title: res.msg, icon: 'success' })
+            Activity24JYBInfoVip()
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('变现失败', error)
+    } finally {
+        uni.hideLoading()
+    }
+}
+
+// 申请活动
+const applications = (item: any) => {
+    // 实现申请逻辑
+    console.log('申请活动:', item)
+}
+
+// 查看活动
+const checkActivity = (item: any) => {
+    console.log('查看活动:', item)
+}
+
+// 返现
+const cashBack = async () => {
+    uni.showLoading({ title: t('common.loading') })
+    try {
+        const res = await activityApi.ActivityPercentageGiveApply({})
+        if (res.code == Code.StatusOK) {
+            uni.showToast({ title: t('Msg.Application'), icon: 'success' })
+        } else {
+            uni.showToast({ title: res.msg, icon: 'none' })
+        }
+    } catch (error) {
+        console.error('返现失败', error)
+    } finally {
+        uni.hideLoading()
+    }
+}
+
+// ==================== 弹窗相关方法 ====================
+const closeApplyPopup = () => {
+    popupApply.value?.close()
+    selectedLogin.value = null
+}
+
+const onLoginChange = (e: any) => {
+    selectedLogin.value = loginOptions.value[e.detail.value]
+}
+
+const onLogin1Change = (e: any) => {
+    selectedAccount.value = loginOptions1.value[e.detail.value]
+    getSurplusActivityOptions()
+}
+
+const onSurplusActivityChange = (e: any) => {
+    const option = surplusActivityOptions.value[e.detail.value]
+    selectedSurplusActivity.value = option.value
+    selectedSurplusActivityLabel.value = option.label
+}
+
+const confirmApply = () => {
+    // 实现申请确认逻辑
+    closeApplyPopup()
+}
+
+// ==================== 创建活动配置方法 ====================
+const createDynamicConfig = (item: any) => {
+    return {
+        id: item.id,
+        title: item.title,
+        description: item.subTitle,
+        image: Host80 + item.coverImage,
+        time: item.deliveryTime?.split(' ')[0],
+        hot: item.hot,
+        onClick: 'toSingle',
+        onClickParams: [item.id],
+        buttons: [
+            {
+                type: item.startTime && item.endTime && overdue(item.startTime, item.endTime) ? 'red' : 'gray',
+                text: 'Custom.Activity.Apply',
+                action: 'applications',
+                params: [item]
+            },
+            {
+                type: 'check',
+                text: 'Custom.Activity.List',
+                action: 'checkActivity',
+                params: [item]
+            },
+            {
+                type: 'check',
+                text: 'Custom.Activity.Single',
+                action: 'toSingle',
+                params: [item.id]
+            }
+        ]
+    }
+}
+
+const createGiveConfig = (item: any) => {
+    return {
+        id: item.id,
+        title: item.title,
+        description: item.subTitle,
+        image: Host80 + item.coverUrl,
+        time: item.revokeDate?.split(' ')[0],
+        hot: item.hot,
+        onClick: 'toSingle',
+        onClickParams: ['newList', item.id],
+        buttons: [
+            {
+                type: item.valid === 1 ? 'red' : 'gray',
+                text: 'Custom.Activity.Apply',
+                action: 'toActivity24nianzhong',
+                condition: item.valid === 1
+            },
+            {
+                type: 'check',
+                text: 'Custom.Activity.Single',
+                action: 'toSingle',
+                params: ['newList', item.id]
+            }
+        ]
+    }
+}
+
+// ==================== 刷新活动数据 ====================
+const refreshAllActivities = () => {
+    // 20赠金是否到期
+    is20Open()
+
+    // 获取活动列表
+    searchFunc()
+    searchFunc1()
+
+    // 获取各种活动数据
+    Activity23HundredInfo()
+    Activity23JiangxinInfoVip()
+    Activity24nianzhongInfo()
+    Activity24nianzhongTwoInfo()
+    GetActivityCptCode()
+    Activity24JYBInfoVip()
+    ActivityNoWorriesInfo()
+
+    // 抽奖和新年活动
+    isRaffleOpen()
+    isNewYear24Open()
+
+    // 限时活动和显示信息
+    ActivityRequiteInfo()
+    getActivityShowsInfo()
+}
+
+// ==================== 生命周期 ====================
+onLoad(() => {
+    refreshAllActivities()
+})
+
+onPullDownRefresh(() => {
+    refreshAllActivities()
+})
+
+onReachBottom(() => {
+    if (hasMore.value && !loadingMore.value) {
+        pageNum.value++
+        searchFunc()
+    }
+})
+
+</script>
+
+<style scoped lang="scss">
+.custom_activities {
+    height: 100vh;
+    display: flex;
+    flex-direction: column;
+
+    .crm-title-box {
+        padding: 20rpx 30rpx;
+        background-color: #fff;
+        border-bottom: 1rpx solid #e5e5e5;
+
+        .tit {
+            font-size: 32rpx;
+            font-weight: bold;
+            color: #333;
+        }
+    }
+
+    .main-content {
+        flex: 1;
+        overflow: hidden;
+
+        .tab {
+            height: 100%;
+            padding: 20rpx;
+        }
+    }
+
+    .loading-mask {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        background-color: rgba(255, 255, 255, 0.9);
+        z-index: 100;
+
+        .loading-content {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            padding: 30rpx;
+            background-color: #fff;
+            border-radius: 16rpx;
+            box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
+
+            .loading-text {
+                margin-top: 20rpx;
+                font-size: 28rpx;
+                color: #666;
+            }
+        }
+    }
+
+    .loading-more,
+    .no-more {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        padding: 30rpx;
+        font-size: 28rpx;
+        color: #999;
+    }
+
+    .spin {
+        animation: spin 1s linear infinite;
+    }
+
+    @keyframes spin {
+        from {
+            transform: rotate(0deg);
+        }
+
+        to {
+            transform: rotate(360deg);
+        }
+    }
+}
+
+.popup-content {
+    width: 600rpx;
+    background-color: #fff;
+    border-radius: 16rpx;
+    overflow: hidden;
+
+    .popup-header {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 30rpx;
+        border-bottom: 1rpx solid #e5e5e5;
+
+        .popup-title {
+            font-size: 32rpx;
+            font-weight: bold;
+            color: #333;
+        }
+    }
+
+    .popup-body {
+        max-height: 800rpx;
+        padding: 30rpx;
+
+        .form-item {
+            margin-bottom: 30rpx;
+
+            .form-label {
+                display: block;
+                margin-bottom: 16rpx;
+                font-size: 28rpx;
+                color: #666;
+            }
+
+            .picker-value {
+                padding: 20rpx;
+                border: 1rpx solid #e5e5e5;
+                border-radius: 8rpx;
+                font-size: 28rpx;
+                color: #333;
+            }
+        }
+
+        .calculator-input {
+            padding: 20rpx;
+            border: 1rpx solid #e5e5e5;
+            border-radius: 8rpx;
+            font-size: 28rpx;
+        }
+
+        .calculator-tip {
+            margin-top: 20rpx;
+            font-size: 26rpx;
+            line-height: 1.6;
+            color: #666;
+
+            .red {
+                color: #ff4d4f;
+                font-weight: bold;
+                margin: 0 8rpx;
+            }
+        }
+
+        .task-info {
+            display: flex;
+            flex-direction: column;
+            gap: 20rpx;
+            font-size: 28rpx;
+            line-height: 1.6;
+            color: #666;
+        }
+
+        .expired-text {
+            display: block;
+            text-align: center;
+            font-size: 28rpx;
+            color: #666;
+            padding: 30rpx 0;
+        }
+    }
+
+    .popup-footer {
+        display: flex;
+        padding: 30rpx;
+        border-top: 1rpx solid #e5e5e5;
+
+        button {
+            flex: 1;
+            margin: 0 10rpx;
+            height: 80rpx;
+            line-height: 80rpx;
+            font-size: 28rpx;
+            border-radius: 8rpx;
+
+            &.btn-cancel {
+                background-color: #f5f5f5;
+                color: #666;
+            }
+
+            &.btn-confirm {
+                background-color: #007aff;
+                color: #fff;
+
+                &:disabled {
+                    opacity: 0.5;
+                }
+            }
+        }
+    }
+}
+</style>