Pārlūkot izejas kodu

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

zhb 1 mēnesi atpakaļ
vecāks
revīzija
a8107c4b8c

+ 2 - 2
components/cwg-popup.vue

@@ -213,7 +213,7 @@ defineExpose({
     .dialog-title {
         font-size: px2rpx(20);
         font-weight: 600;
-        color: var(--bs-heading-color);
+        color: var(--bs-emphasis-color);
     }
 
     .dialog-close {
@@ -223,7 +223,7 @@ defineExpose({
         align-items: center;
         justify-content: center;
         font-size: px2rpx(32);
-        color: rgba(255, 255, 255, 0.9);
+        color: var(--bs-emphasis-color);
         cursor: pointer;
         transition: all 0.3s;
         border-radius: 50%;

+ 11 - 1
components/cwg-tabel.vue

@@ -845,7 +845,7 @@ defineExpose({
             transition: all 0.3s;
             background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
             border-bottom: 1px solid #ebeef5 !important;
-            color: #606266;
+            color: rgb(var(--bs-white-rgb))!important;
 
             .header-content {
                 display: flex;
@@ -876,6 +876,16 @@ defineExpose({
             transition: background-color 0.2s ease;
             border-bottom: 1px solid #ebeef5 !important;
 
+            // 奇数行背景颜色
+            &:nth-child(odd) {
+                background-color: #fafafa;
+            }
+
+            // 偶数行背景颜色
+            &:nth-child(even) {
+                background-color: #fff;
+            }
+
             &:hover {
                 background-color: #f5f7fa !important;
             }

+ 596 - 577
pages/ib/components/applyIbDialog.vue

@@ -4,57 +4,62 @@
       <uni-forms ref="formRef" labelWidth="200">
         <uni-forms-item v-if="isFormApplyIb" :label="t('Ib.Custom.Manage3') + ':'" prop="customerId">
           <cwg-combox v-model:value="addAgentForm.customerId" :options="customerList"
-            :placeholder="t('placeholder.choose')" filterable @change="changeCustomer" style="max-width: 280px" />
+                      :placeholder="t('placeholder.choose')" filterable @change="changeCustomer"
+                      style="max-width: 280px" />
         </uni-forms-item>
         <uni-loading v-if="laoding" />
         <view v-else class="commission-table-container" v-if="addAgentForm.customerId">
           <table class="commission-table">
             <thead>
-              <tr>
-                <th style="width: 80px;">{{ t('Ib.Custom.Status') }}</th>
-                <th style="width: 100px;"></th>
-                <th style="width: 100px;"></th>
-                <th style="width: 80px;">METAL</th>
-                <th>FX</th>
-                <th>ENERGY</th>
-                <th>CFD</th>
-                <th>INDEX</th>
-                <!--                <th>Crypto</th>-->
-              </tr>
+            <tr>
+              <th style="width: 80px;">{{ t('Ib.Custom.Status') }}</th>
+              <th style="width: 100px;"></th>
+              <th style="width: 100px;"></th>
+              <th style="width: 80px;">METAL</th>
+              <th>FX</th>
+              <th>ENERGY</th>
+              <th>CFD</th>
+              <th>INDEX</th>
+              <th>Crypto</th>
+            </tr>
             </thead>
             <tbody v-for="(group, gIndex) in commissionTemplateTableData" :key="gIndex">
-              <tr v-for="(item, iIndex) in group.items" :key="iIndex">
-                <td v-if="iIndex === 0" :rowspan="group.items.length" class="center-td">
-                  <switch :checked="group.isOpen" @change="(e) => onGroupSwitchChange(e, group)" color="#2b5aed"
-                    style="transform:scale(0.8)" />
-                </td>
-                <td v-if="iIndex === 0" :rowspan="group.items.length" class="center-td group-name-td">
-                  {{ group.accountGroup }}
-                </td>
-                <td class="center-td type-td">
-                  {{ item.type }}
-                </td>
-                <td style="width: 80px;">
-                  <cwg-combox v-model:value="item.energy" :options="formatOptions(item.energyOptions)"
-                    :placeholder="t('placeholder.choose')" />
-                </td>
-                <td>
-                  <cwg-combox v-model:value="item.forex" :options="formatOptions(item.forexOptions)"
-                    :placeholder="t('placeholder.choose')" />
-                </td>
-                <td>
-                  <cwg-combox v-model:value="item.energy2" :options="formatOptions(item.energy2Options)"
-                    :placeholder="t('placeholder.choose')" />
-                </td>
-                <td>
-                  <cwg-combox v-model:value="item.index" :options="formatOptions(item.indexOptions)"
-                    :placeholder="t('placeholder.choose')" />
-                </td>
-                <td>
-                  <cwg-combox v-model:value="item.metal" :options="formatOptions(item.metalOptions)"
-                    :placeholder="t('placeholder.choose')" />
-                </td>
-              </tr>
+            <tr v-for="(item, iIndex) in group.items" :key="iIndex">
+              <td v-if="iIndex === 0" :rowspan="group.items.length" class="center-td">
+                <switch :checked="group.isOpen" @change="(e) => onGroupSwitchChange(e, group)" color="#2b5aed"
+                        style="transform:scale(0.8)" />
+              </td>
+              <td v-if="iIndex === 0" :rowspan="group.items.length" class="center-td group-name-td">
+                {{ group.accountGroup }}
+              </td>
+              <td class="center-td type-td">
+                {{ item.type }}
+              </td>
+              <td style="width: 80px;">
+                <cwg-combox v-model:value="item.energy" :options="formatOptions(item.energyOptions)"
+                            :placeholder="t('placeholder.choose')" />
+              </td>
+              <td>
+                <cwg-combox v-model:value="item.forex" :options="formatOptions(item.forexOptions)"
+                            :placeholder="t('placeholder.choose')" />
+              </td>
+              <td>
+                <cwg-combox v-model:value="item.energy2" :options="formatOptions(item.energy2Options)"
+                            :placeholder="t('placeholder.choose')" />
+              </td>
+              <td>
+                <cwg-combox v-model:value="item.index" :options="formatOptions(item.indexOptions)"
+                            :placeholder="t('placeholder.choose')" />
+              </td>
+              <td>
+                <cwg-combox v-model:value="item.metal" :options="formatOptions(item.metalOptions)"
+                            :placeholder="t('placeholder.choose')" />
+              </td>
+              <td>
+                <cwg-combox v-model:value="item.crypto" :options="formatOptions(item.cryptoOptions)"
+                            :placeholder="t('placeholder.choose')" />
+              </td>
+            </tr>
             </tbody>
           </table>
         </view>
@@ -65,597 +70,611 @@
 </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({
-  paramsType: {
-    type: String,
-    default: '',
-  },
-  title: {
-    type: String,
-    default: 'Ib.Report.Title5',
-  },
-  // 是否显示弹窗
-  visible: {
-    type: Boolean,
-    default: false,
-  },
-  // 详情tableData
-  detail: { type: Array, default: () => ({}) },
-  // 是否需要选择客户
-  isFormApplyIb: {
-    type: Boolean,
-    default: false,
-  },
-})
-const { Code, Host80 } = Config
-const { t } = useI18n()
-const formRef = ref(null)
-const addAgentForm = ref({
-  customerId: '',
-})
-const customerList = ref([])
-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 commissionTemplateTableData = ref<any[]>([])
-const emit = defineEmits(['close', 'confirm'])
-const laoding = ref(false)
-onMounted(() => {
-  // initCommissionTemplateData(29634)
-})
-
-watch(() => props.visible, async (val) => {
-  if (val) {
-    laoding.value = true
-    if (props.isFormApplyIb) {
-      await loadCustomerList()
-    }
-    if (props.detail.id) {
-      let params = {
-        customId: props.detail.id,
+  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({
+    paramsType: {
+      type: String,
+      default: '',
+    },
+    title: {
+      type: String,
+      default: 'Ib.Report.Title5',
+    },
+    // 是否显示弹窗
+    visible: {
+      type: Boolean,
+      default: false,
+    },
+    // 详情tableData
+    detail: { type: Object, default: () => ({}) },
+    // 是否需要选择客户
+    isFormApplyIb: {
+      type: Boolean,
+      default: false,
+    },
+  })
+  const { Code, Host80 } = Config
+  const { t } = useI18n()
+  const formRef = ref(null)
+  const addAgentForm = ref({
+    customerId: '',
+  })
+  const customerList = ref([])
+  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 commissionTemplateTableData = ref<any[]>([])
+  const emit = defineEmits(['close', 'confirm'])
+  const laoding = ref(false)
+  onMounted(() => {
+    // initCommissionTemplateData(29634)
+  })
+
+  watch(() => props.visible, async (val) => {
+    if (val) {
+      laoding.value = true
+      if (props.isFormApplyIb) {
+        await loadCustomerList()
       }
-      addAgentForm.value = {
-        customerId: props.detail.id,
-      };
-      if (props.paramsType == 'vietnam') {
-        params = {
-          agentId: props.detail.id,
+      if (props.detail.id) {
+        let params = {
+          customId: props.detail.id,
+        }
+        addAgentForm.value = {
+          customerId: props.detail.id,
         }
+        if (props.paramsType == 'vietnam') {
+          params = {
+            agentId: props.detail.id,
+          }
+        }
+        await initCommissionTemplateData(params)
       }
-      await initCommissionTemplateData(params)
+      laoding.value = false
     }
-    laoding.value = false
-  }
-})
-
-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 generateOptions = (currentValue) => {
-  const options = []
-  for (let i = 0; i <= currentValue; i++) {
-    options.push(i)
-  }
-  return options
-}
-
-// 格式化 options 为 combox 期望的格式
-const formatOptions = (opts) => {
-  if (!opts || !Array.isArray(opts)) return []
-  return opts.map(val => ({ text: String(val), value: val }))
-}
-
-const toggleGroup = (group) => {
-  group.isOpen = !group.isOpen
-}
-
-const onGroupSwitchChange = (e, group) => {
-  group.isOpen = e.detail.value
-}
-
-const initCommissionTemplateData = async (params) => {
-  try {
-    const res = await ibApi.getVietnamPoints(params)
-
-    if (res.code == Code.StatusOK && res.data && Array.isArray(res.data)) {
-      const groupedData: Record<string, any[]> = {}
-
-      res.data.forEach((group: any) => {
-        const accountGroup = group.groupCategoryName || '--'
-        const isOpen = group.valid !== undefined ? group.valid : 1
-
-        if (!groupedData[accountGroup]) {
-          groupedData[accountGroup] = []
-        }
+  })
 
-        const rebates = Array.isArray(group.rebates) ? group.rebates : []
-        const superRebates = Array.isArray(group.superRebates) ? group.superRebates : []
-        if (superRebates.length > 0) {
-          const rebateRow: any = {
-            accountGroup,
-            groupCategoryId: group.groupCategoryId,
-            dataType: 'rebates',
-            type: group.rebateTypeName || 'Point',
-            isOpen,
-            forex: 0,
-            index: 0,
-            metal: 0,
-            energy: 0,
-            energy2: 0,
-            energy2Max: 0,
-            forex1: 0,
-            index1: 0,
-            metal1: 0,
-            energy1: 0,
+  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 generateOptions = (currentValue) => {
+    const options = []
+    for (let i = 0; i <= currentValue; i++) {
+      options.push(i)
+    }
+    return options
+  }
+
+  // 格式化 options 为 combox 期望的格式
+  const formatOptions = (opts) => {
+    if (!opts || !Array.isArray(opts)) return []
+    return opts.map(val => ({ text: String(val), value: val }))
+  }
+
+  const toggleGroup = (group) => {
+    group.isOpen = !group.isOpen
+  }
+
+  const onGroupSwitchChange = (e, group) => {
+    group.isOpen = e.detail.value
+  }
+
+  const initCommissionTemplateData = async (params) => {
+    try {
+      const res = await ibApi.getVietnamPoints(params)
+
+      if (res.code == Code.StatusOK && res.data && Array.isArray(res.data)) {
+        const groupedData: Record<string, any[]> = {}
+
+        res.data.forEach((group: any) => {
+          const accountGroup = group.groupCategoryName || '--'
+          const isOpen = group.valid !== undefined ? group.valid : 1
+
+          if (!groupedData[accountGroup]) {
+            groupedData[accountGroup] = []
           }
 
-          rebates.forEach((rebate: any) => {
-            if (rebate.symbolCategory === 1) rebateRow.forex = rebate.point || 0
-            else if (rebate.symbolCategory === 2) rebateRow.index = rebate.point || 0
-            else if (rebate.symbolCategory === 3) rebateRow.metal = rebate.point || 0
-            else if (rebate.symbolCategory === 4) rebateRow.energy = rebate.point || 0
-            else if (rebate.symbolCategory === 5) rebateRow.energy2 = rebate.point || 0
-          })
-
-          superRebates.forEach((rebate: any) => {
-            if (rebate.symbolCategory === 1) rebateRow.forex1 = rebate.point || 0
-            else if (rebate.symbolCategory === 2) rebateRow.index1 = rebate.point || 0
-            else if (rebate.symbolCategory === 3) rebateRow.metal1 = rebate.point || 0
-            else if (rebate.symbolCategory === 4) rebateRow.energy1 = rebate.point || 0
-            else if (rebate.symbolCategory === 5) rebateRow.energy2Max = rebate.point || 0
-          })
-
-          rebateRow.forexOptions = generateOptions(rebateRow.forex1)
-          rebateRow.indexOptions = generateOptions(rebateRow.index1)
-          rebateRow.metalOptions = generateOptions(rebateRow.metal1)
-          rebateRow.energyOptions = generateOptions(rebateRow.energy1)
-          rebateRow.energy2Options = generateOptions(rebateRow.energy2Max)
-
-          groupedData[accountGroup].push(rebateRow)
-        }
+          const rebates = Array.isArray(group.rebates) ? group.rebates : []
+          const superRebates = Array.isArray(group.superRebates) ? group.superRebates : []
+          if (superRebates.length > 0) {
+            const rebateRow: any = {
+              accountGroup,
+              groupCategoryId: group.groupCategoryId,
+              dataType: 'rebates',
+              type: group.rebateTypeName || 'Point',
+              isOpen,
+              forex: 0,
+              index: 0,
+              metal: 0,
+              energy: 0,
+              energy2: 0,
+              energy2Max: 0,
+              forex1: 0,
+              index1: 0,
+              metal1: 0,
+              energy1: 0,
+              crypto: 0,
+              crypto1: 0,
+            }
+
+            rebates.forEach((rebate: any) => {
+              if (rebate.symbolCategory === 1) rebateRow.forex = rebate.point || 0
+              else if (rebate.symbolCategory === 2) rebateRow.index = rebate.point || 0
+              else if (rebate.symbolCategory === 3) rebateRow.metal = rebate.point || 0
+              else if (rebate.symbolCategory === 4) rebateRow.energy = rebate.point || 0
+              else if (rebate.symbolCategory === 5) rebateRow.energy2 = rebate.point || 0
+              else if (rebate.symbolCategory === 6) rebateRow.crypto = rebate.point || 0
+            })
+
+            superRebates.forEach((rebate: any) => {
+              if (rebate.symbolCategory === 1) rebateRow.forex1 = rebate.point || 0
+              else if (rebate.symbolCategory === 2) rebateRow.index1 = rebate.point || 0
+              else if (rebate.symbolCategory === 3) rebateRow.metal1 = rebate.point || 0
+              else if (rebate.symbolCategory === 4) rebateRow.energy1 = rebate.point || 0
+              else if (rebate.symbolCategory === 5) rebateRow.energy2Max = rebate.point || 0
+              else if (rebate.symbolCategory === 6) rebateRow.crypto1 = rebate.point || 0
+            })
+
+            rebateRow.forexOptions = generateOptions(rebateRow.forex1)
+            rebateRow.indexOptions = generateOptions(rebateRow.index1)
+            rebateRow.metalOptions = generateOptions(rebateRow.metal1)
+            rebateRow.energyOptions = generateOptions(rebateRow.energy1)
+            rebateRow.energy2Options = generateOptions(rebateRow.energy2Max)
+            rebateRow.cryptoOptions = generateOptions(rebateRow.crypto1)
+
+            groupedData[accountGroup].push(rebateRow)
+          }
 
-        const commissions = Array.isArray(group.commissions) ? group.commissions : []
-        const superCommissions = Array.isArray(group.superCommissions) ? group.superCommissions : []
-        if (superCommissions.length > 0) {
-          const commissionRow: any = {
+          const commissions = Array.isArray(group.commissions) ? group.commissions : []
+          const superCommissions = Array.isArray(group.superCommissions) ? group.superCommissions : []
+          if (superCommissions.length > 0) {
+            const commissionRow: any = {
+              accountGroup,
+              groupCategoryId: group.groupCategoryId,
+              dataType: 'commissions',
+              type: group.commissionTypeName || 'Commission',
+              isOpen,
+              forex: 0,
+              index: 0,
+              metal: 0,
+              energy: 0,
+              energy2: 0,
+              energy2Max: 0,
+              forex1: 0,
+              index1: 0,
+              metal1: 0,
+              energy1: 0,
+              crypto: 0,
+              crypto1: 0,
+            }
+
+            commissions.forEach((comm: any) => {
+              if (comm.symbolCategory === 1) commissionRow.forex = comm.point || 0
+              else if (comm.symbolCategory === 2) commissionRow.index = comm.point || 0
+              else if (comm.symbolCategory === 3) commissionRow.metal = comm.point || 0
+              else if (comm.symbolCategory === 4) commissionRow.energy = comm.point || 0
+              else if (comm.symbolCategory === 5) commissionRow.energy2 = comm.point || 0
+              else if (comm.symbolCategory === 6) commissionRow.crypto = comm.point || 0
+            })
+
+            superCommissions.forEach((comm: any) => {
+              if (comm.symbolCategory === 1) commissionRow.forex1 = comm.point || 0
+              else if (comm.symbolCategory === 2) commissionRow.index1 = comm.point || 0
+              else if (comm.symbolCategory === 3) commissionRow.metal1 = comm.point || 0
+              else if (comm.symbolCategory === 4) commissionRow.energy1 = comm.point || 0
+              else if (comm.symbolCategory === 5) commissionRow.energy2Max = comm.point || 0
+              else if (comm.symbolCategory === 6) commissionRow.crypto1 = comm.point || 0
+            })
+
+            commissionRow.forexOptions = generateOptions(commissionRow.forex1)
+            commissionRow.indexOptions = generateOptions(commissionRow.index1)
+            commissionRow.metalOptions = generateOptions(commissionRow.metal1)
+            commissionRow.energyOptions = generateOptions(commissionRow.energy1)
+            commissionRow.energy2Options = generateOptions(commissionRow.energy2Max)
+            commissionRow.cryptoOptions = generateOptions(commissionRow.crypto1)
+
+            groupedData[accountGroup].push(commissionRow)
+          }
+        })
+
+        // 将按 accountGroup 聚合后的对象转换为包含 accountGroup 和 items 数组的结构
+        const finalData = Object.keys(groupedData).map((accountGroup) => {
+          return {
             accountGroup,
-            groupCategoryId: group.groupCategoryId,
-            dataType: 'commissions',
-            type: group.commissionTypeName || 'Commission',
-            isOpen,
-            forex: 0,
-            index: 0,
-            metal: 0,
-            energy: 0,
-            energy2: 0,
-            energy2Max: 0,
-            forex1: 0,
-            index1: 0,
-            metal1: 0,
-            energy1: 0,
+            // 默认不展开
+            isOpen: groupedData[accountGroup].some(item => item.isOpen == 1) || false,
+            items: groupedData[accountGroup],
           }
+        }).filter(item => item.items.length > 0)
 
-          commissions.forEach((comm: any) => {
-            if (comm.symbolCategory === 1) commissionRow.forex = comm.point || 0
-            else if (comm.symbolCategory === 2) commissionRow.index = comm.point || 0
-            else if (comm.symbolCategory === 3) commissionRow.metal = comm.point || 0
-            else if (comm.symbolCategory === 4) commissionRow.energy = comm.point || 0
-            else if (comm.symbolCategory === 5) commissionRow.energy2 = comm.point || 0
-          })
-
-          superCommissions.forEach((comm: any) => {
-            if (comm.symbolCategory === 1) commissionRow.forex1 = comm.point || 0
-            else if (comm.symbolCategory === 2) commissionRow.index1 = comm.point || 0
-            else if (comm.symbolCategory === 3) commissionRow.metal1 = comm.point || 0
-            else if (comm.symbolCategory === 4) commissionRow.energy1 = comm.point || 0
-            else if (comm.symbolCategory === 5) commissionRow.energy2Max = comm.point || 0
-          })
-
-          commissionRow.forexOptions = generateOptions(commissionRow.forex1)
-          commissionRow.indexOptions = generateOptions(commissionRow.index1)
-          commissionRow.metalOptions = generateOptions(commissionRow.metal1)
-          commissionRow.energyOptions = generateOptions(commissionRow.energy1)
-          commissionRow.energy2Options = generateOptions(commissionRow.energy2Max)
-
-          groupedData[accountGroup].push(commissionRow)
-        }
+        console.log('tableData', finalData)
+        commissionTemplateTableData.value = finalData
+        return
+      }
+
+      commissionTemplateTableData.value = []
+      uni.showToast({
+        title: res.msg || t('Ib.Custom.GetDataFailed'),
+        icon: 'none',
       })
+    } catch (error) {
+      commissionTemplateTableData.value = []
+      uni.showToast({ title: t('Ib.Custom.GetDataFailed'), icon: 'none' })
+    }
+  }
 
-      // 将按 accountGroup 聚合后的对象转换为包含 accountGroup 和 items 数组的结构
-      const finalData = Object.keys(groupedData).map((accountGroup) => {
-        return {
-          accountGroup,
-          // 默认不展开
-          isOpen: groupedData[accountGroup].some(item => item.isOpen == 1) || false,
-          items: groupedData[accountGroup],
-        }
-      }).filter(item => item.items.length > 0)
 
-      console.log('tableData', finalData)
-      commissionTemplateTableData.value = finalData
-      return
+  // 加载客户列表
+  const loadCustomerList = async () => {
+    try {
+      let res = await ibApi.customerSubsList({
+        ibStatus: 1,
+      })
+      if (res.code == Code.StatusOK) {
+        customerList.value = res.data.map(item => ({
+          text: `${item.name || ''}-${item.cId}`,
+          value: item.id || '',
+          cId: item.cId, // 保存 cId 供后续提交使用
+        })) || []
+      } else {
+        uni.showToast({ title: res.msg, icon: 'none' })
+        customerList.value = []
+      }
+    } catch (error) {
+      console.error('加载客户列表失败:', error)
+      customerList.value = []
+    } finally {
     }
-
-    commissionTemplateTableData.value = []
-    uni.showToast({
-      title: res.msg || t('Ib.Custom.GetDataFailed'),
-      icon: 'none',
-    })
-  } catch (error) {
-    commissionTemplateTableData.value = []
-    uni.showToast({ title: t('Ib.Custom.GetDataFailed'), icon: 'none' })
   }
-}
-
 
-// 加载客户列表
-const loadCustomerList = async () => {
-  try {
-    let res = await ibApi.customerSubsList({
-      ibStatus: 1,
-    })
-    if (res.code == Code.StatusOK) {
-      customerList.value = res.data.map(item => ({
-        text: `${item.name || ''}-${item.cId}`,
-        value: item.id || '',
-        cId: item.cId, // 保存 cId 供后续提交使用
-      })) || []
+  // 客户选择改变时触发
+  const changeCustomer = async (val) => {
+    if (val) {
+      laoding.value = true
+      await initCommissionTemplateData({ customId: val })
+      laoding.value = false
     } else {
-      uni.showToast({ title: res.msg, icon: 'none' })
-      customerList.value = []
+      commissionTemplateTableData.value = []
     }
-  } catch (error) {
-    console.error('加载客户列表失败:', error)
-    customerList.value = []
-  } finally {
-  }
-}
-
-// 客户选择改变时触发
-const changeCustomer = async (val) => {
-  if (val) {
-    laoding.value = true
-    await initCommissionTemplateData({ customId: val })
-    laoding.value = false
-  } else {
-    commissionTemplateTableData.value = []
   }
-}
-
-// 构建佣金模板points数据
-const buildCommissionTemplatePoints = () => {
-  const points: any[] = []
-  const groupedData: Record<string, any> = {}
-
-  // 由于现在的 commissionTemplateTableData 是 { accountGroup, isOpen, items } 嵌套结构,需要双层遍历提取
-  commissionTemplateTableData.value.forEach((groupObj) => {
-    groupObj.items.forEach((row: any) => {
-      const groupId = row.groupCategoryId
-      if (!groupedData[groupId]) {
-        groupedData[groupId] = {
-          groupCategoryId: groupId,
-          commissions: [],
-          rebates: [],
-          valid: groupObj.isOpen ? 1 : 0,
+
+  // 构建佣金模板points数据
+  const buildCommissionTemplatePoints = () => {
+    const points: any[] = []
+    const groupedData: Record<string, any> = {}
+
+    // 由于现在的 commissionTemplateTableData 是 { accountGroup, isOpen, items } 嵌套结构,需要双层遍历提取
+    commissionTemplateTableData.value.forEach((groupObj) => {
+      groupObj.items.forEach((row: any) => {
+        const groupId = row.groupCategoryId
+        if (!groupedData[groupId]) {
+          groupedData[groupId] = {
+            groupCategoryId: groupId,
+            commissions: [],
+            rebates: [],
+            valid: groupObj.isOpen ? 1 : 0,
+          }
         }
-      }
 
-      // 根据dataType添加到对应的数组
-      const pointList = row.dataType === 'commissions'
-        ? groupedData[groupId].commissions
-        : groupedData[groupId].rebates
+        // 根据dataType添加到对应的数组
+        const pointList = row.dataType === 'commissions'
+          ? groupedData[groupId].commissions
+          : groupedData[groupId].rebates
 
-      // 添加各个symbolCategory的数据
-      if (row.forex !== undefined && row.forex !== null) {
-        pointList.push({ symbolCategory: 1, point: row.forex }) // FX
-      }
-      if (row.index !== undefined && row.index !== null) {
-        pointList.push({ symbolCategory: 2, point: row.index }) // CFD
-      }
-      if (row.metal !== undefined && row.metal !== null) {
-        pointList.push({ symbolCategory: 3, point: row.metal }) // INDEX
-      }
-      if (row.energy !== undefined && row.energy !== null) {
-        pointList.push({ symbolCategory: 4, point: row.energy }) // METAL
-      }
-      if (row.energy2 !== undefined && row.energy2 !== null) {
-        pointList.push({ symbolCategory: 5, point: row.energy2 }) // Energy
-      }
-      // if (row.energy2 !== undefined && row.energy2 !== null) {
-      //   pointList.push({ symbolCategory: 5, point: row.energy2 }) // Energy
-      // }
+        // 添加各个symbolCategory的数据
+        if (row.forex !== undefined && row.forex !== null) {
+          pointList.push({ symbolCategory: 1, point: row.forex }) // FX
+        }
+        if (row.index !== undefined && row.index !== null) {
+          pointList.push({ symbolCategory: 2, point: row.index }) // CFD
+        }
+        if (row.metal !== undefined && row.metal !== null) {
+          pointList.push({ symbolCategory: 3, point: row.metal }) // INDEX
+        }
+        if (row.energy !== undefined && row.energy !== null) {
+          pointList.push({ symbolCategory: 4, point: row.energy }) // METAL
+        }
+        if (row.energy2 !== undefined && row.energy2 !== null) {
+          pointList.push({ symbolCategory: 5, point: row.energy2 }) // Energy
+        }
+        if (row.crypto !== undefined && row.crypto !== null) {
+          pointList.push({ symbolCategory: 6, point: row.crypto }) // Crypto
+        }
+        // if (row.energy2 !== undefined && row.energy2 !== null) {
+        //   pointList.push({ symbolCategory: 5, point: row.energy2 }) // Energy
+        // }
+      })
     })
-  })
 
-  // 转换为数组格式
-  Object.keys(groupedData).forEach((groupId) => {
-    const group = groupedData[groupId]
-    if (group.commissions.length > 0 || group.rebates.length > 0) {
-      points.push({
-        groupCategoryId: group.groupCategoryId,
-        commissions: group.commissions.length > 0 ? group.commissions : undefined,
-        rebates: group.rebates.length > 0 ? group.rebates : undefined,
-        valid: group.valid,
-      })
-    }
-  })
+    // 转换为数组格式
+    Object.keys(groupedData).forEach((groupId) => {
+      const group = groupedData[groupId]
+      if (group.commissions.length > 0 || group.rebates.length > 0) {
+        points.push({
+          groupCategoryId: group.groupCategoryId,
+          commissions: group.commissions.length > 0 ? group.commissions : undefined,
+          rebates: group.rebates.length > 0 ? group.rebates : undefined,
+          valid: group.valid,
+        })
+      }
+    })
 
-  return points
-}
+    return points
+  }
 
-const toVerified = () => {
-  // 确认按钮点击事件
-  emit('confirm')
-}
+  const toVerified = () => {
+    // 确认按钮点击事件
+    emit('confirm')
+  }
 
-const closeDia = () => {
-  addAgentForm.value = {
-    customerId: ''
+  const closeDia = () => {
+    addAgentForm.value = {
+      customerId: '',
+    }
+    commissionTemplateTableData.value = []
+    emit('close')
   }
-  commissionTemplateTableData.value = []
-  emit('close')
-}
 
-const confirmDia = async () => {
-  //  越南分配也用,看怎么调整提交接口
-  let customId, cId
+  const confirmDia = async () => {
+    //  越南分配也用,看怎么调整提交接口
+    let customId, cId
 
-  // 越南佣金分配不用判断customId
-  if (props.paramsType !== 'vietnam') {
-    if (!props.isFormApplyIb) {
-      if (!props.detail.id) {
-        uni.showToast({ title: t('Ib.Custom.CustomerNotExist'), icon: 'none' })
-        return
+    // 越南佣金分配不用判断customId
+    if (props.paramsType !== 'vietnam') {
+      if (!props.isFormApplyIb) {
+        if (!props.detail.id) {
+          uni.showToast({ title: t('Ib.Custom.CustomerNotExist'), icon: 'none' })
+          return
+        }
+        const applyIbRowData: any = props.detail || {}
+        customId = applyIbRowData.id
+        cId = applyIbRowData.cId
+      } else {
+        // 从其他地方打开,需要选择客户
+        if (!addAgentForm.value.customerId) {
+          uni.showToast({ title: t('placeholder.choose'), icon: 'none' })
+          return
+        }
+
+        // 从客户列表中找到选中的客户对象
+        const selectedCustomer: any = customerList.value.find(
+          (item: any) => item.value === addAgentForm.value.customerId,
+        )
+        if (!selectedCustomer) {
+          uni.showToast({ title: t('Ib.Custom.CustomerNotFound'), icon: 'none' })
+          return
+        }
+        customId = selectedCustomer.value
+        cId = selectedCustomer.cId
       }
-      const applyIbRowData: any = props.detail || {}
-      customId = applyIbRowData.id
-      cId = applyIbRowData.cId
-    } else {
-      // 从其他地方打开,需要选择客户
-      if (!addAgentForm.value.customerId) {
-        uni.showToast({ title: t('placeholder.choose'), icon: 'none' })
-        return
+    }
+
+    try {
+      // 构建points数据
+      const points = buildCommissionTemplatePoints()
+      // console.log(points)
+      // 调用新增代理申请接口
+      let params = {
+        customId: customId,
+        cId: cId,
+        points: points,
+      }
+      if (props.paramsType === 'vietnam') {
+        params = {
+          agentId: props.detail.id,
+          points: points,
+        }
       }
 
-      // 从客户列表中找到选中的客户对象
-      const selectedCustomer: any = customerList.value.find(
-        (item: any) => item.value === addAgentForm.value.customerId,
-      )
-      if (!selectedCustomer) {
-        uni.showToast({ title: t('Ib.Custom.CustomerNotFound'), icon: 'none' })
-        return
+      // 越南分配和新增代理
+      const res = props.paramsType === 'vietnam' ? await ibApi.saveVietnamPoints(params) : await ibApi.agentApplyAddPoint(params)
+
+      if (res.code == Code.StatusOK) {
+        uni.showToast({
+          title: res.msg || props.paramsType ? t('Ib.Custom.SaveSuccess') : t('Ib.Custom.SubmitSuccess'),
+          icon: 'success',
+        })
+        closeDia()
+        emit('confirm')
+
+      } else {
+        uni.showToast({
+          title: res.msg || props.paramsType ? t('Ib.Custom.SaveFailed') : t('Ib.Custom.SubmitFailed'),
+          icon: 'none',
+        })
       }
-      customId = selectedCustomer.value
-      cId = selectedCustomer.cId
+    } catch (error) {
+      console.error('新增代理失败或保存越南分配数据失败:', error)
+      uni.showToast({ title: props.paramsType ? t('Ib.Custom.SaveFailed') : t('Ib.Custom.SubmitFailed'), icon: 'none' })
     }
   }
+</script>
+<style lang="scss" scoped>
+  @import "@/uni.scss";
 
-  try {
-    // 构建points数据
-    const points = buildCommissionTemplatePoints()
-    // console.log(points)
-    // 调用新增代理申请接口
-    let params = {
-      customId: customId,
-      cId: cId,
-      points: points,
+  .commission-table-container {
+    margin-top: px2rpx(10);
+    padding-bottom: px2rpx(150);
+    /* 预留底部空间,防止最下面的下拉框被截断或遮挡 */
+    width: 100%;
+    overflow-x: auto;
+  }
+
+  .commission-table {
+    width: 100%;
+    border-collapse: collapse;
+    border-spacing: 0;
+    font-size: px2rpx(14);
+    color: var(--bs-emphasis-color);
+    border: 1px solid #ebeef5;
+
+    thead {
+      background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
     }
-    if (props.paramsType === 'vietnam') {
-      params = {
-        agentId: props.detail.id,
-        points: points,
-      }
+
+    th {
+      padding: px2rpx(12) px2rpx(10);
+      text-align: center;
+      font-weight: bold;
+      color: var(--bs-emphasis-color);
+      border: 1px solid #ebeef5;
+      font-size: px2rpx(13);
+      white-space: nowrap;
     }
 
-    // 越南分配和新增代理
-    const res = props.paramsType === 'vietnam' ? await ibApi.saveVietnamPoints(params) : await ibApi.agentApplyAddPoint(params)
+    td {
+      padding: px2rpx(8) px2rpx(10);
+      border: 1px solid #ebeef5;
+      vertical-align: middle;
+    }
 
-    if (res.code == Code.StatusOK) {
-      uni.showToast({
-        title: res.msg || props.paramsType ? t('Ib.Custom.SaveSuccess') : t('Ib.Custom.SubmitSuccess'),
-        icon: 'success',
-      })
-      closeDia()
-      emit('confirm')
+    .center-td {
+      text-align: center;
+    }
 
-    } else {
-      uni.showToast({
-        title: res.msg || props.paramsType ? t('Ib.Custom.SaveFailed') : t('Ib.Custom.SubmitFailed'),
-        icon: 'none',
-      })
+    .group-name-td {
+      color: var(--bs-emphasis-color);
+      font-weight: 500;
+    }
+
+    .type-td {
+      color: #606266;
+    }
+
+    :deep(.cwg-combox) {
+      width: 100%;
+      min-width: px2rpx(80);
     }
-  } catch (error) {
-    console.error('新增代理失败或保存越南分配数据失败:', error)
-    uni.showToast({ title: props.paramsType ? t('Ib.Custom.SaveFailed') : t('Ib.Custom.SubmitFailed'), icon: 'none' })
   }
-}
-</script>
-<style lang="scss" scoped>
-@import "@/uni.scss";
-
-.commission-table-container {
-  margin-top: px2rpx(10);
-  padding-bottom: px2rpx(150);
-  /* 预留底部空间,防止最下面的下拉框被截断或遮挡 */
-  width: 100%;
-  overflow-x: auto;
-}
-
-.commission-table {
-  width: 100%;
-  border-collapse: collapse;
-  border-spacing: 0;
-  font-size: px2rpx(14);
-  color: #606266;
-  border: 1px solid #ebeef5;
-
-  thead {
+
+  .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: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
+    padding: 15rpx;
+    border-radius: 8rpx;
   }
 
-  th {
-    padding: px2rpx(12) px2rpx(10);
-    text-align: center;
+  .account-adjust-notes-title {
+    display: flex;
+    align-items: center;
+    margin-bottom: px2rpx(10);
     font-weight: bold;
-    color: #909399;
-    border: 1px solid #ebeef5;
     font-size: px2rpx(13);
-    white-space: nowrap;
   }
 
-  td {
-    padding: px2rpx(8) px2rpx(10);
-    border: 1px solid #ebeef5;
-    vertical-align: middle;
+  .account-adjust-notes-title-icon {
+    margin-right: px2rpx(10);
   }
 
-  .center-td {
-    text-align: center;
+  .account-adjust-notes-list {
+    margin-left: px2rpx(20);
+    color: #606266;
+    font-size: px2rpx(13);
   }
 
-  .group-name-td {
-    color: #303133;
-    font-weight: 500;
+  .account-adjust-notes-list .list {
+    margin-bottom: px2rpx(5);
+    margin-left: px2rpx(10);
   }
 
-  .type-td {
-    color: #606266;
+  .account-adjust-footer-buttons {
+    display: flex;
+    justify-content: flex-end;
+    gap: 15rpx;
   }
 
-  :deep(.cwg-combox) {
-    width: 100%;
-    min-width: px2rpx(80);
-  }
-}
-
-.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: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
-  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;
-}
+  .account-adjust-footer-buttons button {
+    min-width: 120rpx;
+  }
 </style>

+ 5 - 7
pages/login/index.vue

@@ -1105,7 +1105,7 @@ button {
   margin: px2rpx(32) 0;
   font-size: px2rpx(24);
   font-weight: bolder;
-  color: #e4e4e4;
+  color: var(--bs-emphasis-color);
   text-align: center;
 
   i {
@@ -1116,7 +1116,7 @@ button {
     font-size: px2rpx(34);
     line-height: 1.5;
     font-weight: bold;
-    color: #000000;
+    color: var(--bs-emphasis-color);
   }
 
   .tit2 {
@@ -1201,9 +1201,7 @@ button {
   display: flex;
   align-items: center;
   justify-content: center;
-  //gap: 5px;
-  //padding-bottom: 10px;
-  border-bottom: 1px solid #e4e4e4;
+  border-bottom: 1px solid var(--bs-border-color);
 }
 
 .tab-item {
@@ -1213,9 +1211,9 @@ button {
   padding-left: 0;
   padding-bottom: 8px;
   text-align: center;
-  border-bottom: 0.1rem solid transparent;
+  border-bottom: 2px solid transparent;
   font-weight: 500;
-  color: var(--bs-heading-color);
+  color: var(--bs-emphasis-color);
   cursor: pointer;
   transition: all 0.3s ease;
 

+ 54 - 119
static/scss/global/global.scss

@@ -143,127 +143,62 @@
 
 
     // 新的
-    --bs-blue: #0d6efd;
-    --bs-indigo: #6610f2;
-    --bs-purple: #6f42c1;
-    --bs-pink: #d63384;
-    --bs-red: #dc3545;
-    --bs-orange: #fd7e14;
-    --bs-yellow: #ffc107;
-    --bs-green: #198754;
-    --bs-teal: #20c997;
-    --bs-cyan: #0dcaf0;
-    --bs-black: #000;
-    --bs-white: #ffffff;
-    --bs-gray: #6c757d;
-    --bs-gray-dark: #343a40;
-    --bs-gray-100: #f8f9fa;
-    --bs-gray-200: #e9ecef;
-    --bs-gray-300: #dee2e6;
-    --bs-gray-400: #ced4da;
-    --bs-gray-500: #adb5bd;
-    --bs-gray-600: #6c757d;
-    --bs-gray-700: #495057;
-    --bs-gray-800: #343a40;
-    --bs-gray-900: #212529;
-    --bs-secondary: #316AFF;
-    --bs-secondary: #FF8110;
-    --bs-success: #22B07E;
-    --bs-info: #02B4FA;
-    --bs-warning: #FDBB1F;
-    --bs-danger: #FF401C;
-    --bs-light: #ECF2FD;
-    --bs-dark: #0C243C;
-    --bs-white: #ffffff;
-    --bs-gray: #97A1C0;
-    --bs-secondary-rgb: 49, 106, 255;
-    --bs-secondary-rgb: 255, 129, 16;
-    --bs-success-rgb: 34, 176, 126;
-    --bs-info-rgb: 2, 180, 250;
-    --bs-warning-rgb: 253, 187, 31;
+    color-scheme: dark;
+    --bs-body-color: #8c96a9;
+    --bs-body-color-rgb: 140, 150, 169;
+    --bs-body-bg: #282b44;
+    --bs-body: #282b44;
+    --bs-body-bg-rgb: 40, 43, 68;
+    --bs-emphasis-color: #ffffff;
+    --bs-emphasis-color-rgb: 255, 255, 255;
+    --bs-secondary-color: rgba(140, 150, 169, 0.75);
+    --bs-secondary-color-rgb: 140, 150, 169;
+    --bs-secondary-bg: #26283e;
+    --bs-secondary-bg-rgb: 38, 40, 62;
+    --bs-tertiary-color: rgba(140, 150, 169, 0.5);
+    --bs-tertiary-color-rgb: 140, 150, 169;
+    --bs-tertiary-bg: #26283e;
+    --bs-tertiary-bg-rgb: 38, 40, 62;
+    --bs-secondary-text-emphasis: #83a6ff;
+    --bs-secondary-text-emphasis: #ffb370;
+    --bs-success-text-emphasis: #7ad0b2;
+    --bs-info-text-emphasis: #67d2fc;
+    --bs-warning-text-emphasis: #fed679;
+    --bs-danger-text-emphasis: #ff8c77;
+    --bs-light-text-emphasis: #888bb2;
+    --bs-dark-text-emphasis: #999999;
+    --bs-secondary-bg-subtle: #0a1533;
+    --bs-secondary-bg-subtle: #331a03;
+    --bs-success-bg-subtle: #072319;
+    --bs-info-bg-subtle: #002432;
+    --bs-warning-bg-subtle: #332506;
+    --bs-danger-bg-subtle: #330d06;
+    --bs-light-bg-subtle: #1a1c31;
+    --bs-dark-bg-subtle: #10101d;
+    --bs-secondary-border-subtle: #1d4099;
+    --bs-secondary-border-subtle: #994d0a;
+    --bs-success-border-subtle: #146a4c;
+    --bs-info-border-subtle: #016c96;
+    --bs-warning-border-subtle: #987013;
+    --bs-danger-border-subtle: #992611;
+    --bs-light-border-subtle: #484c83;
+    --bs-dark-border-subtle: #494949;
+    --bs-heading-color: #fff;
+    --bs-link-color: #83a6ff;
+    --bs-link-hover-color: #9cb8ff;
+    --bs-link-color-rgb: 131, 166, 255;
+    --bs-link-hover-color-rgb: 156, 184, 255;
+    --bs-code-color: #e685b5;
+    --bs-highlight-color: #8c96a9;
+    --bs-highlight-bg: #664d03;
+    --bs-border-color: #3a3b4d;
+    --bs-border-color-translucent: rgba(255, 255, 255, 0.15);
+    --bs-form-valid-color: #75b798;
+    --bs-form-valid-border-color: #75b798;
+    --bs-form-invalid-color: #ea868f;
+    --bs-form-invalid-border-color: #ea868f;
     --bs-danger-rgb: 255, 64, 28;
-    --bs-light-rgb: 236, 242, 253;
-    --bs-dark-rgb: 12, 36, 60;
-    --bs-white-rgb: 255, 255, 255;
-    --bs-gray-rgb: 151, 161, 192;
-    --bs-secondary-text-emphasis: #142a66;
-    --bs-secondary-text-emphasis: #663406;
-    --bs-success-text-emphasis: #0e4632;
-    --bs-info-text-emphasis: #014864;
-    --bs-warning-text-emphasis: #654b0c;
-    --bs-danger-text-emphasis: #661a0b;
-    --bs-light-text-emphasis: #495057;
-    --bs-dark-text-emphasis: #495057;
-    --bs-secondary-bg-subtle: #eaf0ff;
-    --bs-secondary-bg-subtle: #fff2e7;
-    --bs-success-bg-subtle: #e9f7f2;
-    --bs-info-bg-subtle: #e6f8ff;
-    --bs-warning-bg-subtle: #fff8e9;
-    --bs-danger-bg-subtle: #ffece8;
-    --bs-light-bg-subtle: #fcfcfd;
-    --bs-dark-bg-subtle: #ced4da;
-    --bs-secondary-border-subtle: #ccdaff;
-    --bs-secondary-border-subtle: #ffe0c3;
-    --bs-success-border-subtle: #c8ebdf;
-    --bs-info-border-subtle: #c0ecfe;
-    --bs-warning-border-subtle: #ffeec7;
-    --bs-danger-border-subtle: #ffcfc6;
-    --bs-light-border-subtle: #e9ecef;
-    --bs-dark-border-subtle: #adb5bd;
     --bs-white-rgb: 255, 255, 255;
-    --bs-black-rgb: 0, 0, 0;
-    --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
-    --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
-    --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
-    --bs-body-font-family: "Plus Jakarta Sans", sans-serif;
-    --bs-body-font-size: 0.875rem;
-    --bs-body-font-weight: 500;
-    --bs-body-line-height: 1.6;
-    --bs-body-color: #97A1C0;
-    --bs-body-color-rgb: 151, 161, 192;
-    --bs-body-bg: #fff;
-    --bs-body-bg-rgb: 255, 255, 255;
-    --bs-emphasis-color: #000;
-    --bs-emphasis-color-rgb: 0, 0, 0;
-    --bs-secondary-color: rgba(151, 161, 192, 0.75);
-    --bs-secondary-color-rgb: 151, 161, 192;
-    --bs-secondary-bg: #f9f9f9;
-    --bs-secondary-bg-rgb: 249, 249, 249;
-    --bs-tertiary-color: rgba(151, 161, 192, 0.5);
-    --bs-tertiary-color-rgb: 151, 161, 192;
-    --bs-tertiary-bg: #f8f9fa;
-    --bs-tertiary-bg-rgb: 248, 249, 250;
-    --bs-heading-color: #0C243C;
-    --bs-link-color: #316AFF;
-    --bs-link-color-rgb: 49, 106, 255;
-    --bs-link-decoration: none;
-    --bs-link-hover-color: #2755cc;
-    --bs-link-hover-color-rgb: 39, 85, 204;
-    --bs-code-color: #d63384;
-    --bs-highlight-color: #97A1C0;
-    --bs-highlight-bg: #fff3cd;
-    --bs-border-width: 1px;
-    --bs-border-style: solid;
-    --bs-border-color: #E8EBF1;
-    --bs-border-color-translucent: rgba(0, 0, 0, 0.1);
-    --bs-border-radius: 0.375rem;
-    --bs-border-radius-sm: 0.25rem;
-    --bs-border-radius-lg: 0.625rem;
-    --bs-border-radius-xl: 1rem;
-    --bs-border-radius-xxl: 2rem;
-    --bs-border-radius-2xl: var(--bs-border-radius-xxl);
-    --bs-border-radius-pill: 50rem;
-    --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
-    --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
-    --bs-box-shadow-lg: 0 0.26rem 1.126rem 0 rgba(45, 42, 60, 0.15);
-    --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
-    --bs-focus-ring-width: 0.1rem;
-    --bs-focus-ring-opacity: 0.25;
-    --bs-focus-ring-color: rgba(49, 106, 255, 0.25);
-    --bs-form-valid-color: #22B07E;
-    --bs-form-valid-border-color: #22B07E;
-    --bs-form-invalid-color: #FF401C;
-    --bs-form-invalid-border-color: #FF401C;
 }
 
 .dark {