Просмотр исходного кода

Merge branch 'admin_dev' of http://112.213.107.185:3000/cwg-crm/gypsy-crm-frontend-vu into admin_dev

zhb 2 месяцев назад
Родитель
Сommit
d02520c78c
7 измененных файлов с 887 добавлено и 62 удалено
  1. 15 8
      components/IbInfo.vue
  2. 160 15
      pages/ib/accountList.vue
  3. 202 15
      pages/ib/agentList.vue
  4. 304 0
      pages/ib/components/applyIbDialog.vue
  5. 14 8
      pages/ib/customer.vue
  6. 178 15
      pages/ib/subsList.vue
  7. 14 1
      windows/left-window.vue

+ 15 - 8
components/IbInfo.vue

@@ -172,7 +172,7 @@
         </view>
         </view>
       </view>
       </view>
       <template #agree>
       <template #agree>
-        <view>
+        <view v-if="ibStatus.status == 0">
           <view class="agree" >
           <view class="agree" >
             <checkbox-group v-model="ibAgree" @change="onAgreeChange">
             <checkbox-group v-model="ibAgree" @change="onAgreeChange">
               <label class="checkbox">
               <label class="checkbox">
@@ -192,7 +192,7 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-  import { computed, ref, onMounted } from 'vue'
+  import { computed, ref, onMounted, emit } from 'vue'
   import { useI18n } from 'vue-i18n'
   import { useI18n } from 'vue-i18n'
   import useUserStore from '@/stores/use-user-store'
   import useUserStore from '@/stores/use-user-store'
   import useRouter from '@/hooks/useRouter'
   import useRouter from '@/hooks/useRouter'
@@ -218,6 +218,7 @@
   const customInfo = computed(() => {
   const customInfo = computed(() => {
     return userInfo.customInfo
     return userInfo.customInfo
   })
   })
+  const emit = defineEmits(['confirm', 'close'])
 
 
   const confirmText = computed(() => {
   const confirmText = computed(() => {
     return ibStatus.value.status == 3 ? t('Btn.AgainApply') : t('Btn.Confirm')
     return ibStatus.value.status == 3 ? t('Btn.AgainApply') : t('Btn.Confirm')
@@ -273,6 +274,7 @@
       applyIb()
       applyIb()
     }else if (status == 1) {
     }else if (status == 1) {
       dialogApplyIb.value.close()
       dialogApplyIb.value.close()
+      emit('close')
     }else if (status == 3) {
     }else if (status == 3) {
       ibStatus.value.status = 0
       ibStatus.value.status = 0
     }
     }
@@ -298,6 +300,7 @@ icon: 'none'})
       uni.showToast({title: t("Msg.Success"),icon: 'none'})
       uni.showToast({title: t("Msg.Success"),icon: 'none'})
       getLoginInfo();
       getLoginInfo();
       dialogApplyIb.value.close()
       dialogApplyIb.value.close()
+      emit('confirm')
       // reload();
       // reload();
     }
     }
   }
   }
@@ -306,14 +309,14 @@ icon: 'none'})
   const applyIbStatus = async () => {
   const applyIbStatus = async () => {
     let res = await customApi.customApplyIbStatus({})
     let res = await customApi.customApplyIbStatus({})
     if (res.code == Code.StatusOK) {
     if (res.code == Code.StatusOK) {
-      ibStatus.value = res.data
+      ibStatus.value = { ...res.data }
       if (ibStatus.value.status == 0) {
       if (ibStatus.value.status == 0) {
         dialogApplyIb.value.open()
         dialogApplyIb.value.open()
       } else if (ibStatus.value.status == 1) {
       } else if (ibStatus.value.status == 1) {
         dialogApplyIb.value.open()
         dialogApplyIb.value.open()
       } else if (ibStatus.value.status == 2) {
       } else if (ibStatus.value.status == 2) {
 
 
-      } else if (this.ibStatus.status == 3) {
+      } else if (ibStatus.value.status == 3) {
         searchReasons()
         searchReasons()
         dialogApplyIb.value.open()
         dialogApplyIb.value.open()
       }
       }
@@ -327,12 +330,16 @@ icon: 'none'})
 
 
   onMounted(() => {
   onMounted(() => {
   // 进入ib相关页面时,请求
   // 进入ib相关页面时,请求
-    if (route.path.indexOf('pages/ib/') !== -1) {
-      getLogin()
-    }
+  //   if (route.path.indexOf('pages/ib/') !== -1) {
+  //     getLogin()
+  //   }
     // dialogApplyIb.value.open()
     // dialogApplyIb.value.open()
   })
   })
-
+  // 暴露方法给父组件
+  defineExpose({
+    getInfo: getLogin,
+    open: () => popupRef.value?.open()
+  })
 
 
 </script>
 </script>
 
 

+ 160 - 15
pages/ib/accountList.vue

@@ -1,24 +1,169 @@
 <template>
 <template>
-    <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
-        <cwg-header :title="t('Home.page_ib.item2')" />
+  <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
+    <cwg-header :title="t('Home.page_ib.item10')" />
 
 
-        <view class="account-section">
+    <view class="account-content">
+      <view class="search-content">
+        <view class="search-bar">
+          <cwg-combox v-model:value="search.platform" :options="platformOptions"
+                      :placeholder="t('placeholder.choose')" />
+          <uni-easyinput v-model="search.login" :placeholder="t('Label.Login')" />
+          <uni-easyinput v-model="search.cId" placeholder="CID" />
+          <uni-datetime-picker type="daterange" v-model="search.date"
+                               :placeholder="t('placeholder.Start') + ' - ' + t('placeholder.End')" @change="handleDateChange"/>
         </view>
         </view>
-    </cwg-page-wrapper>
+        <view />
+      </view>
+      <cwg-tabel
+        ref="tableRef"
+        :columns="columns"
+        :mobilePrimaryFields="mobilePrimaryFields"
+        :queryParams="search"
+        :api="listApi"
+        :show-operation="true"
+        :showPagination="true"
+      >
+        <template #action="{ row }">
+          <cwg-dropdown :menu-list="menuList(row)" @menuClick="handleMenuClick">
+            <view class="pc-header-btn">
+              <cwg-icon name="crm-ellipsis" :size="24" />
+            </view>
+          </cwg-dropdown>
+        </template>
+      </cwg-tabel>
+    </view>
+  </cwg-page-wrapper>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
-import { customApi } from '@/service/custom'
-import { financialApi } from '@/service/financial'
-import Config from '@/config/index'
-import AddBankDialog from '@/components/AddBankDialog.vue';
-import PaymentMethodsList from './components/PaymentMethodsList.vue'
-const { t, locale } = useI18n()
-const isZh = computed(() => ['cn', 'zhHant'].includes(locale.value))
+  // 账户管理
+  import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
+  import { onLoad } from '@dcloudio/uni-app'
+  import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
+  import { customApi } from '@/service/custom'
+  import { financialApi } from '@/service/financial'
+  import Config from '@/config/index'
+  import { lang } from '@/composables/config'
+  import { ibApi } from '@/service/ib'
+  import { useFilters } from '@/composables/useFilters'
+
+  const { numberFormat, numberDecimal } = useFilters()
+
+  const search = ref({
+    cId: '',
+    login: '',
+    date: '',
+    platform: 'MT4',
+    startDate: '',
+    endDate: '',
+  })
+
+  const platformOptions = [
+    { text: 'MT4', value: 'MT4' },
+    { text: 'MT5', value: 'MT5' },
+  ]
+  const { t, locale } = useI18n()
+  // 表格列配置
+  const columns = ref([
+    {
+      prop: 'login',
+      label: t('Label.Login'),
+      align: 'center',
+    },
+    {
+      prop: 'name',
+      label: t('Ib.Custom.NameLabel'),
+      align: 'center',
+    },
+    {
+      prop: 'platform',
+      label: t('Label.Platform'),
+      align: 'center',
+    },
+    {
+      prop: 'groupName',
+      label: t('Label.GroupName'),
+      align: 'center',
+    },
+    {
+      prop: 'type',
+      type: 'tag',
+      label: t('Label.LoginType'),
+      align: 'center',
+      tagMap: {
+        1: t('AccountType.ClassicAccount'),
+        2: t('AccountType.SeniorAccount'),
+        5: t('AccountType.SpeedAccount'),
+        6: t('AccountType.SpeedAccount'),
+        7: t('AccountType.StandardAccount'),
+        8: t('AccountType.CentAccount'),
+      },
+    },
+    {
+      prop: 'Leverage',
+      label: t('Label.Leverage'),
+      align: 'center',
+      formatter: ({ row }) => row.leverage ? `1:${row.leverage}` : '--',
+    },
+    {
+      prop: 'currency',
+      label: t('Label.Currency'),
+      align: 'center',
+    },
+    {
+      prop: 'balance',
+      label: t('Label.LoginBalance'),
+      align: 'center',
+      formatter: ({ row }) => numberFormat(row.balance ?? 0),
+    },
+    {
+      prop: 'countryEnName',
+      label: t('Label.Country'),
+      align: 'center',
+    },
+    {
+      prop: 'registration',
+      label: t('Label.ApplyTime'),
+      align: 'center',
+    },
+  ])
+
+  const mobilePrimaryFields = ref([
+    {
+      prop: 'login',
+      label: t('Label.Login'),
+      align: 'center',
+    },
+    {
+      prop: 'name',
+      label: t('Ib.Custom.NameLabel'),
+      align: 'center',
+    },
+    {
+      prop: 'platform',
+      label: t('Label.Platform'),
+      align: 'center',
+    },
+    {
+      prop: 'more',
+      type: 'more',
+      width: 20,
+      align: 'right',
+    },
+  ])
+
+
+  const listApi = ref(ibApi.accountSubs)
+  const handleDateChange = (val) => {
+    search.value.startDate = val[0]
+    search.value.endDate = val[1]
+  }
 </script>
 </script>
 <style lang="scss" scoped>
 <style lang="scss" scoped>
-@import "@/uni.scss";
+  @import "@/uni.scss";
+
+  .search-content {
+    display: flex;
+    justify-content: space-between;
+  }
 </style>
 </style>

+ 202 - 15
pages/ib/agentList.vue

@@ -1,24 +1,211 @@
 <template>
 <template>
-    <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
-        <cwg-header :title="t('Home.page_ib.item2')" />
+  <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
+    <cwg-header :title="t('Documentary.console.item23')" />
 
 
-        <view class="account-section">
+    <view class="account-content">
+      <view class="search-content">
+        <view class="search-bar">
+          <uni-easyinput v-model="search.cId" placeholder="CID" />
         </view>
         </view>
-    </cwg-page-wrapper>
+        <view class="search-bar">
+          <button type="primary" class="search-button" @click="addSub">
+            <cwg-icon name="icon_add" :size="18" color="#fff"></cwg-icon>
+            {{t('Ib.Report.Title5')}}
+          </button>
+        </view>
+      </view>
+      <cwg-tabel
+        class="table-container"
+        ref="tableRef"
+        :columns="columns"
+        :mobilePrimaryFields="mobilePrimaryFields"
+        :queryParams="search"
+        :api="listApi"
+        :show-operation="true"
+        :showPagination="true"
+      >
+        <template #action="{ row }">
+          <cwg-dropdown :menu-list="menuList(row)" @menuClick="handleMenuClick">
+            <view class="pc-header-btn">
+              <cwg-icon name="crm-ellipsis" :size="24" />
+            </view>
+          </cwg-dropdown>
+        </template>
+      </cwg-tabel>
+    </view>
+  </cwg-page-wrapper>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
-import { customApi } from '@/service/custom'
-import { financialApi } from '@/service/financial'
-import Config from '@/config/index'
-import AddBankDialog from '@/components/AddBankDialog.vue';
-import PaymentMethodsList from './components/PaymentMethodsList.vue'
-const { t, locale } = useI18n()
-const isZh = computed(() => ['cn', 'zhHant'].includes(locale.value))
+  // 信号源管理
+  import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
+  import { onLoad } from '@dcloudio/uni-app'
+  import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
+  import Config from '@/config/index'
+  import { lang } from '@/composables/config'
+  import { ibApi } from '@/service/ib'
+  import { useFilters } from '@/composables/useFilters'
+
+  const { numberFormat, numberDecimal } = useFilters()
+
+  const search = ref({
+    cId: '',
+  })
+  const { t, locale } = useI18n()
+  // 表格列配置
+  const columns = ref([
+    {
+      prop: 'dealCId',
+      label: t('Label.CidAccount'),
+      align: 'center',
+    },
+    {
+      prop: 'pIbNo',
+      label: t('Label.AgentNumber'),
+      align: 'center',
+    },
+    {
+      prop: 'nickname',
+      label: t('Documentary.console.item20'),
+      align: 'center',
+    },
+    {
+      prop: 'dealLogin',
+      label: t('Documentary.tradingCenter.item18'),
+      align: 'center',
+    },
+    {
+      prop: 'dealPlatform',
+      label: t('Label.Platform'),
+      align: 'center',
+    },
+    {
+      prop: 'dealLeverage',
+      label: t('Label.Leverage'),
+      align: 'center',
+    },
+    {
+      prop: 'dealLoginType',
+      type: 'tag',
+      label: t('Label.AccountType'),
+      align: 'center',
+      tagMap: {
+        1: t('AccountType.ClassicAccount'),
+        2: t('AccountType.SeniorAccount'),
+        5: t('AccountType.SpeedAccount'),
+        6: t('AccountType.SpeedAccount'),
+        7: t('AccountType.StandardAccount'),
+        8: t('AccountType.CentAccount'),
+      },
+    },
+    {
+      prop: 'distributionType',
+      label: t('Documentary.AgentBackground.item11'),
+      align: 'center',
+      formatter: ({ row }) => row.distributionType === 1 ? t('Documentary.TundManagement.item59') : '--',
+    },
+    {
+      prop: 'distributionRatio',
+      label: t('Documentary.Report.item5'),
+      align: 'center',
+    },
+    {
+      prop: 'settlementCycle',
+      label: t('Documentary.AgentBackground.item13'),
+      align: 'center',
+    },
+    {
+      prop: 'approveTime',
+      label: t('Label.ApplyTime'),
+      align: 'center',
+    },
+    {
+      prop: 'permissionDisplay',
+      type: 'tag',
+      label: t('Documentary.AgentBackground.item14'),
+      align: 'center',
+      tagMap: {
+        1: t('Documentary.AgentBackground.item16'),
+        2: t('Documentary.AgentBackground.item15'),
+      },
+    },
+    {
+      prop: 'action',
+      label: t('Label.Action'),
+      align: 'center',
+      slot: 'action',
+    },
+  ])
+
+  const mobilePrimaryFields = ref([
+    {
+      prop: 'cId',
+      label: t('Label.CidAccount'),
+      align: 'center',
+    },
+    {
+      prop: 'ibNo',
+      label: t('Label.IbAccount'),
+      align: 'center',
+    },
+    {
+      prop: 'name',
+      label: t('Ib.Custom.NameLabel'),
+      align: 'center',
+    },
+    {
+      prop: 'more',
+      type: 'more',
+      width: 20,
+      align: 'right',
+    },
+  ])
+
+
+  const listApi = ref(ibApi.IbSubs)
+  const handleDateChange = (val) => {
+    search.value.startDate = val[0]
+    search.value.endDate = val[1]
+  }
+
+  // 下拉菜单配置
+  const menuList = (row) => {
+    return [
+      {
+        label: t('Ib.Custom.Btn'),
+        type: 'DisplaySettings',
+        row,
+        show: row.agentUpdatePurview == '1',
+      },
+    ].filter((item) => item.show)
+  }
+  const handleMenuClick = (item) => {
+    if (item.type == 'DisplaySettings') {
+      const { cId, id, permissionDisplay } = item.row
+      formInfoRow.value = {
+        cId, id, permissionDisplay,
+      }
+      docVisible.value = true
+    } else if (item.type == 'exclusiveCommission') {
+      const { cId, id, comPoint1, hide1 } = item.row
+      pointForm.value = {
+        cId, id, comPoint1, hide1,
+      }
+      pointVisible.value = true
+    }
+  }
 </script>
 </script>
 <style lang="scss" scoped>
 <style lang="scss" scoped>
-@import "@/uni.scss";
+  @import "@/uni.scss";
+
+  .search-content {
+    display: flex;
+    justify-content: space-between;
+  }
+  .search-button{
+    display: flex;
+    align-items: center;
+    height: px2rpx(36);
+    line-height: px2rpx(36);
+  }
 </style>
 </style>

+ 304 - 0
pages/ib/components/applyIbDialog.vue

@@ -0,0 +1,304 @@
+<template>
+  <cwg-popup :title="t('Ib.Custom.AccountAdjust')" :visible="visible" @close="closeDia" @confirm="confirmDia">
+    <view class="dia-content dialog-account-adjust-body">
+
+    </view>
+  </cwg-popup>
+</template>
+
+<script setup lang="ts">
+  import { ref, reactive, computed, onMounted, onUnmounted, watch } from 'vue'
+  import { onLoad } from '@dcloudio/uni-app'
+  import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
+  import { customApi } from '@/service/custom'
+  import { financialApi } from '@/service/financial'
+  import Config from '@/config/index'
+  import { ibApi } from '@/service/ib'
+  import useUserStore from '@/stores/use-user-store'
+  import { lang } from '@/composables/config'
+
+  const props = defineProps({
+    // 是否显示弹窗
+    visible: {
+      type: Boolean,
+      default: false,
+    },
+    // 详情tableData
+    tableData: { type: Array, default: () => ([]) },
+  })
+  const { Code, Host80 } = Config
+  const { t } = useI18n()
+  const formRef = ref(null)
+  const dialogForm = ref({
+    cId: '123',
+  })
+  const commissionAccountTypeSettings = ref({
+    ecn: { selectedIndex: null, selectedItem: null, loginType: '2' },
+    standard: { selectedIndex: null, selectedItem: null, loginType: '7' },
+    cent: { selectedIndex: null, selectedItem: null, loginType: '8' },
+  })
+  const commissionAccountTypeData = ref({
+    ecn: [],
+    standard: [],
+    cent: [],
+  })
+  const emit = defineEmits(['close', 'confirm'])
+
+  onMounted(() => {
+    console.log(props.visible)
+  })
+  // 佣金调整弹框:拉取点差/价格数据(与 ConsumerShareLink getCustomLinkTypes 一致)
+  const loadCommissionAccountTypes = async (ibId) => {
+    const params = ibId ? { ibId } : {}
+    let res = await ibApi.customLinkTypes(params)
+    if (res.code == Code.StatusOK) {
+      const data = res.data || []
+      commissionAccountTypeData.value = {
+        ecn: data.filter(
+          (item) => item.loginType === 2 || item.loginType === '2',
+        ),
+        standard: data.filter(
+          (item) => item.loginType === 7 || item.loginType === '7',
+        ),
+        cent: data.filter(
+          (item) => item.loginType === 8 || item.loginType === '8',
+        ),
+      }
+    } else {
+      uni.showToast({
+        title: res.msg,
+        icon: 'none',
+      })
+      commissionAccountTypeData.value = { ecn: [], standard: [], cent: [] }
+    }
+  }
+  const getAvailableSpreadsCommission = (loginType) => {
+    if (loginType === '2') return commissionAccountTypeData.value.ecn || []
+    if (loginType === '7')
+      return commissionAccountTypeData.value.standard || []
+    if (loginType === '8') return commissionAccountTypeData.value.cent || []
+    return []
+  }
+  // 佣金调整弹框:根据佣金查看(getLoginPoint)的当前值设置账户类型下拉默认选中
+  const setCommissionDefaultsFromLoginPoint = async (customerId) => {
+    if (!customerId) return
+    try {
+      const res = await ibApi.getLoginPoint({ id: customerId })
+      if (res.code !== Code.StatusOK || !Array.isArray(res.data)) return
+      const list = res.data || []
+      const norm = (v) =>
+        v === 2 || v === '2'
+          ? '2'
+          : v === 7 || v === '7'
+            ? '7'
+            : v === 8 || v === '8'
+              ? '8'
+              : null
+      const byType = { 2: [], 7: [], 8: [] }
+      list.forEach((d) => {
+        const t = norm(d.loginType)
+        if (t && d.groupName) byType[t].push(d.groupName)
+      });
+      ['2', '7', '8'].forEach((loginType) => {
+        const key =
+          loginType === '2' ? 'ecn' : loginType === '7' ? 'standard' : 'cent'
+        const currentGroupName = byType[loginType][0]
+        const options = getAvailableSpreadsCommission(loginType)
+        const idx =
+          currentGroupName == null
+            ? -1
+            : options.findIndex(
+              (item) => (item.groupName || '') === currentGroupName,
+            )
+        const setting = commissionAccountTypeSettings.value[key]
+        if (idx >= 0) {
+          setting.selectedIndex = idx
+          setting.selectedItem = options[idx]
+        } else {
+          setting.selectedIndex = null
+          setting.selectedItem = null
+        }
+      })
+    } catch (e) {
+      console.error('设置佣金调整默认值失败:', e)
+    }
+  }
+
+  watch(() => props.detail, (val) => {
+    if (val) {
+      const { cId, id, comPoint1, hide1 } = val
+      dialogForm.value = {
+        cId, id, comPoint1, hide1,
+      }
+      if (val.ibId) {
+        loadCommissionAccountTypes(val.ibId).then(
+          () => {
+            return setCommissionDefaultsFromLoginPoint(val.id)
+          },
+        )
+      }
+    }
+  })
+
+  const getSpreadLabelCommission = (item) => {
+    return item.groupName || ''
+  }
+
+  const handleCommissionAccountTypeChange = (type, loginType) => {
+    const setting = commissionAccountTypeSettings.value[type]
+    const availableSpreads = getAvailableSpreadsCommission(loginType)
+    if (
+      setting.selectedIndex !== null &&
+      setting.selectedIndex !== undefined
+    ) {
+      setting.selectedItem = availableSpreads[setting.selectedIndex] || null
+    } else {
+      setting.selectedItem = null
+    }
+  }
+
+  const toVerified = () => {
+    // 确认按钮点击事件
+    emit('confirm')
+  }
+
+  const cancel = () => {
+    // 取消按钮点击事件
+    emit('close')
+  }
+
+  const closeDia = () => {
+    emit('close')
+  }
+
+  const confirmDia = async () => {
+    // 确认按钮点击事件
+    const loginConfig = []
+    Object.keys(commissionAccountTypeSettings.value).forEach((key) => {
+      const setting = commissionAccountTypeSettings.value[key]
+      if (setting.selectedItem) {
+        loginConfig.push(setting.selectedItem)
+      }
+    })
+    let res = await ibApi.customCommissionPoint({
+      id: dialogForm.value.id,
+      loginConfig,
+    })
+    if (res.code == Code.StatusOK) {
+      uni.showToast({
+        title: t('Msg.ModifySuccess'),
+      })
+      this.cancel()
+    } else {
+      uni.showToast({
+        title: res.msg,
+        icon: 'none',
+      })
+    }
+    emit('confirm')
+  }
+</script>
+<style lang="scss" scoped>
+  @import "@/uni.scss";
+
+  .dialog-account-adjust-body {
+    padding: 20rpx;
+  }
+
+  .account-adjust-cid-row {
+    display: flex;
+    align-items: center;
+    margin-bottom: 20rpx;
+  }
+
+  .account-adjust-cid-label {
+    color: #606266;
+    margin-right: px2rpx(5);
+  }
+
+  .account-adjust-cid-value {
+    font-weight: bold;
+    color: #303133;
+  }
+
+  .form-section {
+    margin-bottom: 20rpx;
+  }
+
+  .section-title {
+    display: flex;
+    align-items: center;
+    margin-bottom: px2rpx(15);
+    font-weight: bold;
+    font-size: px2rpx(14);
+  }
+
+  .section-title i {
+    margin-right: 10rpx;
+  }
+
+  .account-type-grid {
+  }
+
+  .account-type-card {
+    display: flex;
+    flex-direction: column;
+    margin-bottom: px2rpx(20);
+  }
+
+  .account-type-label {
+    margin-bottom: 10rpx;
+    font-size: 14rpx;
+  }
+
+  .account-select {
+    width: 100%;
+  }
+
+  .dialog-account-adjust-footer {
+    padding: 20rpx;
+  }
+
+  .account-adjust-notes-panel {
+    margin-bottom: 20rpx;
+  }
+
+  .account-adjust-notes-section {
+    background-color: #f5f7fa;
+    padding: 15rpx;
+    border-radius: 8rpx;
+  }
+
+  .account-adjust-notes-title {
+    display: flex;
+    align-items: center;
+    margin-bottom: px2rpx(10);
+    font-weight: bold;
+    font-size: px2rpx(13);
+  }
+
+  .account-adjust-notes-title-icon {
+    margin-right: px2rpx(10);
+  }
+
+  .account-adjust-notes-list {
+    margin-left: px2rpx(20);
+    color: #606266;
+    font-size: px2rpx(13);
+  }
+
+  .account-adjust-notes-list .list {
+    margin-bottom: px2rpx(5);
+    margin-left: px2rpx(10);
+  }
+
+  .account-adjust-footer-buttons {
+    display: flex;
+    justify-content: flex-end;
+    gap: 15rpx;
+  }
+
+  .account-adjust-footer-buttons button {
+    min-width: 120rpx;
+  }
+</style>

+ 14 - 8
pages/ib/customer.vue

@@ -66,7 +66,8 @@
       <!-- 跟单全局设置     -->
       <!-- 跟单全局设置     -->
       <DocumentaryDialog :visible="docVisible" :detail="formInfoRow" @close="closeDoc" @confirm="confirmDoc" />
       <DocumentaryDialog :visible="docVisible" :detail="formInfoRow" @close="closeDoc" @confirm="confirmDoc" />
       <!-- 开户调整     -->
       <!-- 开户调整     -->
-      <PointDialog :visible="pointVisible" @close="closePoint" @confirm="confirmPoint" />
+      <PointDialog :visible="pointVisible" :detail="pointForm" @close="closePoint" @confirm="confirmPoint" />
+      <ApplyIbDialog :visible="applyVisible" :tableData="pointForm" @close="closePoint" @confirm="confirmPoint" />
     </view>
     </view>
   </cwg-page-wrapper>
   </cwg-page-wrapper>
 </template>
 </template>
@@ -82,6 +83,7 @@
   import { ibApi } from '@/service/ib'
   import { ibApi } from '@/service/ib'
   import DocumentaryDialog from '@/pages/ib/components/documentaryDialog.vue'
   import DocumentaryDialog from '@/pages/ib/components/documentaryDialog.vue'
   import PointDialog from '@/pages/ib/components/pointDialog.vue'
   import PointDialog from '@/pages/ib/components/pointDialog.vue'
+  import ApplyIbDialog from '@/pages/ib/components/applyIbDialog.vue'
 
 
   const { Code } = Config
   const { Code } = Config
   const statistics = ref({
   const statistics = ref({
@@ -93,12 +95,14 @@
   const search = ref({
   const search = ref({
     'name': '',
     'name': '',
     'email': '',
     'email': '',
-    'cId': '700101',
+    'cId': '',
     // 1:未实名 2:未入金 3:已入金
     // 1:未实名 2:未入金 3:已入金
     belongsType: null,
     belongsType: null,
   })
   })
 
 
   const formInfoRow = ref({})
   const formInfoRow = ref({})
+  const pointForm = ref({})
+  const applyTable = ref([])
   const docVisible = ref(false)
   const docVisible = ref(false)
   const pointVisible = ref(false)
   const pointVisible = ref(false)
   const applyVisible = ref(false)
   const applyVisible = ref(false)
@@ -220,14 +224,16 @@
       formInfoRow.value = {
       formInfoRow.value = {
         cId, id, permissionDisplay,
         cId, id, permissionDisplay,
       }
       }
+      docVisible.value = true
     } else if (item.type == 'applyIb') {
     } else if (item.type == 'applyIb') {
-      uni.navigateTo({
-        url: '/pages/ib/applyIb/index?cId=' + row.cId,
-      })
+
+      applyVisible.value = true
     } else if (item.type == 'Point') {
     } else if (item.type == 'Point') {
-      uni.navigateTo({
-        url: '/pages/ib/point/index?cId=' + row.cId,
-      })
+      const { cId, id, comPoint1, hide1 } = item.row
+      pointForm.value = {
+        cId, id, comPoint1, hide1,
+      }
+      pointVisible.value = true
     }
     }
   }
   }
 
 

+ 178 - 15
pages/ib/subsList.vue

@@ -1,24 +1,187 @@
 <template>
 <template>
-    <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
-        <cwg-header :title="t('Home.page_ib.item2')" />
+  <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
+    <cwg-header :title="t('Ib.Custom.Manage2')" />
 
 
-        <view class="account-section">
+    <view class="account-content">
+      <view class="search-content">
+        <view class="search-bar">
+          <uni-easyinput v-model="search.ibNo" :placeholder="t('Label.IbAccount')" />
+          <uni-easyinput v-model="search.name" :placeholder="t('Ib.Custom.NameLabel')" />
+          <uni-easyinput v-model="search.cId" placeholder="CID" />
+          <uni-datetime-picker type="daterange" v-model="search.date"
+                               :placeholder="t('placeholder.Start') + ' - ' + t('placeholder.End')" @change="handleDateChange"/>
         </view>
         </view>
-    </cwg-page-wrapper>
+        <view class="search-bar">
+          <button type="primary" class="search-button" @click="addSub">
+            <cwg-icon name="icon_add" :size="18" color="#fff"></cwg-icon>
+            {{t('Ib.Report.Title5')}}
+          </button>
+        </view>
+      </view>
+      <cwg-tabel
+        ref="tableRef"
+        :columns="columns"
+        :mobilePrimaryFields="mobilePrimaryFields"
+        :queryParams="search"
+        :api="listApi"
+        :show-operation="true"
+        :showPagination="true"
+      >
+        <template #action="{ row }">
+          <cwg-dropdown :menu-list="menuList(row)" @menuClick="handleMenuClick">
+            <view class="pc-header-btn">
+              <cwg-icon name="crm-ellipsis" :size="24" />
+            </view>
+          </cwg-dropdown>
+        </template>
+      </cwg-tabel>
+    </view>
+  </cwg-page-wrapper>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
-import { customApi } from '@/service/custom'
-import { financialApi } from '@/service/financial'
-import Config from '@/config/index'
-import AddBankDialog from '@/components/AddBankDialog.vue';
-import PaymentMethodsList from './components/PaymentMethodsList.vue'
-const { t, locale } = useI18n()
-const isZh = computed(() => ['cn', 'zhHant'].includes(locale.value))
+  // 代理管理
+  import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
+  import { onLoad } from '@dcloudio/uni-app'
+  import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
+  import { customApi } from '@/service/custom'
+  import { financialApi } from '@/service/financial'
+  import Config from '@/config/index'
+  import { lang } from '@/composables/config'
+  import { ibApi } from '@/service/ib'
+  import { useFilters } from '@/composables/useFilters'
+
+  const { numberFormat, numberDecimal } = useFilters()
+
+  const search = ref({
+    ibNo: '',
+    name: '',
+    date: '',
+    cId: '',
+    startDate: '',
+    endDate: '',
+  })
+  const { t, locale } = useI18n()
+  // 表格列配置
+  const columns = ref([
+    {
+      prop: 'cId',
+      label: t('Label.CidAccount'),
+      align: 'center',
+    },
+    {
+      prop: 'ibNo',
+      label: t('Label.IbAccount'),
+      align: 'center',
+    },
+    {
+      prop: 'name',
+      label: t('Ib.Custom.NameLabel'),
+      align: 'center',
+    },
+    {
+      prop: 'agentNum',
+      label: t('Ib.Custom.AgentNum'),
+      align: 'center',
+    },
+    {
+      prop: 'customNum',
+      label: t('Ib.Custom.CustomerNum'),
+      align: 'center',
+    },
+    {
+      prop: 'addTime',
+      label: t('Label.ApplyTime'),
+      align: 'center',
+    },
+    {
+      prop: 'lastTime',
+      label: t('Ib.Custom.LastActiveTime'),
+      align: 'center',
+    },
+    {
+      prop: 'action',
+      label: t('Label.Action'),
+      align: 'center',
+      slot: 'action',
+    },
+  ])
+
+  const mobilePrimaryFields = ref([
+    {
+      prop: 'cId',
+      label: t('Label.CidAccount'),
+      align: 'center',
+    },
+    {
+      prop: 'ibNo',
+      label: t('Label.IbAccount'),
+      align: 'center',
+    },
+    {
+      prop: 'name',
+      label: t('Ib.Custom.NameLabel'),
+      align: 'center',
+    },
+    {
+      prop: 'more',
+      type: 'more',
+      width: 20,
+      align: 'right',
+    },
+  ])
+
+
+  const listApi = ref(ibApi.IbSubs)
+  const handleDateChange = (val) => {
+    search.value.startDate = val[0]
+    search.value.endDate = val[1]
+  }
+
+  // 下拉菜单配置
+  const menuList = (row) => {
+    return [
+      {
+        label: t('Ib.Custom.Commit3'),
+        type: 'vietnamDistribution',
+        row,
+        show: true,
+      },
+      {
+        label: t('Ib.Custom.Commit5'),
+        type: 'exclusiveCommission',
+        row,
+        show: row.exclusiveCommissionOptions?.length > 0,
+      },
+    ].filter((item) => item.show)
+  }
+  const handleMenuClick = (item) => {
+    if (item.type == 'vietnamDistribution') {
+      const { cId, id, permissionDisplay } = item.row
+      formInfoRow.value = {
+        cId, id, permissionDisplay,
+      }
+      docVisible.value = true
+    } else if (item.type == 'exclusiveCommission') {
+      const { cId, id, comPoint1, hide1 } = item.row
+      pointForm.value = {
+        cId, id, comPoint1, hide1,
+      }
+      pointVisible.value = true
+    }
+  }
 </script>
 </script>
 <style lang="scss" scoped>
 <style lang="scss" scoped>
-@import "@/uni.scss";
+  @import "@/uni.scss";
+
+  .search-content {
+    display: flex;
+    justify-content: space-between;
+  }
+  .search-button{
+    display: flex;
+    align-items: center;
+    height: px2rpx(36);
+    line-height: px2rpx(36);
+  }
 </style>
 </style>

+ 14 - 1
windows/left-window.vue

@@ -20,7 +20,7 @@
       </view>
       </view>
     </view>
     </view>
     <view class="menu fixed">
     <view class="menu fixed">
-      <view class="menu-item ib-box" @click="setMode('ib')" v-if="mode !== 'ib'">
+      <view class="menu-item ib-box" @click="toIb" v-if="mode !== 'ib'">
         <cwg-icon name="crm-ib" :size="20" color="#6c8595" />
         <cwg-icon name="crm-ib" :size="20" color="#6c8595" />
         <view class="menu-label" v-t="'Home.msg.Ib'" />
         <view class="menu-label" v-t="'Home.msg.Ib'" />
       </view>
       </view>
@@ -32,17 +32,30 @@
         <cwg-icon name="crm-zy" :size="20" color="#6c8595" />
         <cwg-icon name="crm-zy" :size="20" color="#6c8595" />
       </view>
       </view>
     </view>
     </view>
+<!--    ib弹窗-->
+    <IbInfo ref="ibRef"/>
   </view>
   </view>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
+import { ref } from 'vue'
 import { useMenuSplit } from '@/composables/useMenuSplit'
 import { useMenuSplit } from '@/composables/useMenuSplit'
+import IbInfo from '@/components/IbInfo.vue'
 const { menus, setSubmenuRef, setMode, handleClick, handleSubmenuClick, mode } = useMenuSplit()
 const { menus, setSubmenuRef, setMode, handleClick, handleSubmenuClick, mode } = useMenuSplit()
+const ibRef = ref(null)
 // 固定菜单项点击事件
 // 固定菜单项点击事件
 function handleFixedMenuClick() {
 function handleFixedMenuClick() {
   // 这里可以添加固定菜单的点击处理逻辑
   // 这里可以添加固定菜单的点击处理逻辑
   console.log('Fixed menu clicked')
   console.log('Fixed menu clicked')
 }
 }
+const toIb = ()=>{
+  // 判断是否有注册过ib
+  console.log(ibRef.value)
+  if(ibRef.value){
+    ibRef.value.getInfo()
+  }
+  setMode('ib')
+}
 
 
 </script>
 </script>