zhb há 1 mês atrás
pai
commit
a9083f7977

+ 1 - 1
components/cwg-confirm-popup.vue

@@ -6,7 +6,7 @@
     </view>
     <template #footer>
       <button @click="handleCancel">{{ cancelText }}</button>
-      <button type="primary" @click="handleConfirm">{{ confirmText }}</button>
+      <button class="btn btn-secondary btn-shadow waves-effect" @click="handleConfirm">{{ confirmText }}</button>
     </template>
   </cwg-popup>
 </template>

+ 15 - 9
components/cwg-page-wrapper.vue

@@ -42,13 +42,10 @@
           </cwg-match-media>
         </view>
       </view>
-      <cwg-match-media :max-width="991">
-        <view class="chat-icon"
-          :class="{ 'chat-icon-expanded': isChatIconExpanded, 'chat-icon-hidden': type == 'chat' }"
-          @click="handleChatIconClick">
-          <cwg-icon name="chat" color="#fff" />
-        </view>
-      </cwg-match-media>
+      <view class="chat-icon" :class="{ 'chat-icon-expanded': isChatIconExpanded, 'chat-icon-hidden': type == 'chat' }"
+        @click="handleChatIconClick">
+        <cwg-icon name="chat" color="#fff" />
+      </view>
       <view :style="{ height: isTabBarPage ? '60px' : '0px' }" />
     </view>
     <cwg-match-media :min-width="991" v-if="!isLoginPage">
@@ -73,7 +70,10 @@ import { useI18n } from 'vue-i18n'
 import Config from '@/config/index'
 import { customApi } from '@/service/custom'
 import tool from "@/global/tool"
-
+import LiveChatService from '@/utils/liveChat.js'
+import { useWindowWidth } from '@/composables/useWindowWidth'
+const windowWidth = useWindowWidth(300)
+const isMobile = computed(() => windowWidth.value <= 991)
 const { t, locale } = useI18n()
 const globalStore = useGlobalStore()
 const router = useRouter()
@@ -132,7 +132,13 @@ const handleChatIconClick = () => {
     isChatIconExpanded.value = true
     return
   }
-  router.push('/pages/common/chat')
+  if (isMobile.value) {
+    router.push('/pages/common/chat')
+  } else {
+    if (LiveChatService) {
+      LiveChatService.showChat()
+    }
+  }
   setTimeout(() => {
     isChatIconExpanded.value = false
   }, 300)

+ 40 - 16
pages/customer/components/AccountCard.vue

@@ -2,7 +2,8 @@
     <view class="col-lg-4 col-md-6">
         <view class="card">
             <view class="card-header d-flex align-items-center justify-content-between border-0 pb-2 p-3">
-                <text class="badge bg-success-subtle text-success">正常</text>
+                <text v-if="!isDel" class="badge bg-success-subtle text-success">正常</text>
+                <text v-if="isDel" class="badge bg-danger-subtle text-danger">已删除</text>
                 <view class="clearfix">
                     <view class="btn-group">
                         <cwg-dropdown ref="dropdownRef" @open="onOpen" @close="onClose" :menu-list="customMenuList"
@@ -66,7 +67,7 @@
                                 </view>
                             </view>
                         </view>
-                        <view class="d-flex flex-wrap gap-2" v-if="!isDemo">
+                        <view class="d-flex flex-wrap gap-2" v-if="isReal">
                             <button v-for="btn in actionButtons" :key="btn.key" type="submit" value="Submit"
                                 class="btn btn-dark btn-sm waves-effect waves-light"
                                 :class="{ 'disabled': btn.disabled.value }" @click="handleAction(btn.action)">
@@ -126,6 +127,9 @@ export interface Account {
     closeFunctions?: string;    // 关闭的功能
 }
 const isDemo = computed(() => accountInfo.value.listType == 'demo')
+const isDel = computed(() => accountInfo.value.listType == 'del')
+const isReal = computed(() => accountInfo.value.listType == 'real')
+
 const closeFunctionOpen = (code) => {
     const closeFunctions = accountInfo.value.closeFunctions || ""
     if (closeFunctions == null || closeFunctions === "") {
@@ -179,6 +183,10 @@ const handleAction = (type: string) => {
             pwdType.value = 2
             terminalChangePasswordDialogVisible.value = true
             break;
+        case 'changePassword3':
+            pwdType.value = 3
+            terminalChangePasswordDialogVisible.value = true
+            break;
         case 'info':
             terminalInfoDialogVisible.value = true
             break;
@@ -205,18 +213,31 @@ const handleAction = (type: string) => {
     }
 };
 
-const customMenuList = computed(() => !isDemo.value ? [
-    { label: '开始交易', type: 'trade' },
-    { label: t('Ib.Report.Tit1'), type: 'history' },
-    { label: t('Ib.Report.Tit4'), type: 'position' },
-    { label: t('Home.page_customer.item4'), type: 'payment-history' },
-    { label: t('Documentary.TundManagement.item29'), type: 'info' },
-    { label: t('vu.item3'), type: 'changePassword1' },
-    { label: t('vu.item4'), type: 'changePassword2' }
-] : [
-    { label: '开始交易', type: 'trade' },
-    { label: t('Documentary.TundManagement.item29'), type: 'info' }
-])
+const customMenuList = computed(() => {
+    switch (accountInfo.value.listType) {
+        case 'real':
+            return [
+                { label: '开始交易', type: 'trade' },
+                { label: t('Ib.Report.Tit1'), type: 'history' },
+                { label: t('Ib.Report.Tit4'), type: 'position' },
+                { label: t('Home.page_customer.item4'), type: 'payment-history' },
+                { label: t('Documentary.TundManagement.item29'), type: 'info' },
+                { label: t('vu.item3'), type: 'changePassword1' },
+                { label: t('vu.item4'), type: 'changePassword2' },
+                { label: t('Custom.Settings.TitReset'), type: 'changePassword3' }
+            ]
+        case 'demo':
+            return [
+                { label: '开始交易', type: 'trade' },
+                { label: t('Documentary.TundManagement.item29'), type: 'info' }
+            ]
+
+        case 'del':
+            return [
+                { label: t('Documentary.TundManagement.item29'), type: 'info' }
+            ]
+    }
+})
 const handleCustomClick = (item, index) => {
     handleAction(item.value.type)
 }
@@ -251,10 +272,13 @@ const toTransfer = () => {
     router.push(`/pages/customer/transfer?login=${accountInfo.value.login}&type=${accountInfo.value.type}&balance=${accountInfo.value.balance}&currency=${accountInfo.value.currency}`)
 }
 const balanceInteger = computed(() => {
-    return Math.floor(accountInfo.value.balance).toString();
+    return accountInfo.value.balance ? Math.floor(accountInfo.value.balance).toString() : '0';
 });
 const balanceDecimal = computed(() => {
-    const parts = accountInfo.value.balance.toFixed(2).split('.');
+    const parts = accountInfo.value?.balance?.toFixed(2)?.split || [];
+    console.log(accountInfo.value?.balance, 1212);
+    if (!accountInfo.value?.balance) return '.00'
+
     return parts[1] ? '.' + parts[1] : '.00';
 });
 onMounted(() => {

+ 22 - 9
pages/customer/components/AccountList.vue

@@ -22,8 +22,9 @@
                         <view class="card-header">
                             <view class="nav nav-underline card-header-tabs">
                                 <view class="nav-item cwg-cursor" v-for="(tab, index) in tabs" :key="index"
-                                    @click="cativeIndex = index">
-                                    <view class="nav-link" :class="{ 'active': index === cativeIndex }">{{ tab.text }}
+                                    @click="cativeIndex = tab.value">
+                                    <view class="nav-link" :class="{ 'active': tab.value === cativeIndex }">{{ tab.text
+                                    }}
                                     </view>
                                 </view>
                             </view>
@@ -112,11 +113,12 @@ const typeMap = computed(() => ({
     7: t('AccountType.StandardAccount'),
     8: t('AccountType.CentAccount')
 }));
-const cativeIndex = ref(0)
+const cativeIndex = ref('real')
 const isGridLayout = ref(true)
 const tabs = computed(() => ([
     { value: 'real', text: t('vu.item1') },
-    { value: 'demo', text: t('vu.item2') }
+    { value: 'demo', text: t('vu.item2') },
+    { value: 'del', text: t('Tips.DeleteAccount') },
 ]))
 
 const toggleLayout = () => {
@@ -225,7 +227,7 @@ async function getCustomLoginInfo() {
                 res.data.customInfo.status == 2 &&
                 res.data.customInfo.applyRealStatus == 2
             ) {
-                router.push(`/pages/customer/account-select?server=${cativeIndex.value == 1 ? 'demo' : 'real'}`)
+                router.push(`/pages/customer/account-select?server=${cativeIndex.value}`)
             } else {
                 dialogCheck.value = true;
             }
@@ -244,7 +246,18 @@ const AccountList = ref([])
 const getAccountList = async () => {
     AccountList.value = []
     loading.value = true
-    const api = cativeIndex.value == 1 ? customApi.demoList : customApi.AccountAllList
+    var api
+    switch (cativeIndex.value) {
+        case 'real':
+            api = customApi.AccountAllList
+            break;
+        case 'demo':
+            api = customApi.demoList
+            break;
+        case 'del':
+            api = customApi.deleteAccountList
+            break;
+    }
     const res = await api({
         page: {
             current: 1,
@@ -277,12 +290,12 @@ const accounts = computed(() => {
         const currency = acc.currency || 'USD';
         const floating = acc.floating ?? 0;
         let labels = [t('vu.item1'), 'MT4', 'Standard'];
-        labels[0] = cativeIndex.value == 1 ? t('vu.item2') : t('vu.item1');
+        labels[0] = cativeIndex.value == 'demo' ? t('vu.item2') : t('vu.item1');
         labels[1] = acc.platform || 'MT4';
         labels[2] = typeMap.value[acc.type];
         let nickname = typeMap.value[acc.type];
         let fwq
-        if (cativeIndex.value != 1) {
+        if (cativeIndex.value != 'demo') {
             fwq = acc.platform == 'MT4' ? 'CWGMarketsLtd-Live' : 'CWGMarketsSVG-Live';
         } else {
             fwq = acc.platform == 'MT4' ? 'CWGMarketsLtd-Demo' : 'CWGMarketsSVG-Demo';
@@ -305,7 +318,7 @@ const accounts = computed(() => {
             platform: acc.platform || 'MT4',
             server: acc.groupCode || '',
             login: acc.login.toString(),
-            listType: cativeIndex.value == 1 ? 'demo' : 'real'
+            listType: cativeIndex.value
         };
     })
 })

+ 118 - 53
pages/customer/components/TerminalChangePasswordDialog.vue

@@ -1,32 +1,38 @@
 <template>
-    <cwg-popup :title="props.pwdType == 1 ? t('vu.item3') : t('vu.item4')" :visible="props.visible" :showFooters="false"
+    <cwg-popup :title="pwdTitle" :visible="props.visible" :showFooters="false"
         @update:visible="$emit('update:visible', $event)">
         <view class="popup-content">
             <text class="account-number">{{ accountLabel }} {{ account.login }}</text>
 
-            <uni-forms :model="passwordInfo" labelWidth="200" label-position="top" class="crm-form">
-                <uni-forms-item
-                    :label="props.pwdType == 1 ? t('Custom.Settings.LoginPwdOld') : t('Custom.Settings.InvestorPwdOld')">
-                    <uni-easyinput type="password" :clearable="false" v-model="passwordInfo.oldPassword"
-                        :placeholder="props.pwdType == 1 ? t('Custom.Settings.LoginPwdOld') : t('Custom.Settings.InvestorPwdOld')" />
-                </uni-forms-item>
-                <uni-forms-item :label="t('Custom.Settings.NewPwd')">
-                    <uni-easyinput type="password" :clearable="false" v-model="passwordInfo.newPassword"
-                        :placeholder="t('Custom.Settings.NewPwd')" />
-                </uni-forms-item>
-            </uni-forms>
-
-            <view class="notice-list">
-                <view v-for="(item, index) in noticeItems" :key="index"
-                    :class="['notice-item', item.valid ? 'isOK' : '']">
-                    {{ item.label }}
+            <template v-if="props.pwdType != 3">
+                <uni-forms :model="passwordInfo" labelWidth="200" label-position="top" class="crm-form">
+                    <uni-forms-item
+                        :label="props.pwdType == 1 ? t('Custom.Settings.LoginPwdOld') : t('Custom.Settings.InvestorPwdOld')">
+                        <uni-easyinput type="password" :clearable="false" v-model="passwordInfo.oldPassword"
+                            :placeholder="props.pwdType == 1 ? t('Custom.Settings.LoginPwdOld') : t('Custom.Settings.InvestorPwdOld')" />
+                    </uni-forms-item>
+                    <uni-forms-item :label="t('Custom.Settings.NewPwd')">
+                        <uni-easyinput type="password" :clearable="false" v-model="passwordInfo.newPassword"
+                            :placeholder="t('Custom.Settings.NewPwd')" />
+                    </uni-forms-item>
+                </uni-forms>
+
+                <view class="notice-list">
+                    <view v-for="(item, index) in noticeItems" :key="index"
+                        :class="['notice-item', item.valid ? 'isOK' : '']">
+                        {{ item.label }}
+                    </view>
                 </view>
-            </view>
+            </template>
 
             <view class="save-btn">
-                <view class="btn primary" @click="save" v-t="'Btn.Save'" />
+                <view v-if="props.pwdType != 3" class="btn btn-secondary btn-shadow waves-effect" @click="save"
+                    v-t="'Btn.Save'" />
+                <view v-else class="btn btn-secondary btn-shadow waves-effect" @click="resetPwd"
+                    v-t="'Btn.ResetPassword'" />
             </view>
         </view>
+        <cwg-confirm-popup />
     </cwg-popup>
 </template>
 
@@ -35,7 +41,8 @@ import { ref, computed, watch } from 'vue'
 import { customApi } from '@/service/custom';
 import { useI18n } from 'vue-i18n'
 import { showToast } from "@/utils/toast";
-
+import { useConfirm } from '@/hooks/useConfirm'
+const confirm = useConfirm()
 const { t } = useI18n()
 
 const props = defineProps({
@@ -52,7 +59,16 @@ const passwordInfo = ref({
     oldPassword: '',
     newPassword: ''
 });
-
+const pwdTitle = computed(() => {
+    switch (props.pwdType) {
+        case 1:
+            return t('vu.item3')
+        case 2:
+            return t('vu.item4')
+        case 3:
+            return t('Custom.Settings.TitReset')
+    }
+})
 const rule1 = computed(() => {
     if (!passwordInfo.value.newPassword) return false;
     return /^.{8,16}$/.test(passwordInfo.value.newPassword);
@@ -111,16 +127,65 @@ const save = async () => {
         }
 
         if (res.code == 200) {
-            showToast(t('Msg.Success'));
+            await confirm({
+                title: t('Msg.SystemPrompt'),
+                content: t('ApplicationDialog.Des1'),
+                confirmText: t('Btn.Confirm'),
+                cancelText: t('Btn.Cancel')
+            })
             emit('update:visible', false);
             passwordInfo.value = {
                 oldPassword: '',
                 newPassword: ''
             }
             emit('save');
+        } else {
+            await confirm({
+                title: t('Msg.SystemPrompt'),
+                content: res.msg,
+                confirmText: t('Btn.Confirm'),
+                cancelText: t('Btn.Cancel')
+            })
+            emit('update:visible', false);
+        }
+    } catch (error) {
+        showToast(error.msg);
+        emit('update:visible', false);
+    } finally {
+        flag.value = false;
+    }
+}
+// 重置交易账号密码
+const resetPwd = async () => {
+    try {
+        if (flag.value) {
+            return
+        } else {
+            flag.value = true;
+        }
 
+        let res = await customApi.ResetDealPasswordEmail({
+            login: props.account.login
+        });
+        if (res.code == 200) {
+            flag.value = false;
+            await confirm({
+                title: t('Msg.SystemPrompt'),
+                content: t('ApplicationDialog.Des1'),
+                confirmText: t('Btn.Confirm'),
+                cancelText: t('Btn.Cancel')
+            })
+            emit('update:visible', false);
         } else {
-            showToast(res.msg);
+            flag.value = false;
+            await confirm({
+                title: t('Msg.SystemPrompt'),
+                content: res.msg,
+                confirmText: t('Btn.Confirm'),
+                cancelText: t('Btn.Cancel')
+            })
+            // showToast(res.msg);
+            emit('update:visible', false);
         }
     } catch (error) {
         showToast(error.msg);
@@ -202,35 +267,35 @@ watch(() => props.visible, (newVal) => {
     justify-content: flex-end;
     margin-top: px2rpx(20);
 
-    .btn {
-        border: 1px solid rgba(108, 133, 149, 0);
-        border-radius: px2rpx(8);
-        padding: px2rpx(8) px2rpx(20);
-        font-size: px2rpx(14);
-        color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;
-        display: inline-flex;
-        align-items: center;
-        justify-content: center;
-        gap: px2rpx(8);
-        cursor: pointer;
-        transition: all 0.2s;
-        height: px2rpx(40);
-        box-sizing: border-box;
-        background-color: rgba(108, 133, 149, 0.08);
-
-        &.primary {
-            background-color: #cf1322;
-            ;
-            color: var(--bs-emphasis-color);
-
-            &:hover {
-                background-color: var(--color-navy-600);
-            }
-
-            &[disabled] {
-                cursor: not-allowed;
-            }
-        }
-    }
+    // .btn {
+    //     border: 1px solid rgba(108, 133, 149, 0);
+    //     border-radius: px2rpx(8);
+    //     padding: px2rpx(8) px2rpx(20);
+    //     font-size: px2rpx(14);
+    //     color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;
+    //     display: inline-flex;
+    //     align-items: center;
+    //     justify-content: center;
+    //     gap: px2rpx(8);
+    //     cursor: pointer;
+    //     transition: all 0.2s;
+    //     height: px2rpx(40);
+    //     box-sizing: border-box;
+    //     background-color: rgba(108, 133, 149, 0.08);
+
+    //     &.primary {
+    //         background-color: #cf1322;
+    //         ;
+    //         color: var(--bs-emphasis-color);
+
+    //         &:hover {
+    //             background-color: var(--color-navy-600);
+    //         }
+
+    //         &[disabled] {
+    //             cursor: not-allowed;
+    //         }
+    //     }
+    // }
 }
 </style>

+ 2 - 0
pages/customer/recording-history.vue

@@ -44,6 +44,7 @@ const search = ref({
 const getInfoAgentTransfer = computed(() => userInfo.value.customInfo?.agentTransfer)
 const typeMap = computed(() => ([
     { value: 1, text: t('Custom.Recording.NewAccount') },
+    { value: 7, text: t('Custom.NewAccount.BtnDome') },
     // { value: 2, text: t('Custom.Recording.LeverageApply') },
     { value: 3, text: t('Custom.Recording.InternalTransfer') },
     // { value: 4, text: t('Custom.Recording.ActivitiesApply') },
@@ -66,6 +67,7 @@ const reasons = ref({})
 const getColumnsByType = (type: number) => {
     switch (type) {
         case 1: // 开户记录
+        case 7: // 开户记录
             return [
                 {
                     prop: 'platform',

+ 1 - 1
pages/ib/transfer.vue

@@ -137,7 +137,7 @@
 
                                                 <view type="submit" value="Submit"
                                                     class="btn btn-danger waves-effect waves-light"><i
-                                                        class="fi fi-rs-check"></i> Submit
+                                                        class="fi fi-rs-check"></i> {{ t('Btn.Submit') }}
                                                 </view>
                                             </view>
                                         </uni-forms>

+ 1 - 1
static/scss/global/global.scss

@@ -621,7 +621,7 @@ body {
 .uni-input-input {
     --bs-bg-opacity: 1;
     background-color: transparent;
-    color: var(--bs-body-color) !important;
+    color: var(--bs-emphasis-color) !important;
 }
 
 .uni-top-window {

+ 1 - 1
uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue

@@ -579,7 +579,7 @@ $uni-border-1: #dcdfe6 !default;
 }
 
 .uni-easyinput__placeholder-class {
-	color: var(--bs-body-color)!important;
+	color: var(--bs-emphasis-color) !important;
 	font-size: 1rem;
 	// font-weight: 200;
 }