zhb преди 1 месец
родител
ревизия
ea7f6e350c
променени са 6 файла, в които са добавени 3114 реда и са изтрити 115 реда
  1. 3 1
      composables/useMenuSplit.ts
  2. 14 0
      pages.json
  3. 22 58
      pages/follow/account-management.vue
  4. 1514 0
      pages/follow/follow-list.vue
  5. 1539 0
      pages/follow/subscribe-list.vue
  6. 22 56
      pages/follow/trading-management.vue

+ 3 - 1
composables/useMenuSplit.ts

@@ -346,8 +346,10 @@ export function useMenuSplit(handleClick1: (item: MenuItem) => void) {
             label: 'Documentary.page_doc.item5',
             icon: 'crm-trade',
             children: [
-                { path: '/pages/follow/trading-management', label: 'Documentary.TundManagement.item8', icon: 'icon-client' },
+                { path: '/pages/follow/trading-management', label: 'Documentary.TundManagement.item11', icon: 'icon-client' },
+                { path: '/pages/follow/follow-list', label: 'Documentary.TundManagement.item17', icon: 'icon-client' },
                 { path: '/pages/follow/account-management', label: 'Documentary.TundManagement.item9', icon: 'icon-transfer' },
+                { path: '/pages/follow/subscribe-list', label: 'Documentary.TundManagement.item45', icon: 'icon-transfer' },
                 { path: '/pages/follow/record', label: 'Documentary.TundManagement.item10', icon: 'icon-transfer' }
             ],
         },

+ 14 - 0
pages.json

@@ -415,6 +415,20 @@
         "navigationStyle": "custom"
       }
     },
+    {
+      "path": "pages/follow/follow-list",
+      "style": {
+        "navigationBarTitleText": "",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/follow/subscribe-list",
+      "style": {
+        "navigationBarTitleText": "",
+        "navigationStyle": "custom"
+      }
+    },
     {
       "path": "pages/follow/account-management",
       "style": {

+ 22 - 58
pages/follow/account-management.vue

@@ -1,20 +1,20 @@
 <template>
     <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
-        <cwg-header :title="t('Documentary.TundManagement.item9')" />
+        
         <view class="content-container">
             <!-- 动态字段列表 -->
-            <view class="field-container">
-                <view class="content-title">
-                    <view v-t="'Documentary.TundManagement.item9'"></view>
-                    <view class="content-title-btns">
-                        <view class="btn-primary btn-primary1" @click="toSubscribeList()">
-                            <cwg-icon icon="crm-plus" :size="16" color="#fff" />
-                            <text v-t="'Documentary.TundManagement.item44'" />
-                        </view>
+            <view class="content-title">
+                <cwg-header :title="t('Documentary.TundManagement.item9')" />
+                <view class="content-title-btns">
+                    <view class="btn-primary btn-primary1" @click="toSubscribeList()">
+                        <cwg-icon icon="crm-plus" :size="16" color="#fff" />
+                        <text v-t="'Documentary.TundManagement.item44'" />
                     </view>
                 </view>
-                <uni-loading v-if="accountDataLoading" />
-                <template v-else>
+            </view>
+            <uni-loading v-if="accountDataLoading" />
+            <template v-else>
+                <view class="field-container" v-if="accountData.length > 0">
                     <view class="account-l-con" v-for="(item, index) in accountData" :key="index">
                         <view class="tit">
                             <view>
@@ -57,38 +57,9 @@
                             </view>
                         </view>
                     </view>
-                    <cwg-empty-state v-if="accountData.length == 0" />
-                </template>
-            </view>
-            <view class="info-card">
-                <view class="content-title">
-                    <view v-t="'Documentary.TundManagement.item45'"></view>
                 </view>
-                <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
-                    @reset="handleReset" />
-                <cwg-tabel ref="tableRef" :columns="currentColumns" :immediate="false" :queryParams="search"
-                    :api="listApi" :show-operation="false">
-                    <!-- 状态列自定义渲染 -->
-                    <template #status="{ row }">
-                        <view v-if="getStatusText(row)" class="status-tag" :class="getStatusClass(row.status)">
-                            {{ getStatusText(row) }}
-                        </view>
-                        <view v-else></view>
-                    </template>
-                    <!-- 账户类型列自定义渲染 -->
-                    <template #accountType="{ row }">
-                        {{ getAccountTypeText(row.type || row.loginType) }}
-                    </template>
-                    <!-- 金额列格式化 -->
-                    <template #amount="{ row }">
-                        <view>-{{ formatNumber(row.withdrawAmount || row.amount) }}</view>
-                    </template>
-                    <!-- 备注列格式化 -->
-                    <template #note="{ row }">
-                        <view>{{ formatNote(row.approveDesc) }}</view>
-                    </template>
-                </cwg-tabel>
-            </view>
+                <cwg-empty-state v-if="accountData.length == 0" />
+            </template>
         </view>
         <!-- 删除信号源 -->
         <cwg-popup v-model:visible="dialogFllowDelete" type="center" :mask-click="false" :show-footers="true"
@@ -1277,24 +1248,20 @@ onMounted(() => {
 @import "@/uni.scss";
 
 .content-container {
-    display: grid;
-    grid-template-columns: 1fr 2fr;
-    gap: px2rpx(16);
-    width: 100%;
-    min-width: 0;
-    overflow: hidden;
 
-    @media (max-width: 991px) {
-        grid-template-columns: 1fr;
-    }
 
     .field-container {
-        display: flex;
-        flex-direction: column;
-        gap: px2rpx(12);
+        display: grid;
+        grid-template-columns: repeat(3, 1fr);
+        gap: px2rpx(16);
+        width: 100%;
         min-width: 0;
         overflow: hidden;
 
+        @media (max-width: 991px) {
+            grid-template-columns: 1fr;
+        }
+
         .account-l-con {
             background-color: #f8f9fa;
             border-radius: px2rpx(8);
@@ -1417,16 +1384,13 @@ onMounted(() => {
     display: flex;
     justify-content: space-between;
     align-items: center;
-    font-size: px2rpx(22);
-    font-weight: 500;
-    color: var(--color-slate-800);
-    background-color: rgba(255, 255, 255, 0);
 
     .content-title-btns {
         display: flex;
         align-items: center;
         justify-content: center;
         gap: px2rpx(12);
+        margin-bottom: px2rpx(24);
 
 
         .btn-primary {

+ 1514 - 0
pages/follow/follow-list.vue

@@ -0,0 +1,1514 @@
+<template>
+    <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
+        <cwg-header :title="t('Documentary.TundManagement.item17')" />
+        <view class="content-container">
+            <view class="info-card">
+                <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
+                    @reset="handleReset" />
+                <cwg-tabel ref="tableRef" :columns="currentColumns" :immediate="false" :queryParams="search"
+                    :api="listApi" :show-operation="false">
+                    <!-- 状态列自定义渲染 -->
+                    <template #status="{ row }">
+                        <view v-if="getStatusText(row)" class="status-tag" :class="getStatusClass(row.status)">
+                            {{ getStatusText(row) }}
+                        </view>
+                        <view v-else></view>
+                    </template>
+                    <!-- 账户类型列自定义渲染 -->
+                    <template #accountType="{ row }">
+                        {{ getAccountTypeText(row.type || row.loginType) }}
+                    </template>
+                    <!-- 金额列格式化 -->
+                    <template #amount="{ row }">
+                        <view>-{{ formatNumber(row.withdrawAmount || row.amount) }}</view>
+                    </template>
+                    <!-- 备注列格式化 -->
+                    <template #note="{ row }">
+                        <view>{{ formatNote(row.approveDesc) }}</view>
+                    </template>
+                </cwg-tabel>
+            </view>
+        </view>
+        <!-- 删除信号源 -->
+        <cwg-popup v-model:visible="dialogFllowDelete" type="center" :mask-click="false" :show-footers="true"
+            :title="t('Documentary.TundManagement.item28')">
+            <view class="dia-content">
+                <view class="fllow-title delete-title">
+                    <text class="title">{{ t('Documentary.TundManagement.item29') }}</text>
+                </view>
+
+                <view class="delete-grid">
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.tradingCenter.item29') }}</text>
+                            <text class="delete-value">{{ dialogFllowDataDelete.dealLogin || '--' }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.console.item3') }}</text>
+                            <text class="delete-value">{{ dialogFllowDataDelete.dealPlatform || '--' }}</text>
+                        </view>
+                    </view>
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.console.item7') }}</text>
+                            <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealBalance) }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Label.AccountType') }}</text>
+                            <text class="delete-value">
+                                <text> {{ groupTypeName(dialogFllowDataDelete.dealLoginType) }}</text>
+                            </text>
+                        </view>
+                    </view>
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.console.item6') }}</text>
+                            <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealEquity) }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.tradingCenter.item30') }}</text>
+                            <text class="delete-value">
+                                <text v-if="dialogFllowDataDelete.distributionType == 1"
+                                    v-t="'Documentary.TundManagement.item59'"></text>
+                            </text>
+                        </view>
+                    </view>
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Label.Credit') }}</text>
+                            <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealCredit) }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.tradingCenter.item31') }}</text>
+                            <text class="delete-value">{{ dialogFllowDataDelete.distributionRatio || '0' }}%</text>
+                        </view>
+                    </view>
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Label.Leverage') }}</text>
+                            <text class="delete-value">1:{{ dialogFllowDataDelete.dealLeverage || '0' }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
+                            <text class="delete-value">{{ dialogFllowDataDelete.settlementCycle || '--' }}</text>
+                        </view>
+                    </view>
+                </view>
+
+                <view class="delete-tip">
+                    <text v-t="'Documentary.TundManagement.item30'"></text>
+                </view>
+            </view>
+
+            <template #footer>
+                <button @click="FllowDeleCancel">{{ t('Btn.Cancel') }}</button>
+                <button type="primary" @click="FllowDele">{{ t('Btn.Confirm') }}</button>
+            </template>
+        </cwg-popup>
+        <!-- 信号源设置 -->
+        <cwg-popup v-model:visible="dialogFllow" type="center" :mask-click="false" :show-footers="true"
+            :title="t('Documentary.TundManagement.item31')" width="650px">
+            <uni-forms ref="formRef" :model="dialogFllowData" :rules="rules" label-position="top">
+                <!-- 名片信息 -->
+                <view class="dia-content">
+                    <!-- 名片信息 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.tradingCenter.item126') }}</text>
+                    </view>
+
+                    <view class="form-item">
+                        <uni-forms-item name="nickname" :label="t('Documentary.console.item20') + ':'">
+                            <uni-easyinput v-model="dialogFllowData.nickname" :placeholder="t('placeholder.input')"
+                                @blur="validateAmount" />
+                        </uni-forms-item>
+                    </view>
+
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="personalSignature" :label="t('Documentary.console.item21') + ':'">
+                                    <uni-easyinput v-model="dialogFllowData.personalSignature"
+                                        :placeholder="t('placeholder.input')" type="textarea"
+                                        @input="filterChineseEnglishOnlyForApply('personalSignature', $event, 1)" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="traderStrategy" :label="t('Documentary.console.item22') + ':'">
+                                    <uni-easyinput v-model="dialogFllowData.traderStrategy"
+                                        :placeholder="t('placeholder.input')" type="textarea"
+                                        @input="filterChineseEnglishOnlyForApply('traderStrategy', $event, 1)" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+
+                    <view class="tip-red">
+                        <text v-t="'Documentary.console.item37'"></text>
+                    </view>
+
+                    <!-- 账户信息 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item29') }}</text>
+                    </view>
+                    <view class="delete-grid">
+                        <view class="delete-row">
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.console.item3') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.dealPlatform || '--' }}</text>
+                            </view>
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.tradingCenter.item29') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.dealLogin || '--' }}</text>
+                            </view>
+
+                        </view>
+                        <view class="delete-row">
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Label.AccountType') }}</text>
+                                <text class="delete-value">
+                                    <text> {{ groupTypeName(dialogFllowData.dealLoginType) }}</text>
+                                </text>
+                            </view>
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Label.Leverage') }}</text>
+                                <text class="delete-value">1:{{ dialogFllowData.dealLeverage || '0' }}</text>
+                            </view>
+                        </view>
+                    </view>
+
+                    <!-- 展示设置 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item32') }}</text>
+                    </view>
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="historyShow"
+                                    :label="t('Documentary.TundManagement.item34') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowData.historyShow" :clearable="false"
+                                        :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
+                                        :placeholder="t('placeholder.choose')" />
+
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="historyTime"
+                                    :label="t('Documentary.TundManagement.item35') + ':'">
+                                    <uni-datetime-picker v-model="dialogFllowData.historyTime" type="date"
+                                        :placeholder="t('placeholder.input')" @change="handleDateChange" />
+                                    <!-- <uni-date-picker type="date" v-model="dialogFllowData.historyTime" /> -->
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+                    <view class="form-item">
+                        <uni-forms-item name="introduceShow" :label="t('Documentary.TundManagement.item36') + ':'">
+                            <cwg-combox v-model:value="dialogFllowData.historyShow" :clearable="false"
+                                :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
+                                :placeholder="t('placeholder.choose')" />
+                        </uni-forms-item>
+                    </view>
+
+                    <!-- 分润设置 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item33') }}</text>
+                    </view>
+
+                    <!-- 已有订阅 → 只读 -->
+                    <view v-if="dialogFllowData.followCount" class="delete-grid">
+                        <view class="delete-row">
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.TundManagement.item38') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.distributionType || '--' }}</text>
+                            </view>
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.settlementCycle || '--' }}</text>
+                            </view>
+                        </view>
+                        <view class="delete-row">
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.TundManagement.item39') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.distributionRatio || '--' }}</text>
+                            </view>
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.settlementCycle || '--' }}</text>
+                            </view>
+                        </view>
+                    </view>
+
+                    <!-- 无订阅 → 可编辑 -->
+                    <view v-else class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="distributionType"
+                                    :label="t('Documentary.TundManagement.item38') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowData.distributionType" :clearable="false"
+                                        :options="[{ text: t('Documentary.TundManagement.item59'), value: 1 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="distributionRatio"
+                                    :label="t('Documentary.TundManagement.item39') + '(%):'">
+                                    <uni-easyinput v-model="dialogFllowData.distributionRatio"
+                                        :placeholder="t('placeholder.input')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="settlementCycle"
+                                    :label="t('Documentary.tradingCenter.item32') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowData.settlementCycle" :clearable="false"
+                                        :options="[{ text: 7, value: 7 }, { text: 15, value: 15 }, { text: 30, value: 30 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+            </uni-forms>
+
+            <template #footer>
+
+                <button @click="FllowUpdateCancel">{{ t('Btn.Cancel') }}</button>
+                <button type="primary" @click="FllowUpdate">{{ t('Btn.Confirm') }}</button>
+            </template>
+        </cwg-popup>
+
+        <!--申请成为信号源-->
+        <cwg-popup v-model:visible="dialogFllowApply" type="center" :mask-click="false" :show-footers="true"
+            :title="t('Documentary.TundManagement.item41')" width="650px">
+            <uni-forms ref="applyRef" :model="dialogFllowDataApply" :rules="rules" label-position="top"
+                label-width="200px">
+                <!-- 名片信息 -->
+                <view class="dia-content">
+                    <!-- 名片信息 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.tradingCenter.item126') }}</text>
+                    </view>
+
+                    <view class="form-item">
+                        <uni-forms-item name="nickname" :label="t('Documentary.console.item20') + ':'">
+                            <uni-easyinput v-model="dialogFllowDataApply.nickname" :placeholder="t('placeholder.input')"
+                                @blur="validateAmount" />
+                        </uni-forms-item>
+                    </view>
+
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="personalSignature" :label="t('Documentary.console.item21') + ':'">
+                                    <uni-easyinput v-model="dialogFllowDataApply.personalSignature"
+                                        :placeholder="t('placeholder.input')" type="textarea"
+                                        @input="filterChineseEnglishOnlyForApply('personalSignature', $event, 2)" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="traderStrategy" :label="t('Documentary.console.item22') + ':'">
+                                    <uni-easyinput v-model="dialogFllowDataApply.traderStrategy"
+                                        :placeholder="t('placeholder.input')" type="textarea"
+                                        @input="filterChineseEnglishOnlyForApply('traderStrategy', $event, 2)" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+
+                    <view class="tip-red">
+                        <text v-t="'Documentary.console.item37'"></text>
+                    </view>
+
+                    <!-- 账户信息 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item29') }}{{ fundRequirementText }}</text>
+                    </view>
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="dealLogin" :label="t('Label.TradingAccount') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.dealLogin" :clearable="false"
+                                        :options="loginOptions" :placeholder="t('placeholder.choose')"
+                                        @change="selectLoginDeal" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="platform" :label="t('Label.PlatformType') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.platform" :clearable="false"
+                                        :options="[{ text: 'MT4', value: 'MT4' }, { text: 'MT5', value: 'MT5' }]"
+                                        :placeholder="t('placeholder.choose')" :disabled="true" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="loginType" :label="t('Label.AccountType') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.loginType" :clearable="false"
+                                        :options="[
+                                            { text: t('AccountType.ClassicAccount'), value: 1 },
+                                            { text: t('AccountType.SeniorAccount'), value: 2 },
+                                            { text: t('AccountType.SpeedAccount'), value: 5 },
+                                            { text: t('AccountType.SpeedAccount'), value: 6 },
+                                            { text: t('AccountType.StandardAccount'), value: 7 },
+                                            { text: t('AccountType.CentAccount'), value: 8 }
+                                        ]" :placeholder="t('placeholder.choose')" :disabled="true" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="leverage" :label="t('Label.Leverage') + ':'">
+                                    <uni-easyinput v-model="dialogFllowDataApply.leverage"
+                                        :placeholder="t('placeholder.input')" :disabled="true" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+
+                    <!-- 展示设置 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item32') }}</text>
+                    </view>
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="historyShow"
+                                    :label="t('Documentary.TundManagement.item34') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.historyShow" :clearable="false"
+                                        :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="historyTime"
+                                    :label="t('Documentary.TundManagement.item35') + ':'">
+                                    <uni-datetime-picker v-model="dialogFllowDataApply.historyTime" type="date"
+                                        :placeholder="t('Documentary.TundManagement.item37')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+                    <view class="form-item">
+                        <uni-forms-item name="introduceShow" :label="t('Documentary.TundManagement.item36') + ':'">
+                            <cwg-combox v-model:value="dialogFllowDataApply.introduceShow" :clearable="false"
+                                :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
+                                :placeholder="t('placeholder.choose')" />
+                        </uni-forms-item>
+                    </view>
+
+                    <!-- 分润设置 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item33') }}</text>
+                    </view>
+
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="distributionType"
+                                    :label="t('Documentary.TundManagement.item38') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.distributionType" :clearable="false"
+                                        :options="[{ text: t('Documentary.TundManagement.item59'), value: 1 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="distributionRatio"
+                                    :label="t('Documentary.TundManagement.item39') + '(%):'">
+                                    <uni-easyinput v-model="dialogFllowDataApply.distributionRatio"
+                                        :placeholder="t('placeholder.input')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="settlementCycle"
+                                    :label="t('Documentary.tradingCenter.item32') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.settlementCycle" :clearable="false"
+                                        :options="[{ text: 7, value: 7 }, { text: 15, value: 15 }, { text: 30, value: 30 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+
+                    <view class="form-item agree">
+                        <uni-forms-item name="agree">
+                            <checkbox-group :value="dialogFllowDataApply.agree ? ['1'] : []" @change="onAgreeChange">
+                                <label class="checkbox-agree">
+                                    <checkbox value="1" :checked="dialogFllowDataApply.agree" />
+                                    <text class="agree-text">
+                                        {{ t('Documentary.TundManagement.item42') }}
+                                        <cwg-link style="text-decoration: underline;" class="a"
+                                            :url="isZh ? 'pdf/CopyTradeUserAgreementcn.pdf' : 'pdf/CopyTradeUserAgreement.pdf'"
+                                            target="_blank" title="Documentary.TundManagement.item43" />
+                                        {{ t('Documentary.TundManagement.item42_2') }}
+                                    </text>
+                                </label>
+                            </checkbox-group>
+                        </uni-forms-item>
+                    </view>
+                </view>
+            </uni-forms>
+
+            <template #footer>
+                <button @click="ApplyFllowCancel">{{ t('Btn.Cancel') }}</button>
+                <button type="primary" @click="ApplyFllow">{{ t('Btn.Confirm') }}</button>
+            </template>
+        </cwg-popup>
+
+    </cwg-page-wrapper>
+</template>
+
+<script setup lang="ts">
+import { computed, ref, nextTick, onMounted, reactive, watch } from 'vue';
+import { isAfterJuly28 } from '@/utils/dateUtils'
+import { useI18n } from 'vue-i18n';
+const { t, locale } = useI18n();
+import { documentaryApi } from '@/service/documentary';
+import useUserStore from "@/stores/use-user-store";
+const userStore = useUserStore();
+const userInfo = computed(() => userStore.userInfo);
+import { useFilters } from '@/composables/useFilters'
+const { numberFormat, numberDecimal } = useFilters()
+const search = ref({
+    type: 1
+})
+const getInfoAgentTransfer = computed(() => userInfo.value.customInfo?.agentTransfer)
+const typeMap = [
+    { value: 'MT4', text: 'MT4' },
+    { value: 'MT5', text: 'MT5' }]
+const isZh = computed(() => ['cn', 'zh', 'zhHant'].includes(locale.value));
+
+// 账户类型映射
+const accountTypeMap = {
+    1: 'AccountType.ClassicAccount',
+    2: 'AccountType.SeniorAccount',
+    5: 'AccountType.SpeedAccount',
+    6: 'AccountType.SpeedAccount',
+    7: 'AccountType.StandardAccount',
+    8: 'AccountType.CentAccount'
+}
+// 拒绝原因映射(示例)
+const reasons = ref({})
+// 动态传入筛选字段配置
+const filterFields = computed(() => [
+    { key: 'followPlatform', type: 'select', label: t('Label.Platform'), placeholder: t('placeholder.choose'), options: typeMap, defaultValue: 1 },
+    !isSubscribeLoading.value && { key: 'followLogin', type: 'select', label: t('Documentary.console.item28'), placeholder: t('placeholder.choose'), options: SubscribeDownData.value },
+    { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
+])
+const formRef = ref(null)
+const rules = {
+    password: {
+        rules: [
+            {
+                required: true,
+                validateFunction: (rule, value, data, callback) => {
+                    if (Config.Pattern.Password.test(value)) {
+                        callback()
+                    } else {
+                        callback(t('vaildate.password.format'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    agree: {
+        rules: [
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (value) {
+                        callback()
+                    } else {
+                        callback(t('vaildate.agree.empty'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    platform: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    currency: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    leverage: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    loginType: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    dealLogin: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    distributionType: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    distributionRatio: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (value >= 0 && value <= 50) {
+                        callback()
+                    } else {
+                        callback('0-50')
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    settlementCycle: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    },
+    historyShow: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    historyTime: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    introduceShow: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    protectAmount: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    },
+    protectRatio: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    },
+    nickname: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (value && /^[0-9a-zA-Z]{1,24}$/.test(value)) {
+                        callback()
+                    } else {
+                        callback(t('Msg.nickname'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    personalSignature: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (!value || /^[\u4e00-\u9fa5a-zA-Z\s]*$/.test(value)) {
+                        callback()
+                    } else {
+                        callback(t('Documentary.console.item38'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    traderStrategy: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (!value || /^[\u4e00-\u9fa5a-zA-Z\s]*$/.test(value)) {
+                        callback()
+                    } else {
+                        callback(t('Documentary.console.item38'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    followType: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    volume: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    },
+    ratio: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    }
+}
+
+const filterChineseEnglishOnlyForApply = (field, value, type) => {
+    // 只保留中文、英文和空格
+    const filtered = value.replace(/[^\u4e00-\u9fa5a-zA-Z\s]/g, '');
+    // 去掉前后空格,如果没有正文内容(全是空格)就设置为空字符串
+    const trimmed = filtered.trim();
+    if (type == 1) {
+        nextTick(() => {
+            dialogFllowData.value[field] = trimmed;
+        })
+    } else {
+        nextTick(() => {
+            dialogFllowDataApply[field] = trimmed;
+        })
+    }
+}
+//获取客户跟单账户的下拉列表
+const isSubscribeLoading = ref(false)
+const SubscribeDownData = ref([])
+const getSubscribeLoginDown = async () => {
+    isSubscribeLoading.value = true
+    let res = await documentaryApi.followDealSubscribeLoginList({
+        platform: "",
+        page: null,
+    });
+    if (res.code == 200) {
+        SubscribeDownData.value = res.data?.map(item => ({
+            text: t('Documentary.console.item28') + '-' + item.dealLogin || '--',
+            value: item.dealLogin
+        })) || []
+    } else {
+        uni.showToast({
+            title: res.msg,
+            icon: 'none'
+        })
+    }
+    isSubscribeLoading.value = false
+}
+const onAgreeChange = (e) => {
+    dialogFllowDataApply.agree = e.detail.value.length > 0
+}
+const searchParams = ref({})
+const tableRef = ref(null)
+const handleSearch = (params) => {
+    search.value = params
+    nextTick(() => {
+        tableRef.value.refreshTable()
+    })
+}
+
+const handleReset = (params) => {
+    search.value = params
+    nextTick(() => {
+        tableRef.value.refreshTable()
+    })
+}
+// 当前列配置
+const currentColumns = computed(() => [
+    {
+        prop: 'dealPlatform',
+        label: t('Label.Platform'),
+        align: 'center',
+        formatter: ({ row }) => row.dealPlatform || '--'
+    },
+    {
+        prop: 'followLogin',
+        label: t('Documentary.TundManagement.item25'),
+        align: 'center',
+        formatter: ({ row }) => row.followLogin || '--'
+    },
+    {
+        prop: 'followType',
+        label: t('Documentary.TundManagement.item19'),
+        align: 'center',
+        slot: 'followType'        // 使用插槽显示跟单类型(正向/反向/混合)
+    },
+    {
+        prop: 'followValue',
+        label: t('Documentary.TundManagement.item20'),
+        align: 'center',
+        slot: 'followValue'       // 使用插槽显示跟单数值(手数/比例/--)
+    },
+    {
+        prop: 'followLeverage',
+        label: t('Label.Leverage'),
+        align: 'center',
+        formatter: ({ row }) => row.followLeverage ? `1:${row.followLeverage}` : '--'
+    },
+    {
+        prop: 'balanceEquity',
+        label: t('Label.Balance'),
+        align: 'center',
+        children: [               // 嵌套子列
+            {
+                prop: 'followBalance',
+                label: t('Label.Equity'),
+                align: 'center',
+                slot: 'balanceEquity'  // 使用插槽显示余额和净值(上下两行)
+            }
+        ]
+    },
+    {
+        prop: 'timeRange',
+        label: t('Documentary.TundManagement.item26'),
+        align: 'center',
+        children: [               // 嵌套子列
+            {
+                prop: 'startTime',
+                label: t('Documentary.TundManagement.item27'),
+                align: 'center',
+                slot: 'timeRange'     // 使用插槽显示开始时间和结束时间(上下两行)
+            }
+        ]
+    },
+    {
+        prop: 'followProfit',
+        label: t('Documentary.TundManagement.item21'),
+        align: 'center',
+        formatter: ({ row }) => NumberFormat(row.followProfit || 0)
+    }
+])
+// 获取状态文本
+const getStatusText = (row: any) => {
+    const status = row.status
+    // 根据不同记录类型处理状态
+    if (search.value.type === 1) {
+        if (status === 1) return t('State.ToBeProcessed')
+        if (status === 2 && row.accountStatus === 2) return t('State.Completed')
+        if (status === 2 && (row.accountStatus === 1 || !row.accountStatus)) return t('State.InTheProcessing')
+        if (status === 3) return t('State.Refused')
+    } else if (search.value.type === 2) {
+        if (status === 1) return t('State.ToBeProcessed')
+        if (status === 2 && row.leverageStatus === 2) return t('State.Completed')
+        if (status === 2 && row.leverageStatus === 1) return t('State.InTheProcessing')
+        if (status === 3) return t('State.Refused')
+    } else if (search.value.type === 3 || search.value.type === 5) {
+        if (status === 1) return t('State.ToBeProcessed')
+        if (status === 2 && row.withdrawStatus === 2 && row.depositStatus === 2) return t('State.Completed')
+        if (status === 2 && (row.withdrawStatus === 1 || row.depositStatus === 1)) return t('State.InTheProcessing')
+        if (status === 3 || row.withdrawStatus === 3 || row.depositStatus === 3) return t('State.Refused')
+    } else {
+        // 活动申请等
+        if (status === 1) return t('State.ToBeProcessed')
+        if (status === 2) return t('State.Completed')
+        if (status === 3) return t('State.Refused')
+    }
+    return ''
+}
+// 获取状态样式类
+const getStatusClass = (status: number) => {
+    const classMap: Record<number, string> = {
+        1: 'status-pending',
+        2: 'status-success',
+        3: 'status-processing',
+        4: 'status-danger'
+    }
+    return classMap[status] || ''
+}
+// 获取账户类型文本
+const getAccountTypeText = (type: number) => {
+    const key = accountTypeMap[type as keyof typeof accountTypeMap]
+    return key ? t(key) : '--'
+}
+// 格式化数字
+const formatNumber = (value: string | number) => {
+    if (!value) return '--'
+    const num = Number(value)
+    return isNaN(num) ? '--' : num.toFixed(2)
+}
+// 格式化备注
+const formatNote = (approveDesc: string) => {
+    if (!approveDesc) return '--'
+    const reason = reasons.value[approveDesc as keyof typeof reasons.value]
+    if (reason) {
+        return isZh.value ? reason.content : reason.enContent
+    }
+    return approveDesc
+}
+// 单位类型
+function groupCurrency(type) {
+    const map = { GBP: ': £', USD: ': $', EUR: ': €', USC: ': ¢' }
+    return map[type] || ': $'
+}
+// 单位类型
+function groupCurrency1(type) {
+    const map = { GBP: '£', USD: '$', EUR: '€', USC: '¢' }
+    return map[type] || '$'
+}
+
+
+// 账户类型
+function groupTypeName(type) {
+    const typeMap = {
+        '1': t('AccountType.ClassicAccount'),
+        '2': t('AccountType.SeniorAccount'),
+        '3': isAfterJuly28() ? '--' : t('AccountType.AgencyAccount'),
+        '5': t('AccountType.SpeedAccount'),
+        '6': t('AccountType.SpeedAccount'),
+        '7': t('AccountType.StandardAccount'),
+        '8': t('AccountType.CentAccount')
+    }
+    return typeMap[type] || ''
+}
+
+const loginOptions = computed(() => loginOptionsLogin.value.map(item => ({
+    text: `${item.login} - ${groupTypeName(item.type)} - ${t('Custom.Deposit.AvailableBalance')}${groupCurrency(item.currency)}${item.balance}`,
+    value: item.login,
+    disable: item.balance < 200
+})))
+
+const selectLoginDeal = () => {
+    loginOptionsLogin.value.forEach((item) => {
+        if (item.login == dialogFllowDataApply.dealLogin) {
+            dialogFllowDataApply.leverage = "1:" + item.leverage;
+            dialogFllowDataApply.loginType = item.type;
+            dialogFllowDataApply.platform = item.platform;
+        }
+    });
+}
+
+const applyRef = ref(null)
+const dialogFllowDataApply = reactive({
+    dealLogin: '',
+    leverage: '',
+    loginType: '',
+    platform: '',
+    currency: '',
+    leverageStatus: '',
+    withdrawStatus: '',
+    depositStatus: '',
+    accountStatus: '',
+    status: '',
+    note: '',
+    followType: '',
+    volume: '',
+    ratio: '',
+    traderStrategy: '',
+    personalSignature: '',
+    nickname: '',
+    protectAmount: '',
+    protectRatio: '',
+    introduceShow: '',
+    historyShow: '',
+    historyTime: '',
+    settlementCycle: '',
+    distributionType: '',
+    distributionRatio: '',
+    withdrawCurrency: '',
+    withdrawAmount: '',
+    depositCurrency: '',
+    depositAmount: '',
+    withdrawLogin: '',
+    depositLogin: '',
+    addTime: '',
+    title: '',
+})
+const loginOptionsLogin = ref([])
+const dialogFllowApply = ref(false)
+//获取申请信号源交易账户下拉
+const getCustomLoginDownLogin = async () => {
+    if (flag.value) {
+        return;
+    } else {
+        flag.value = true;
+    }
+    let res = await documentaryApi.CustomDropdownData({
+        platform: "",
+    });
+    if (res.code == 200) {
+        loginOptionsLogin.value = res.data;
+        dialogFllowApply.value = true;
+    } else {
+        uni.showToast({
+            title: res.msg,
+            icon: 'none'
+        });
+    }
+    flag.value = false;
+}
+watch(() => dialogFllowDataApply.dealLogin, (newVal, oldVal) => {
+    if (newVal !== oldVal) {
+        selectLoginDeal();
+    }
+})
+
+//申请信号源
+const ApplyFllow = async () => {
+    try {
+        await applyRef.value.validate()
+        if (flag.value) {
+            return;
+        } else {
+            flag.value = true;
+        }
+        let res = await documentaryApi.followDealApply({
+            ...dialogFllowDataApply,
+        });
+        if (res.code == 200) {
+            uni.showToast({
+                title: t("Msg.Success"),
+                icon: 'none'
+            });
+            ApplyFllowCancel();
+            tableRef.value.refreshTable();
+            getDealLogin();
+            flag.value = false;
+        } else {
+            uni.showToast({
+                title: res.msg,
+                icon: 'none'
+            });
+            flag.value = false;
+        }
+    } catch (error) {
+        return false;
+    } finally {
+        flag.value = false;
+    }
+}
+const ApplyFllowCancel = () => {
+    applyRef.value &&
+        applyRef.value.clearValidate();
+    dialogFllowApply.value = false;
+}
+
+//获取客户信号源账户
+const accountDataLoading = ref(false)
+const accountData = ref([])
+const accountPager = ref({
+    current: 1,
+    row: 10,
+    rowTotal: 0,
+    pageTotal: 0
+})
+const getDealLogin = async () => {
+    accountDataLoading.value = true;
+    let res = await documentaryApi.followDealList({
+        platform: null,
+        status: 2,
+        page: {
+            current: accountPager.value.current,
+            row: accountPager.value.row,
+        },
+    });
+    if (res.code == 200) {
+        accountData.value = res.data || []
+        accountPager.value.rowTotal = res.page.rowTotal;
+        accountPager.value.pageTotal = res.page.pageTotal;
+    } else {
+        uni.showToast({
+            title: res.msg,
+            icon: 'none'
+        });
+    }
+    accountDataLoading.value = false;
+
+}
+//修改信号源
+const dialogFllowData = ref({})
+const dialogFllow = ref(false)
+const dialogFllowDataDelete = ref({})
+const dialogFllowDelete = ref(false)
+const flag = ref(false)
+const dialogFllowUpdate = (item) => {
+    dialogFllowData.value = item;
+    dialogFllow.value = true;
+}
+const FllowUpdate = async () => {
+    try {
+        await formRef.value.validate()
+        if (flag.value) {
+            return;
+        } else {
+            flag.value = true;
+        }
+
+        let res = await documentaryApi.followDealUpdate({
+            ...dialogFllowData.value,
+        });
+        if (res.code == 200) {
+            uni.showToast({
+                title: t("Msg.Success"),
+                icon: 'none'
+            });
+            FllowUpdateCancel();
+            tableRef.value.refreshTable()
+            getDealLogin();
+            getSubscribeLoginDown()
+            flag.value = false;
+        } else {
+            uni.showToast({
+                title: res.msg,
+                icon: 'none'
+            });
+            flag.value = false;
+        }
+    } catch (error) {
+        flag.value = false;
+    }
+}
+const FllowUpdateCancel = () => {
+    formRef.value && formRef.value.clearValidate();
+
+    dialogFllow.value = false;
+}
+//删除信号源
+const dialogFllowDele = (item) => {
+    dialogFllowDataDelete.value = item;
+    dialogFllowDelete.value = true;
+}
+const FllowDele = async () => {
+    if (flag.value) {
+        return;
+    } else {
+        flag.value = true;
+    }
+
+    let res = await documentaryApi.followDealDelete({
+        ids: [dialogFllowDataDelete.value.id],
+    });
+    if (res.code == 200) {
+        uni.showToast({
+            title: t("Msg.Success"),
+            icon: 'none'
+        });
+        FllowDeleCancel();
+        tableRef.value.refreshTable()
+        getDealLogin();
+        getSubscribeLoginDown()
+        flag.value = false;
+    } else {
+        uni.showToast({
+            title: res.msg,
+            icon: 'none'
+        });
+        flag.value = false;
+    }
+}
+const FllowDeleCancel = () => {
+    dialogFllowDelete.value = false;
+}
+const listApi = ref(null)
+onMounted(() => {
+    getDealLogin()
+    getSubscribeLoginDown()
+    listApi.value = documentaryApi.followDealSubscribeDealList
+})
+
+
+</script>
+
+<style scoped lang="scss">
+@import "@/uni.scss";
+
+.avatar {
+    width: px2rpx(60);
+    height: px2rpx(60);
+    border-radius: 4px;
+}
+
+
+.content-title {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: px2rpx(22);
+    font-weight: 500;
+    color: var(--color-slate-800);
+    background-color: rgba(255, 255, 255, 0);
+
+    .content-title-btns {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        gap: px2rpx(12);
+
+
+        .btn-primary {
+            min-width: px2rpx(120);
+            background-color: var(--color-error);
+            color: #fff;
+            padding: 0 px2rpx(12);
+            border: none;
+            font-size: px2rpx(14);
+            text-align: center;
+            cursor: pointer;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            gap: px2rpx(8);
+        }
+
+        .btn-primary1 {
+            background-color: #cf1322;
+            ;
+        }
+
+        .btn-primary2 {
+            background-color: var(--color-secondary-focus);
+        }
+    }
+}
+
+.operation-btn {
+    :deep(text) {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        gap: px2rpx(4);
+        cursor: pointer;
+        background-color: var(--color-slate-150);
+        padding: px2rpx(8) 0;
+    }
+}
+
+.operation-btn.disabled {
+    cursor: not-allowed;
+    opacity: 0.5;
+}
+
+.search-bar {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    flex-wrap: wrap;
+    gap: px2rpx(16);
+    margin: px2rpx(16) 0;
+
+    .cwg-combox,
+    .uni-easyinput,
+    .uni-date {
+        width: px2rpx(240) !important;
+        flex: none;
+    }
+}
+
+.dia-content {
+    padding: px2rpx(20);
+
+    .uni-forms-item {
+        width: 100%;
+    }
+
+    .grid-layout {
+        display: grid;
+        grid-template-columns: 1fr 1fr;
+        gap: px2rpx(20);
+        margin: px2rpx(24) 0;
+        padding: px2rpx(20);
+        background-color: #f8f9fa;
+        border-radius: px2rpx(8);
+        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+    }
+
+
+
+    .fllow-title {
+        margin: px2rpx(10) 0 px2rpx(16);
+        padding-left: px2rpx(8);
+        border-left: 4px solid #dc3545;
+        border-bottom: none;
+
+        .title {
+            font-size: px2rpx(16);
+            font-weight: 600;
+            color: #343a40;
+        }
+    }
+
+    .delete-grid {
+        margin: px2rpx(16) 0;
+    }
+
+    .delete-row {
+        display: flex;
+        gap: px2rpx(12);
+    }
+
+    .delete-item {
+        flex: 1;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: px2rpx(12) 0;
+        border-bottom: 1px dashed #e9ecef;
+
+        &:first-child {
+            padding-right: px2rpx(16);
+        }
+
+        &:last-child {
+            padding-left: px2rpx(16);
+        }
+    }
+
+    .delete-label {
+        font-size: px2rpx(14);
+        color: #6c757d;
+    }
+
+    .delete-value {
+        font-size: px2rpx(14);
+        color: #343a40;
+        font-weight: 400;
+    }
+
+    .delete-tip {
+        margin-top: px2rpx(16);
+        font-size: px2rpx(14);
+        color: #6c757d;
+        line-height: 1.5;
+        padding-top: px2rpx(16);
+    }
+
+    .tip-star {
+        color: #dc3545;
+        margin-right: px2rpx(4);
+    }
+
+    .agree {
+        margin-top: px2rpx(20);
+    }
+
+    .checkbox-agree {
+        display: flex;
+        align-items: flex-start;
+        gap: px2rpx(8);
+
+        .agree-text {
+            font-size: px2rpx(14);
+            color: #6c757d;
+            line-height: 1.5;
+            width: 100%;
+            white-space: wrap;
+
+            .a {
+                color: #007bff;
+                text-decoration: underline;
+                margin: 0 px2rpx(4);
+
+                &:hover {
+                    color: #0056b3;
+                }
+            }
+        }
+    }
+
+    .fllow-content {
+        margin-bottom: px2rpx(16);
+
+        .tit {
+            font-size: px2rpx(14);
+            font-weight: 500;
+            color: #6c757d;
+            margin-bottom: px2rpx(6);
+            text-transform: uppercase;
+            letter-spacing: px2rpx(0.5);
+        }
+
+        .con {
+            font-size: px2rpx(16);
+            font-weight: 400;
+            color: #343a40;
+            line-height: 1.4;
+        }
+    }
+
+    .form-row {
+        display: grid;
+        grid-template-columns: 1fr 1fr;
+        gap: px2rpx(20);
+        margin-top: px2rpx(16);
+    }
+
+    .form-item {
+        display: flex;
+        flex-direction: column;
+        align-items: flex-start;
+
+        text {
+            font-size: px2rpx(14);
+            font-weight: 500;
+            color: #6c757d;
+            margin-bottom: px2rpx(8);
+            white-space: nowrap;
+        }
+
+        input,
+        select,
+        textarea {
+            width: 100%;
+            padding: px2rpx(10);
+            border: 1px solid #ced4da;
+            border-radius: px2rpx(4);
+            font-size: px2rpx(14);
+            transition: all 0.2s ease;
+
+            &:focus {
+                outline: none;
+                border-color: #4dabf7;
+                box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.2);
+            }
+        }
+
+        textarea {
+            resize: vertical;
+            min-height: px2rpx(100);
+        }
+    }
+
+    .tip-red {
+        color: #dc3545;
+        font-size: px2rpx(14);
+        margin: px2rpx(12) 0 px2rpx(24) 0;
+    }
+
+    .tip-text {
+        margin-top: px2rpx(24);
+        font-size: px2rpx(14);
+        color: #6c757d;
+        line-height: 1.5;
+        padding: px2rpx(16);
+        background-color: #e7f3ff;
+        border-radius: px2rpx(4);
+        border-left: 4px solid #4dabf7;
+    }
+}
+
+/* 弹窗按钮样式 */
+:deep(.cwg-popup__footer) {
+    display: flex;
+    gap: px2rpx(20);
+    padding: px2rpx(20);
+    border-top: 1px solid #e9ecef;
+
+    button {
+        flex: 1;
+        padding: px2rpx(12) 0;
+        border-radius: px2rpx(4);
+        font-size: px2rpx(14);
+        font-weight: 500;
+        transition: all 0.2s ease;
+
+        &:first-child {
+            background-color: #fff;
+            color: #495057;
+            border: 1px solid #ced4da;
+
+            &:hover {
+                background-color: #f8f9fa;
+                border-color: #adb5bd;
+            }
+
+            &:active {
+                transform: scale(0.98);
+            }
+        }
+
+        &:last-child {
+            background-color: #dc3545;
+            color: white;
+            border: 1px solid #dc3545;
+
+            &:hover {
+                background-color: #c82333;
+                border-color: #bd2130;
+            }
+
+            &:active {
+                transform: scale(0.98);
+            }
+        }
+    }
+}
+</style>

+ 1539 - 0
pages/follow/subscribe-list.vue

@@ -0,0 +1,1539 @@
+<template>
+    <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
+        <cwg-header :title="t('Documentary.TundManagement.item45')" />
+        <view class="content-container">
+
+            <view class="info-card">
+                <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
+                    @reset="handleReset" />
+                <cwg-tabel ref="tableRef" :columns="currentColumns" :immediate="false" :queryParams="search"
+                    :api="listApi" :show-operation="false">
+                    <!-- 状态列自定义渲染 -->
+                    <template #status="{ row }">
+                        <view v-if="getStatusText(row)" class="status-tag" :class="getStatusClass(row.status)">
+                            {{ getStatusText(row) }}
+                        </view>
+                        <view v-else></view>
+                    </template>
+                    <!-- 账户类型列自定义渲染 -->
+                    <template #accountType="{ row }">
+                        {{ getAccountTypeText(row.type || row.loginType) }}
+                    </template>
+                    <!-- 金额列格式化 -->
+                    <template #amount="{ row }">
+                        <view>-{{ formatNumber(row.withdrawAmount || row.amount) }}</view>
+                    </template>
+                    <!-- 备注列格式化 -->
+                    <template #note="{ row }">
+                        <view>{{ formatNote(row.approveDesc) }}</view>
+                    </template>
+                </cwg-tabel>
+            </view>
+        </view>
+        <!-- 删除信号源 -->
+        <cwg-popup v-model:visible="dialogFllowDelete" type="center" :mask-click="false" :show-footers="true"
+            :title="t('Documentary.TundManagement.item28')">
+            <view class="dia-content">
+                <view class="fllow-title delete-title">
+                    <text class="title">{{ t('Documentary.TundManagement.item29') }}</text>
+                </view>
+
+                <view class="delete-grid">
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.tradingCenter.item29') }}</text>
+                            <text class="delete-value">{{ dialogFllowDataDelete.dealLogin || '--' }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.console.item3') }}</text>
+                            <text class="delete-value">{{ dialogFllowDataDelete.dealPlatform || '--' }}</text>
+                        </view>
+                    </view>
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.console.item7') }}</text>
+                            <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealBalance) }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Label.AccountType') }}</text>
+                            <text class="delete-value">
+                                <text> {{ groupTypeName(dialogFllowDataDelete.dealLoginType) }}</text>
+                            </text>
+                        </view>
+                    </view>
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.console.item6') }}</text>
+                            <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealEquity) }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.tradingCenter.item30') }}</text>
+                            <text class="delete-value">
+                                <text v-if="dialogFllowDataDelete.distributionType == 1"
+                                    v-t="'Documentary.TundManagement.item59'"></text>
+                            </text>
+                        </view>
+                    </view>
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Label.Credit') }}</text>
+                            <text class="delete-value">{{ numberFormat(dialogFllowDataDelete.dealCredit) }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.tradingCenter.item31') }}</text>
+                            <text class="delete-value">{{ dialogFllowDataDelete.distributionRatio || '0' }}%</text>
+                        </view>
+                    </view>
+                    <view class="delete-row">
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Label.Leverage') }}</text>
+                            <text class="delete-value">1:{{ dialogFllowDataDelete.dealLeverage || '0' }}</text>
+                        </view>
+                        <view class="delete-item">
+                            <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
+                            <text class="delete-value">{{ dialogFllowDataDelete.settlementCycle || '--' }}</text>
+                        </view>
+                    </view>
+                </view>
+
+                <view class="delete-tip">
+                    <text v-t="'Documentary.TundManagement.item30'"></text>
+                </view>
+            </view>
+
+            <template #footer>
+                <button @click="FllowDeleCancel">{{ t('Btn.Cancel') }}</button>
+                <button type="primary" @click="FllowDele">{{ t('Btn.Confirm') }}</button>
+            </template>
+        </cwg-popup>
+        <!-- 信号源设置 -->
+        <cwg-popup v-model:visible="dialogFllow" type="center" :mask-click="false" :show-footers="true"
+            :title="t('Documentary.TundManagement.item31')" width="650px">
+            <uni-forms ref="formRef" :model="dialogFllowData" :rules="rules" label-position="top">
+                <!-- 名片信息 -->
+                <view class="dia-content">
+                    <!-- 名片信息 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.tradingCenter.item126') }}</text>
+                    </view>
+
+                    <view class="form-item">
+                        <uni-forms-item name="nickname" :label="t('Documentary.console.item20') + ':'">
+                            <uni-easyinput v-model="dialogFllowData.nickname" :placeholder="t('placeholder.input')"
+                                @blur="validateAmount" />
+                        </uni-forms-item>
+                    </view>
+
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="personalSignature" :label="t('Documentary.console.item21') + ':'">
+                                    <uni-easyinput v-model="dialogFllowData.personalSignature"
+                                        :placeholder="t('placeholder.input')" type="textarea"
+                                        @input="filterChineseEnglishOnlyForApply('personalSignature', $event, 1)" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="traderStrategy" :label="t('Documentary.console.item22') + ':'">
+                                    <uni-easyinput v-model="dialogFllowData.traderStrategy"
+                                        :placeholder="t('placeholder.input')" type="textarea"
+                                        @input="filterChineseEnglishOnlyForApply('traderStrategy', $event, 1)" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+
+                    <view class="tip-red">
+                        <text v-t="'Documentary.console.item37'"></text>
+                    </view>
+
+                    <!-- 账户信息 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item29') }}</text>
+                    </view>
+                    <view class="delete-grid">
+                        <view class="delete-row">
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.console.item3') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.dealPlatform || '--' }}</text>
+                            </view>
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.tradingCenter.item29') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.dealLogin || '--' }}</text>
+                            </view>
+
+                        </view>
+                        <view class="delete-row">
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Label.AccountType') }}</text>
+                                <text class="delete-value">
+                                    <text> {{ groupTypeName(dialogFllowData.dealLoginType) }}</text>
+                                </text>
+                            </view>
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Label.Leverage') }}</text>
+                                <text class="delete-value">1:{{ dialogFllowData.dealLeverage || '0' }}</text>
+                            </view>
+                        </view>
+                    </view>
+
+                    <!-- 展示设置 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item32') }}</text>
+                    </view>
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="historyShow"
+                                    :label="t('Documentary.TundManagement.item34') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowData.historyShow" :clearable="false"
+                                        :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
+                                        :placeholder="t('placeholder.choose')" />
+
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="historyTime"
+                                    :label="t('Documentary.TundManagement.item35') + ':'">
+                                    <uni-datetime-picker v-model="dialogFllowData.historyTime" type="date"
+                                        :placeholder="t('placeholder.input')" @change="handleDateChange" />
+                                    <!-- <uni-date-picker type="date" v-model="dialogFllowData.historyTime" /> -->
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+                    <view class="form-item">
+                        <uni-forms-item name="introduceShow" :label="t('Documentary.TundManagement.item36') + ':'">
+                            <cwg-combox v-model:value="dialogFllowData.historyShow" :clearable="false"
+                                :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
+                                :placeholder="t('placeholder.choose')" />
+                        </uni-forms-item>
+                    </view>
+
+                    <!-- 分润设置 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item33') }}</text>
+                    </view>
+
+                    <!-- 已有订阅 → 只读 -->
+                    <view v-if="dialogFllowData.followCount" class="delete-grid">
+                        <view class="delete-row">
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.TundManagement.item38') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.distributionType || '--' }}</text>
+                            </view>
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.settlementCycle || '--' }}</text>
+                            </view>
+                        </view>
+                        <view class="delete-row">
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.TundManagement.item39') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.distributionRatio || '--' }}</text>
+                            </view>
+                            <view class="delete-item">
+                                <text class="delete-label">{{ t('Documentary.tradingCenter.item32') }}</text>
+                                <text class="delete-value">{{ dialogFllowData.settlementCycle || '--' }}</text>
+                            </view>
+                        </view>
+                    </view>
+
+                    <!-- 无订阅 → 可编辑 -->
+                    <view v-else class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="distributionType"
+                                    :label="t('Documentary.TundManagement.item38') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowData.distributionType" :clearable="false"
+                                        :options="[{ text: t('Documentary.TundManagement.item59'), value: 1 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="distributionRatio"
+                                    :label="t('Documentary.TundManagement.item39') + '(%):'">
+                                    <uni-easyinput v-model="dialogFllowData.distributionRatio"
+                                        :placeholder="t('placeholder.input')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="settlementCycle"
+                                    :label="t('Documentary.tradingCenter.item32') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowData.settlementCycle" :clearable="false"
+                                        :options="[{ text: 7, value: 7 }, { text: 15, value: 15 }, { text: 30, value: 30 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+            </uni-forms>
+
+            <template #footer>
+
+                <button @click="FllowUpdateCancel">{{ t('Btn.Cancel') }}</button>
+                <button type="primary" @click="FllowUpdate">{{ t('Btn.Confirm') }}</button>
+            </template>
+        </cwg-popup>
+
+        <!--申请成为信号源-->
+        <cwg-popup v-model:visible="dialogFllowApply" type="center" :mask-click="false" :show-footers="true"
+            :title="t('Documentary.TundManagement.item41')" width="650px">
+            <uni-forms ref="applyRef" :model="dialogFllowDataApply" :rules="rules" label-position="top"
+                label-width="200px">
+                <!-- 名片信息 -->
+                <view class="dia-content">
+                    <!-- 名片信息 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.tradingCenter.item126') }}</text>
+                    </view>
+
+                    <view class="form-item">
+                        <uni-forms-item name="nickname" :label="t('Documentary.console.item20') + ':'">
+                            <uni-easyinput v-model="dialogFllowDataApply.nickname" :placeholder="t('placeholder.input')"
+                                @blur="validateAmount" />
+                        </uni-forms-item>
+                    </view>
+
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="personalSignature" :label="t('Documentary.console.item21') + ':'">
+                                    <uni-easyinput v-model="dialogFllowDataApply.personalSignature"
+                                        :placeholder="t('placeholder.input')" type="textarea"
+                                        @input="filterChineseEnglishOnlyForApply('personalSignature', $event, 2)" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="traderStrategy" :label="t('Documentary.console.item22') + ':'">
+                                    <uni-easyinput v-model="dialogFllowDataApply.traderStrategy"
+                                        :placeholder="t('placeholder.input')" type="textarea"
+                                        @input="filterChineseEnglishOnlyForApply('traderStrategy', $event, 2)" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+
+                    <view class="tip-red">
+                        <text v-t="'Documentary.console.item37'"></text>
+                    </view>
+
+                    <!-- 账户信息 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item29') }}{{ fundRequirementText }}</text>
+                    </view>
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="dealLogin" :label="t('Label.TradingAccount') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.dealLogin" :clearable="false"
+                                        :options="loginOptions" :placeholder="t('placeholder.choose')"
+                                        @change="selectLoginDeal" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="platform" :label="t('Label.PlatformType') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.platform" :clearable="false"
+                                        :options="[{ text: 'MT4', value: 'MT4' }, { text: 'MT5', value: 'MT5' }]"
+                                        :placeholder="t('placeholder.choose')" :disabled="true" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="loginType" :label="t('Label.AccountType') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.loginType" :clearable="false"
+                                        :options="[
+                                            { text: t('AccountType.ClassicAccount'), value: 1 },
+                                            { text: t('AccountType.SeniorAccount'), value: 2 },
+                                            { text: t('AccountType.SpeedAccount'), value: 5 },
+                                            { text: t('AccountType.SpeedAccount'), value: 6 },
+                                            { text: t('AccountType.StandardAccount'), value: 7 },
+                                            { text: t('AccountType.CentAccount'), value: 8 }
+                                        ]" :placeholder="t('placeholder.choose')" :disabled="true" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="leverage" :label="t('Label.Leverage') + ':'">
+                                    <uni-easyinput v-model="dialogFllowDataApply.leverage"
+                                        :placeholder="t('placeholder.input')" :disabled="true" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+
+                    <!-- 展示设置 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item32') }}</text>
+                    </view>
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="historyShow"
+                                    :label="t('Documentary.TundManagement.item34') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.historyShow" :clearable="false"
+                                        :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="historyTime"
+                                    :label="t('Documentary.TundManagement.item35') + ':'">
+                                    <uni-datetime-picker v-model="dialogFllowDataApply.historyTime" type="date"
+                                        :placeholder="t('Documentary.TundManagement.item37')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+                    <view class="form-item">
+                        <uni-forms-item name="introduceShow" :label="t('Documentary.TundManagement.item36') + ':'">
+                            <cwg-combox v-model:value="dialogFllowDataApply.introduceShow" :clearable="false"
+                                :options="[{ text: t('Btn.item6'), value: 1 }, { text: t('Btn.item7'), value: 0 }]"
+                                :placeholder="t('placeholder.choose')" />
+                        </uni-forms-item>
+                    </view>
+
+                    <!-- 分润设置 -->
+                    <view class="fllow-title">
+                        <text class="title">{{ t('Documentary.TundManagement.item33') }}</text>
+                    </view>
+
+                    <view class="form-row">
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="distributionType"
+                                    :label="t('Documentary.TundManagement.item38') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.distributionType" :clearable="false"
+                                        :options="[{ text: t('Documentary.TundManagement.item59'), value: 1 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="distributionRatio"
+                                    :label="t('Documentary.TundManagement.item39') + '(%):'">
+                                    <uni-easyinput v-model="dialogFllowDataApply.distributionRatio"
+                                        :placeholder="t('placeholder.input')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                        <view class="form-col">
+                            <view class="form-item">
+                                <uni-forms-item name="settlementCycle"
+                                    :label="t('Documentary.tradingCenter.item32') + ':'">
+                                    <cwg-combox v-model:value="dialogFllowDataApply.settlementCycle" :clearable="false"
+                                        :options="[{ text: 7, value: 7 }, { text: 15, value: 15 }, { text: 30, value: 30 }]"
+                                        :placeholder="t('placeholder.choose')" />
+                                </uni-forms-item>
+                            </view>
+                        </view>
+                    </view>
+
+                    <view class="form-item agree">
+                        <uni-forms-item name="agree">
+                            <checkbox-group :value="dialogFllowDataApply.agree ? ['1'] : []" @change="onAgreeChange">
+                                <label class="checkbox-agree">
+                                    <checkbox value="1" :checked="dialogFllowDataApply.agree" />
+                                    <text class="agree-text">
+                                        {{ t('Documentary.TundManagement.item42') }}
+                                        <cwg-link style="text-decoration: underline;" class="a"
+                                            :url="isZh ? 'pdf/CopyTradeUserAgreementcn.pdf' : 'pdf/CopyTradeUserAgreement.pdf'"
+                                            target="_blank" title="Documentary.TundManagement.item43" />
+                                        {{ t('Documentary.TundManagement.item42_2') }}
+                                    </text>
+                                </label>
+                            </checkbox-group>
+                        </uni-forms-item>
+                    </view>
+                </view>
+            </uni-forms>
+
+            <template #footer>
+                <button @click="ApplyFllowCancel">{{ t('Btn.Cancel') }}</button>
+                <button type="primary" @click="ApplyFllow">{{ t('Btn.Confirm') }}</button>
+            </template>
+        </cwg-popup>
+
+    </cwg-page-wrapper>
+</template>
+
+<script setup lang="ts">
+import { computed, ref, nextTick, onMounted, reactive, watch } from 'vue';
+import { isAfterJuly28 } from '@/utils/dateUtils'
+import { useI18n } from 'vue-i18n';
+const { t, locale } = useI18n();
+import { documentaryApi } from '@/service/documentary';
+import useUserStore from "@/stores/use-user-store";
+const userStore = useUserStore();
+const userInfo = computed(() => userStore.userInfo);
+import { useFilters } from '@/composables/useFilters'
+const { numberFormat, numberDecimal } = useFilters()
+import { useRouter } from 'vue-router'
+const router = useRouter()
+
+const search = ref({
+    status: 1,
+    followLogin: '',
+    endTime: '',
+    startTime: ''
+})
+const typeMap = [
+    { value: 'MT4', text: 'MT4' },
+    { value: 'MT5', text: 'MT5' }]
+const isZh = computed(() => ['cn', 'zh', 'zhHant'].includes(locale.value));
+// 账户类型映射
+const accountTypeMap = {
+    1: 'AccountType.ClassicAccount',
+    2: 'AccountType.SeniorAccount',
+    5: 'AccountType.SpeedAccount',
+    6: 'AccountType.SpeedAccount',
+    7: 'AccountType.StandardAccount',
+    8: 'AccountType.CentAccount'
+}
+// 拒绝原因映射(示例)
+const reasons = ref({})
+// 动态传入筛选字段配置
+const filterFields = computed(() => [
+    { key: 'followPlatform', type: 'select', label: t('Label.Platform'), placeholder: t('placeholder.choose'), options: typeMap },
+    !isSubscribeLoading.value && { key: 'followLogin', type: 'select', label: t('Documentary.console.item28'), placeholder: t('placeholder.choose'), options: SubscribeDownData.value },
+    { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
+])
+const formRef = ref(null)
+const rules = {
+    password: {
+        rules: [
+            {
+                required: true,
+                validateFunction: (rule, value, data, callback) => {
+                    if (Config.Pattern.Password.test(value)) {
+                        callback()
+                    } else {
+                        callback(t('vaildate.password.format'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    agree: {
+        rules: [
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (value) {
+                        callback()
+                    } else {
+                        callback(t('vaildate.agree.empty'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    platform: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    currency: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    leverage: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    loginType: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    dealLogin: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    distributionType: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    distributionRatio: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (value >= 0 && value <= 50) {
+                        callback()
+                    } else {
+                        callback('0-50')
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    settlementCycle: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    },
+    historyShow: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    historyTime: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    introduceShow: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    protectAmount: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    },
+    protectRatio: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    },
+    nickname: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (value && /^[0-9a-zA-Z]{1,24}$/.test(value)) {
+                        callback()
+                    } else {
+                        callback(t('Msg.nickname'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    personalSignature: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (!value || /^[\u4e00-\u9fa5a-zA-Z\s]*$/.test(value)) {
+                        callback()
+                    } else {
+                        callback(t('Documentary.console.item38'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    traderStrategy: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (!value || /^[\u4e00-\u9fa5a-zA-Z\s]*$/.test(value)) {
+                        callback()
+                    } else {
+                        callback(t('Documentary.console.item38'))
+                    }
+                    return true
+                }
+            }
+        ]
+    },
+    followType: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty')
+            }
+        ]
+    },
+    volume: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    },
+    ratio: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty')
+            }
+        ]
+    }
+}
+const SubscribeDownData = ref([])
+//获取客户跟单账户的下拉列表
+const isSubscribeLoading = ref(false)
+const getSubscribeLoginDown = async () => {
+    isSubscribeLoading.value = true
+    let res = await documentaryApi.followDealSubscribeLoginList({
+        platform: "",
+        page: null,
+    });
+    if (res.code == 200) {
+        SubscribeDownData.value = res.data?.map(item => ({
+            text: t('Documentary.console.item28') + '-' + item.followLogin || '--',
+            value: item.followLogin
+        })) || []
+    } else {
+        uni.showToast({
+            title: res.msg,
+            icon: 'none'
+        })
+    }
+    isSubscribeLoading.value = false
+}
+const filterChineseEnglishOnlyForApply = (field, value, type) => {
+    // 只保留中文、英文和空格
+    const filtered = value.replace(/[^\u4e00-\u9fa5a-zA-Z\s]/g, '');
+    // 去掉前后空格,如果没有正文内容(全是空格)就设置为空字符串
+    const trimmed = filtered.trim();
+    if (type == 1) {
+        nextTick(() => {
+            dialogFllowData.value[field] = trimmed;
+        })
+    } else {
+        nextTick(() => {
+            dialogFllowDataApply[field] = trimmed;
+        })
+    }
+}
+
+const onAgreeChange = (e) => {
+    dialogFllowDataApply.agree = e.detail.value.length > 0
+}
+const searchParams = ref({})
+const tableRef = ref(null)
+const handleSearch = (params) => {
+    search.value = { ...search.value, ...params }
+    nextTick(() => {
+        tableRef.value.refreshTable()
+    })
+}
+
+const handleReset = (params) => {
+    search.value = { ...search.value, ...params }
+    nextTick(() => {
+        tableRef.value.refreshTable()
+    })
+}
+const currentColumns = computed(() => [
+    {
+        prop: 'dealNickname',
+        label: t('Documentary.tradingCenter.item1'),
+        align: 'center',
+        formatter: ({ row }) => row.dealNickname || '--'
+    },
+    {
+        prop: 'dealLogin',
+        label: t('Documentary.tradingCenter.item18'),
+        align: 'center',
+        formatter: ({ row }) => row.dealLogin || '--'
+    },
+    {
+        prop: 'followLogin',
+        label: t('Documentary.console.item28'),
+        align: 'center',
+        formatter: ({ row }) => row.followLogin || '--'
+    },
+    {
+        prop: 'followPlatform',
+        label: t('Label.Platform'),
+        align: 'center',
+        formatter: ({ row }) => row.followPlatform || '--'
+    },
+    {
+        prop: 'followLeverage',
+        label: t('Label.Leverage'),
+        align: 'center',
+        formatter: ({ row }) => row.followLeverage ? `1:${row.followLeverage}` : '--'
+    },
+    {
+        prop: 'followType',
+        label: t('Documentary.TundManagement.item19'),
+        align: 'center',
+        slot: 'followType'
+    },
+    {
+        prop: 'followValue',
+        label: t('Documentary.TundManagement.item20'),
+        align: 'center',
+        slot: 'followValue'
+    },
+    {
+        prop: 'balanceEquity',
+        label: t('Label.Balance'),
+        align: 'center',
+        children: [
+            {
+                prop: 'followEquity',
+                label: t('Label.Equity'),
+                align: 'center',
+                slot: 'balanceEquity'
+            }
+        ]
+    },
+    {
+        prop: 'timeRange',
+        label: t('Documentary.TundManagement.item26'),
+        align: 'center',
+        children: [
+            {
+                prop: 'startTime',
+                label: t('Documentary.TundManagement.item27'),
+                align: 'center',
+                slot: 'timeRange'
+            }
+        ]
+    },
+    {
+        prop: 'followProfit',
+        label: t('Documentary.TundManagement.item21'),
+        align: 'center',
+        formatter: ({ row }) => NumberFormat(row.followProfit || 0)
+    },
+    {
+        prop: 'action',
+        label: t('Label.Action'),
+        align: 'center',
+        slot: 'action'
+    }
+])
+// 获取状态文本
+const getStatusText = (row: any) => {
+    const status = row.status
+    // 根据不同记录类型处理状态
+    if (search.value.type === 1) {
+        if (status === 1) return t('State.ToBeProcessed')
+        if (status === 2 && row.accountStatus === 2) return t('State.Completed')
+        if (status === 2 && (row.accountStatus === 1 || !row.accountStatus)) return t('State.InTheProcessing')
+        if (status === 3) return t('State.Refused')
+    } else if (search.value.type === 2) {
+        if (status === 1) return t('State.ToBeProcessed')
+        if (status === 2 && row.leverageStatus === 2) return t('State.Completed')
+        if (status === 2 && row.leverageStatus === 1) return t('State.InTheProcessing')
+        if (status === 3) return t('State.Refused')
+    } else if (search.value.type === 3 || search.value.type === 5) {
+        if (status === 1) return t('State.ToBeProcessed')
+        if (status === 2 && row.withdrawStatus === 2 && row.depositStatus === 2) return t('State.Completed')
+        if (status === 2 && (row.withdrawStatus === 1 || row.depositStatus === 1)) return t('State.InTheProcessing')
+        if (status === 3 || row.withdrawStatus === 3 || row.depositStatus === 3) return t('State.Refused')
+    } else {
+        // 活动申请等
+        if (status === 1) return t('State.ToBeProcessed')
+        if (status === 2) return t('State.Completed')
+        if (status === 3) return t('State.Refused')
+    }
+    return ''
+}
+// 获取状态样式类
+const getStatusClass = (status: number) => {
+    const classMap: Record<number, string> = {
+        1: 'status-pending',
+        2: 'status-success',
+        3: 'status-processing',
+        4: 'status-danger'
+    }
+    return classMap[status] || ''
+}
+// 获取账户类型文本
+const getAccountTypeText = (type: number) => {
+    const key = accountTypeMap[type as keyof typeof accountTypeMap]
+    return key ? t(key) : '--'
+}
+// 格式化数字
+const formatNumber = (value: string | number) => {
+    if (!value) return '--'
+    const num = Number(value)
+    return isNaN(num) ? '--' : num.toFixed(2)
+}
+// 格式化备注
+const formatNote = (approveDesc: string) => {
+    if (!approveDesc) return '--'
+    const reason = reasons.value[approveDesc as keyof typeof reasons.value]
+    if (reason) {
+        return isZh.value ? reason.content : reason.enContent
+    }
+    return approveDesc
+}
+// 单位类型
+function groupCurrency(type) {
+    const map = { GBP: ': £', USD: ': $', EUR: ': €', USC: ': ¢' }
+    return map[type] || ': $'
+}
+// 单位类型
+function groupCurrency1(type) {
+    const map = { GBP: '£', USD: '$', EUR: '€', USC: '¢' }
+    return map[type] || '$'
+}
+
+
+// 账户类型
+function groupTypeName(type) {
+    const typeMap = {
+        '1': t('AccountType.ClassicAccount'),
+        '2': t('AccountType.SeniorAccount'),
+        '3': isAfterJuly28() ? '--' : t('AccountType.AgencyAccount'),
+        '5': t('AccountType.SpeedAccount'),
+        '6': t('AccountType.SpeedAccount'),
+        '7': t('AccountType.StandardAccount'),
+        '8': t('AccountType.CentAccount')
+    }
+    console.log(type, 3333);
+
+    return typeMap[type] || ''
+}
+
+const loginOptions = computed(() => loginOptionsLogin.value.map(item => ({
+    text: `${item.login} - ${groupTypeName(item.type)} - ${t('Custom.Deposit.AvailableBalance')}${groupCurrency(item.currency)}${item.balance}`,
+    value: item.login,
+    disable: item.balance < 200
+})))
+
+const selectLoginDeal = () => {
+    loginOptionsLogin.value.forEach((item) => {
+        if (item.login == dialogFllowDataApply.dealLogin) {
+            dialogFllowDataApply.leverage = "1:" + item.leverage;
+            dialogFllowDataApply.loginType = item.type;
+            dialogFllowDataApply.platform = item.platform;
+        }
+    });
+}
+
+const applyRef = ref(null)
+const dialogFllowDataApply = reactive({
+    dealLogin: '',
+    leverage: '',
+    loginType: '',
+    platform: '',
+    currency: '',
+    leverageStatus: '',
+    withdrawStatus: '',
+    depositStatus: '',
+    accountStatus: '',
+    status: '',
+    note: '',
+    followType: '',
+    volume: '',
+    ratio: '',
+    traderStrategy: '',
+    personalSignature: '',
+    nickname: '',
+    protectAmount: '',
+    protectRatio: '',
+    introduceShow: '',
+    historyShow: '',
+    historyTime: '',
+    settlementCycle: '',
+    distributionType: '',
+    distributionRatio: '',
+    withdrawCurrency: '',
+    withdrawAmount: '',
+    depositCurrency: '',
+    depositAmount: '',
+    withdrawLogin: '',
+    depositLogin: '',
+    addTime: '',
+    title: '',
+})
+const loginOptionsLogin = ref([])
+const dialogFllowApply = ref(false)
+//获取申请信号源交易账户下拉
+const toSubscribeList = async () => {
+    router.push('/pages/follow/trading-center')
+}
+const getCustomLoginDownLogin = async () => {
+    if (flag.value) {
+        return;
+    } else {
+        flag.value = true;
+    }
+    let res = await documentaryApi.CustomDropdownData({
+        platform: "",
+    });
+    if (res.code == 200) {
+        loginOptionsLogin.value = res.data;
+        dialogFllowApply.value = true;
+    } else {
+        uni.showToast({
+            title: res.msg,
+            icon: 'none'
+        });
+    }
+    flag.value = false;
+}
+watch(() => dialogFllowDataApply.dealLogin, (newVal, oldVal) => {
+    if (newVal !== oldVal) {
+        selectLoginDeal();
+    }
+})
+
+//申请信号源
+const ApplyFllow = async () => {
+    try {
+        await applyRef.value.validate()
+        if (flag.value) {
+            return;
+        } else {
+            flag.value = true;
+        }
+        let res = await documentaryApi.followDealApply({
+            ...dialogFllowDataApply,
+        });
+        if (res.code == 200) {
+            uni.showToast({
+                title: t("Msg.Success"),
+                icon: 'none'
+            });
+            ApplyFllowCancel();
+            tableRef.value.refreshTable();
+            getDealLogin();
+            flag.value = false;
+        } else {
+            uni.showToast({
+                title: res.msg,
+                icon: 'none'
+            });
+            flag.value = false;
+        }
+    } catch (error) {
+        return false;
+    } finally {
+        flag.value = false;
+    }
+}
+const ApplyFllowCancel = () => {
+    applyRef.value &&
+        applyRef.value.clearValidate();
+    dialogFllowApply.value = false;
+}
+
+//获取客户信号源账户
+const accountDataLoading = ref(false)
+const accountData = ref([])
+const accountPager = ref({
+    current: 1,
+    row: 10,
+    rowTotal: 0,
+    pageTotal: 0
+})
+const getDealLogin = async () => {
+    accountDataLoading.value = true;
+    let res = await documentaryApi.followDealSubscribeLoginList({
+        platform: null,
+        page: {
+            current: accountPager.value.current,
+            row: accountPager.value.row,
+        },
+    });
+    if (res.code == 200) {
+        accountData.value = res.data || []
+        accountPager.value.rowTotal = res.page.rowTotal;
+        accountPager.value.pageTotal = res.page.pageTotal;
+    } else {
+        uni.showToast({
+            title: res.msg,
+            icon: 'none'
+        });
+    }
+    accountDataLoading.value = false;
+
+}
+//修改信号源
+const dialogFllowData = ref({})
+const dialogFllow = ref(false)
+const dialogFllowDataDelete = ref({})
+const dialogFllowDelete = ref(false)
+const flag = ref(false)
+const dialogFllowUpdate = (item) => {
+    dialogFllowData.value = item;
+    dialogFllow.value = true;
+}
+const FllowUpdate = async () => {
+    try {
+        await formRef.value.validate()
+        if (flag.value) {
+            return;
+        } else {
+            flag.value = true;
+        }
+
+        let res = await documentaryApi.followDealUpdate({
+            ...dialogFllowData.value,
+        });
+        if (res.code == 200) {
+            uni.showToast({
+                title: t("Msg.Success"),
+                icon: 'none'
+            });
+            FllowUpdateCancel();
+            tableRef.value.refreshTable()
+            getDealLogin();
+            console.log(222);
+
+            flag.value = false;
+        } else {
+            uni.showToast({
+                title: res.msg,
+                icon: 'none'
+            });
+            flag.value = false;
+        }
+    } catch (error) {
+        flag.value = false;
+    }
+}
+const FllowUpdateCancel = () => {
+    formRef.value && formRef.value.clearValidate();
+
+    dialogFllow.value = false;
+}
+//删除信号源
+const dialogFllowDele = (item) => {
+    dialogFllowDataDelete.value = item;
+    dialogFllowDelete.value = true;
+}
+const FllowDele = async () => {
+    if (flag.value) {
+        return;
+    } else {
+        flag.value = true;
+    }
+
+    let res = await documentaryApi.followDealDelete({
+        ids: [dialogFllowDataDelete.value.id],
+    });
+    if (res.code == 200) {
+        uni.showToast({
+            title: t("Msg.Success"),
+            icon: 'none'
+        });
+        FllowDeleCancel();
+        tableRef.value.refreshTable()
+        getDealLogin();
+        flag.value = false;
+    } else {
+        uni.showToast({
+            title: res.msg,
+            icon: 'none'
+        });
+        flag.value = false;
+    }
+}
+const FllowDeleCancel = () => {
+    dialogFllowDelete.value = false;
+}
+const listApi = ref(null)
+onMounted(() => {
+    getDealLogin()
+    getSubscribeLoginDown()
+    listApi.value = documentaryApi.followDealSubscribeList
+})
+
+</script>
+
+<style scoped lang="scss">
+@import "@/uni.scss";
+
+.avatar {
+    width: px2rpx(60);
+    height: px2rpx(60);
+    border-radius: 4px;
+}
+
+
+.content-title {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: px2rpx(22);
+    font-weight: 500;
+    color: var(--color-slate-800);
+    background-color: rgba(255, 255, 255, 0);
+
+    .content-title-btns {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        gap: px2rpx(12);
+
+
+        .btn-primary {
+            min-width: px2rpx(120);
+            background-color: var(--color-error);
+            color: #fff;
+            padding: 0 px2rpx(12);
+            border: none;
+            font-size: px2rpx(14);
+            text-align: center;
+            cursor: pointer;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            gap: px2rpx(8);
+        }
+
+        .btn-primary1 {
+            background-color: #cf1322;
+            ;
+        }
+
+        .btn-primary2 {
+            background-color: var(--color-secondary-focus);
+        }
+    }
+}
+
+.operation-btn {
+    :deep(text) {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        gap: px2rpx(4);
+        cursor: pointer;
+        background-color: var(--color-slate-150);
+        padding: px2rpx(8) 0;
+    }
+}
+
+.operation-btn.disabled {
+    cursor: not-allowed;
+    opacity: 0.5;
+}
+
+.search-bar {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    flex-wrap: wrap;
+    gap: px2rpx(16);
+    margin: px2rpx(26) 0;
+
+    .cwg-combox,
+    .uni-easyinput,
+    .uni-date {
+        width: px2rpx(240) !important;
+        flex: none;
+    }
+}
+
+.dia-content {
+    padding: px2rpx(20);
+
+    .uni-forms-item {
+        width: 100%;
+    }
+
+    .grid-layout {
+        display: grid;
+        grid-template-columns: 1fr 1fr;
+        gap: px2rpx(20);
+        margin: px2rpx(24) 0;
+        padding: px2rpx(20);
+        background-color: #f8f9fa;
+        border-radius: px2rpx(8);
+        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+    }
+
+
+
+    .fllow-title {
+        margin: px2rpx(10) 0 px2rpx(16);
+        padding-left: px2rpx(8);
+        border-left: 4px solid #dc3545;
+        border-bottom: none;
+
+        .title {
+            font-size: px2rpx(16);
+            font-weight: 600;
+            color: #343a40;
+        }
+    }
+
+    .delete-grid {
+        margin: px2rpx(16) 0;
+    }
+
+    .delete-row {
+        display: flex;
+        gap: px2rpx(12);
+    }
+
+    .delete-item {
+        flex: 1;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: px2rpx(12) 0;
+        border-bottom: 1px dashed #e9ecef;
+
+        &:first-child {
+            padding-right: px2rpx(16);
+        }
+
+        &:last-child {
+            padding-left: px2rpx(16);
+        }
+    }
+
+    .delete-label {
+        font-size: px2rpx(14);
+        color: #6c757d;
+    }
+
+    .delete-value {
+        font-size: px2rpx(14);
+        color: #343a40;
+        font-weight: 400;
+    }
+
+    .delete-tip {
+        margin-top: px2rpx(16);
+        font-size: px2rpx(14);
+        color: #6c757d;
+        line-height: 1.5;
+        padding-top: px2rpx(16);
+    }
+
+    .tip-star {
+        color: #dc3545;
+        margin-right: px2rpx(4);
+    }
+
+    .agree {
+        margin-top: px2rpx(20);
+    }
+
+    .checkbox-agree {
+        display: flex;
+        align-items: flex-start;
+        gap: px2rpx(8);
+
+        .agree-text {
+            font-size: px2rpx(14);
+            color: #6c757d;
+            line-height: 1.5;
+            width: 100%;
+            white-space: wrap;
+
+            .a {
+                color: #007bff;
+                text-decoration: underline;
+                margin: 0 px2rpx(4);
+
+                &:hover {
+                    color: #0056b3;
+                }
+            }
+        }
+    }
+
+    .fllow-content {
+        margin-bottom: px2rpx(16);
+
+        .tit {
+            font-size: px2rpx(14);
+            font-weight: 500;
+            color: #6c757d;
+            margin-bottom: px2rpx(6);
+            text-transform: uppercase;
+            letter-spacing: px2rpx(0.5);
+        }
+
+        .con {
+            font-size: px2rpx(16);
+            font-weight: 400;
+            color: #343a40;
+            line-height: 1.4;
+        }
+    }
+
+    .form-row {
+        display: grid;
+        grid-template-columns: 1fr 1fr;
+        gap: px2rpx(20);
+        margin-top: px2rpx(16);
+    }
+
+    .form-item {
+        display: flex;
+        flex-direction: column;
+        align-items: flex-start;
+
+        text {
+            font-size: px2rpx(14);
+            font-weight: 500;
+            color: #6c757d;
+            margin-bottom: px2rpx(8);
+            white-space: nowrap;
+        }
+
+        input,
+        select,
+        textarea {
+            width: 100%;
+            padding: px2rpx(10);
+            border: 1px solid #ced4da;
+            border-radius: px2rpx(4);
+            font-size: px2rpx(14);
+            transition: all 0.2s ease;
+
+            &:focus {
+                outline: none;
+                border-color: #4dabf7;
+                box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.2);
+            }
+        }
+
+        textarea {
+            resize: vertical;
+            min-height: px2rpx(100);
+        }
+    }
+
+    .tip-red {
+        color: #dc3545;
+        font-size: px2rpx(14);
+        margin: px2rpx(12) 0 px2rpx(24) 0;
+    }
+
+    .tip-text {
+        margin-top: px2rpx(24);
+        font-size: px2rpx(14);
+        color: #6c757d;
+        line-height: 1.5;
+        padding: px2rpx(16);
+        background-color: #e7f3ff;
+        border-radius: px2rpx(4);
+        border-left: 4px solid #4dabf7;
+    }
+}
+
+/* 弹窗按钮样式 */
+:deep(.cwg-popup__footer) {
+    display: flex;
+    gap: px2rpx(20);
+    padding: px2rpx(20);
+    border-top: 1px solid #e9ecef;
+
+    button {
+        flex: 1;
+        padding: px2rpx(12) 0;
+        border-radius: px2rpx(4);
+        font-size: px2rpx(14);
+        font-weight: 500;
+        transition: all 0.2s ease;
+
+        &:first-child {
+            background-color: #fff;
+            color: #495057;
+            border: 1px solid #ced4da;
+
+            &:hover {
+                background-color: #f8f9fa;
+                border-color: #adb5bd;
+            }
+
+            &:active {
+                transform: scale(0.98);
+            }
+        }
+
+        &:last-child {
+            background-color: #dc3545;
+            color: white;
+            border: 1px solid #dc3545;
+
+            &:hover {
+                background-color: #c82333;
+                border-color: #bd2130;
+            }
+
+            &:active {
+                transform: scale(0.98);
+            }
+        }
+    }
+}
+</style>

+ 22 - 56
pages/follow/trading-management.vue

@@ -1,20 +1,20 @@
 <template>
     <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
-        <cwg-header :title="t('Documentary.TundManagement.item8')" />
+
         <view class="content-container">
             <!-- 动态字段列表 -->
-            <view class="field-container">
-                <view class="content-title">
-                    <view v-t="'Documentary.TundManagement.item11'"></view>
-                    <view class="content-title-btns">
-                        <view class="btn-primary btn-primary1" @click="getCustomLoginDownLogin()">
-                            <cwg-icon icon="crm-plus" :size="16" color="#fff" />
-                            <text v-t="'Documentary.TundManagement.item12'" />
-                        </view>
+            <view class="content-title">
+                <cwg-header :title="t('Documentary.TundManagement.item8')" />
+                <view class="content-title-btns">
+                    <view class="btn-primary btn-primary1" @click="getCustomLoginDownLogin()">
+                        <cwg-icon icon="crm-plus" :size="16" color="#fff" />
+                        <text v-t="'Documentary.TundManagement.item12'" />
                     </view>
                 </view>
-                <uni-loading v-if="accountDataLoading" />
-                <template v-else>
+            </view>
+            <uni-loading v-if="accountDataLoading" />
+            <template v-else>
+                <view class="field-container" v-if="accountData.length > 0">
                     <view class="account-l-con" v-for="(item, index) in accountData" :key="index">
                         <view class="tit">
                             <view>
@@ -78,35 +78,9 @@
                             </view>
                         </view>
                     </view>
-                    <cwg-empty-state v-if="accountData.length == 0" />
-                </template>
-            </view>
-            <view class="info-card">
-                <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
-                    @reset="handleReset" />
-                <cwg-tabel ref="tableRef" :columns="currentColumns" :immediate="false" :queryParams="search"
-                    :api="listApi" :show-operation="false">
-                    <!-- 状态列自定义渲染 -->
-                    <template #status="{ row }">
-                        <view v-if="getStatusText(row)" class="status-tag" :class="getStatusClass(row.status)">
-                            {{ getStatusText(row) }}
-                        </view>
-                        <view v-else></view>
-                    </template>
-                    <!-- 账户类型列自定义渲染 -->
-                    <template #accountType="{ row }">
-                        {{ getAccountTypeText(row.type || row.loginType) }}
-                    </template>
-                    <!-- 金额列格式化 -->
-                    <template #amount="{ row }">
-                        <view>-{{ formatNumber(row.withdrawAmount || row.amount) }}</view>
-                    </template>
-                    <!-- 备注列格式化 -->
-                    <template #note="{ row }">
-                        <view>{{ formatNote(row.approveDesc) }}</view>
-                    </template>
-                </cwg-tabel>
-            </view>
+                </view>
+                <cwg-empty-state v-if="accountData.length == 0" />
+            </template>
         </view>
         <!-- 删除信号源 -->
         <cwg-popup v-model:visible="dialogFllowDelete" type="center" :mask-click="false" :show-footers="true"
@@ -1271,24 +1245,19 @@ onMounted(() => {
 @import "@/uni.scss";
 
 .content-container {
-    display: grid;
-    grid-template-columns: 1fr 2fr;
-    gap: px2rpx(16);
-    width: 100%;
-    min-width: 0;
-    overflow: hidden;
 
-    @media (max-width: 991px) {
-        grid-template-columns: 1fr;
-    }
 
     .field-container {
-        display: flex;
-        flex-direction: column;
-        gap: px2rpx(12);
+        display: grid;
+        grid-template-columns: repeat(3, 1fr);
+        gap: px2rpx(16);
         min-width: 0;
         overflow: hidden;
 
+        @media (max-width: 991px) {
+            grid-template-columns: 1fr;
+        }
+
         .account-l-con {
             background-color: #f8f9fa;
             border-radius: px2rpx(8);
@@ -1411,16 +1380,13 @@ onMounted(() => {
     display: flex;
     justify-content: space-between;
     align-items: center;
-    font-size: px2rpx(22);
-    font-weight: 500;
-    color: var(--color-slate-800);
-    background-color: rgba(255, 255, 255, 0);
 
     .content-title-btns {
         display: flex;
         align-items: center;
         justify-content: center;
         gap: px2rpx(12);
+        margin-bottom: px2rpx(24);
 
 
         .btn-primary {