Files
HTFX-CRM-APP/pages/capital/transfer/index.vue
2025-07-07 15:55:44 +08:00

456 lines
15 KiB
Vue

<template>
<view>
<NavBar />
<view class="container">
<view class="title">
<PageTitle :title="$t('home.transfer')" />
</view>
<uni-forms ref="transferForm" :modelValue="transferFormData" :rules="transferFormRules">
<uni-forms-item name="mt4_login_out">
<text class="uni-subtitle">{{ $t('form.mtAccount.labelOut') }}</text>
<uni-data-select
:placeholder="$t('form.pleaseSelect')"
:emptyTips="$t('common.empty')"
:localdata="mtLoginOptions"
v-model="transferFormData.mt4_login_out"
@change="mtLoginOutChange"
></uni-data-select>
</uni-forms-item>
<view class="availableMoneyOut">
{{ $t('mtTransfer.transferableAmount') }}
<text class="value">${{ availableMoneyOut ?? 0 }}</text>
</view>
<uni-forms-item name="transfer_type">
<text class="uni-subtitle">{{ $t('form.transType.label') }}</text>
<uni-data-select
:placeholder="$t('form.pleaseSelect')"
:emptyTips="$t('form.transType.required')"
:localdata="transTypeOptions"
v-model="transferFormData.transfer_type"
@change="transTypeChange"
></uni-data-select>
</uni-forms-item>
<uni-forms-item name="mt4_server_in" v-if="showTransferOut">
<text class="uni-subtitle">{{ $t('form.mtServer.label') }}</text>
<uni-data-select
:placeholder="$t('form.pleaseSelect')"
:emptyTips="$t('common.empty')"
:localdata="mtServerOptions"
v-model="transferFormData.mt4_server_in"
:clear="false"
></uni-data-select>
</uni-forms-item>
<uni-forms-item name="mt4_login_in" v-if="showTransferOut">
<text class="uni-subtitle">{{ $t('form.mtAccount.labelIn') }}</text>
<uni-easyinput type="number" primaryColor="#29BBE4" v-model="transferFormData.mt4_login_in"></uni-easyinput>
</uni-forms-item>
<uni-forms-item name="mt4_login_name" v-if="showTransferOut" >
<text class="uni-subtitle">{{ $t('form.mtAccountName.label') }}</text>
<uni-easyinput type="text" :placeholder="$t('form.mtAccountName.placeholder')" primaryColor="#29BBE4" v-model="transferFormData.mt4_login_name"></uni-easyinput>
</uni-forms-item>
<uni-forms-item name="mt4_login_in" v-if="showTransferOwn">
<text class="uni-subtitle">{{ $t('form.mtAccount.labelIn') }}</text>
<uni-data-select
:placeholder="$t('form.pleaseSelect')"
:emptyTips="$t('common.empty')"
:localdata="mtLoginInOptions"
v-model="transferFormData.mt4_login_in"
@change="mtLoginInChange"
></uni-data-select>
</uni-forms-item>
<uni-forms-item name="usd_amount">
<text class="uni-subtitle">{{ $t('form.amount.label') }}</text>
<uni-easyinput type="digit" primaryColor="#29BBE4" v-model="transferFormData.usd_amount" @input="handleAmountInput"></uni-easyinput>
<view :class="['minAmount', amountAvailable ? '' : 'unavailable']">{{ unavailableAmountTip }}</view>
</uni-forms-item>
<uni-popup ref="alertDialog" :isMaskClick="false">
<view class="detailModal">
<uni-icons type="closeempty" size="17" class="closeIcon" @click="closeDetailDialog"></uni-icons>
<view class="detailContent">
<view class="modalTitle">{{ $t('mtTransfer.transferConfirmation') }}</view>
<view class="titleWrapper">
<view class="loginsWrapper">
<view class="loginWrapper">
<text class="mtLoginOut">{{ selectedMtLoginOut.mt4_login }}</text>
<text>{{ $t('mtTransfer.account') }}</text>
</view>
<view class="transferTo">{{ $t('mtTransfer.transferTo') }}</view>
<view class="loginWrapper">
<text class="mtLoginIn">{{ transferFormData.mt4_login_in }}</text>
<text>{{ $t('mtTransfer.account') }}</text>
</view>
</view>
<view class="divider"></view>
<view class="amount">$ {{ this.transferFormData?.usd_amount }}</view>
</view>
<uni-forms-item name="safe_pass">
<text class="uni-subtitle">{{ $t('form.CRMPassword.label') }}</text>
<uni-easyinput type="password" trim="all" primaryColor="#29BBE4" v-model="transferFormData.safe_pass"></uni-easyinput>
</uni-forms-item>
<button class="primaryButton" :disabled="submitBtnLoading" @click="handleSaveTransfer">
<image v-show="submitBtnLoading" src="/static/loadingCircle.svg" mode="aspectFit" style="width: 16px; height: 16px"></image>
{{ $t('form.submit') }}
</button>
</view>
</view>
</uni-popup>
</uni-forms>
<button class="primaryButton" type="button" :disabled="nextBtnLoading" @click="showDetailDialog">
<image v-show="nextBtnLoading" src="/static/loadingCircle.svg" mode="aspectFit" style="width: 16px; height: 16px"></image>
{{ $t('form.next') }}
</button>
</view>
</view>
</template>
<script>
import { getMTAccounts2 } from '@/services/home/home.ts';
import { getExchangeRate, getGoldRange } from '@/services/capital/deposit.ts';
import { saveTransfer,getIfOTParams } from '@/services/capital/transfer.ts';
import { getBankList } from '@/services/user.ts';
import { getMtServers, getDictByCode } from '@/services/common.ts';
import { UserLanguage } from '@/utils/const';
export default {
name: '',
data() {
return {
paramsMtLogin: undefined,
showTransferOwn: false,
showTransferOut: false,
ioPowerMap: {},
mtServerOptions: [],
mtLoginOptions: [],
mtLoginInOptions: [],
transTypeOptions: [],
mtlogins: {},
selectedMtLoginIn: null,
selectedMtLoginOut: null,
bankOptions: [],
banks: {},
selectedBank: null,
currencyOptions: [],
goldRange: null,
amountAvailable: true,
unavailableAmountTip: '',
availableMoneyOut: 0,
exchangeRate: undefined,
rateSign: undefined,
currency_amount: undefined,
nextBtnLoading: false,
submitBtnLoading: false,
transferFormData: { usd_amount: '' },
transferFormRules: {
transfer_type: {
rules: [
{
required: true,
errorMessage: this.$t('form.transType.required')
}
]
},
mt4_server_in: {
rules: [
{
required: true,
errorMessage: this.$t('form.mtServer.required')
}
]
},
mt4_login_out: {
rules: [
{
required: true,
errorMessage: this.$t('form.mtAccount.required')
}
]
},
mt4_login_in: {
rules: [
{
required: true,
errorMessage: this.$t('form.mtAccount.required')
}
]
},
mt4_login_name: {
rules: [
{
required: true,
errorMessage: this.$t('form.mtAccountName.required')
}
]
},
usd_amount: {
rules: [
{
required: true,
errorMessage: this.$t('form.amount.required')
},
{
validateFunction: (rule, value, data, callback) => {
// 异步需要返回 Promise 对象
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Number(value) < this.goldRange?.tran_min) {
// 不通过返回 reject(new Error('错误信息'))
this.amountAvailable = false;
reject(new Error(' '));
} else if (Number(value) > (this.availableMoneyOut ?? 0)) {
this.amountAvailable = false;
this.unavailableAmountTip = `${this.$t('mtTransfer.maxAmount')} $${this.availableMoneyOut ?? 0}`;
reject(new Error(' '));
} else {
// 通过返回 resolve
this.amountAvailable = true;
resolve();
}
}, 0);
});
}
}
]
},
safe_pass: {
rules: [
{
required: true,
errorMessage: this.$t('form.CRMPassword.required')
}
]
}
}
};
},
methods: {
handleAmountInput() {
this.amountAvailable = true;
this.unavailableAmountTip = `${this.$t('mtTransfer.minAmount')} $${this.goldRange?.tran_min??0}`;
},
goldRangePlaceholderRender(min, max) {
return `${this.$t('form.amount.placeholderBefore')}${min}-${max}${this.$t('form.amount.placeholderAfter')}`;
},
async getMtLoginData() {
const res = await getMTAccounts2({ server_type: 'live' });
if (res && res.code === 0) {
this.mtLoginOptions = res.data?.map((mtAccount) => ({
text: `${mtAccount.mt4_server_name} ${mtAccount.mt4_login}`,
value: mtAccount.mt4_login?.toString()
}));
res.data?.forEach((mtAccount) => {
this.mtlogins[mtAccount.mt4_login] = mtAccount;
});
if (res.data[0]) {
if (this.paramsMtLogin && this.mtlogins[this.paramsMtLogin]) {
this.transferFormData.mt4_login_out = this.paramsMtLogin;
this.mtLoginOutChange(this.paramsMtLogin);
} else {
this.transferFormData.mt4_login_out = res.data[0].mt4_login;
this.mtLoginOutChange(res.data[0].mt4_login);
}
}
}
},
async getMtServerOptions() {
const res = await getMtServers({ qcc_language: UserLanguage, server_type: 'live' });
if (res && res.code === 0) {
let tempOptions = res.data?.map((item) => ({
text: item.server_name,
value: item.id
}));
if (this.actInfo && this.actInfo.actMtLogin && this.actInfo.actMtServer) {
tempOptions = tempOptions.filter((item) => item.value === Number(this.actInfo.actMtServer));
}
this.mtServerOptions = tempOptions;
}
if (this.mtServerOptions[0] && !this.actId && !this.mt4Server && !this.mt4Login) {
this.transferFormData.mt4_server_in = this.mtServerOptions[0].value;
}
},
async getIfOTParams() {
const res = await getIfOTParams();
if (res && res.code === 0) {
this.ioPowerMap = res.data;
if(this.ioPowerMap != null && this.ioPowerMap.gold_transfer_own==0 && this.ioPowerMap.gold_transfer_out==0 ){
this.transTypeOptions = [{text:this.$t('form.transType.0'),value:0}, {text:this.$t('form.transType.1'),value:1}]
}else if (this.ioPowerMap != null && this.ioPowerMap.gold_transfer_own==1 && this.ioPowerMap.gold_transfer_out==0 ){
this.transTypeOptions = [{text:this.$t('form.transType.1'),value:1}]
}else if (this.ioPowerMap != null && this.ioPowerMap.gold_transfer_own!=1 && this.ioPowerMap.gold_transfer_out==1 ){
this.transTypeOptions = [{text:this.$t('form.transType.0'),value:0}]
}else {
this.transTypeOptions = []
}
}
},
async getBankListData() {
const res = await getBankList();
if (res && res.code === 0) {
this.bankOptions = res.data.map((item) => ({
text: item.bank_no,
value: item.bank_no,
disable: item.apply_status === 0
}));
res.data?.forEach((bank) => {
this.banks[bank.bank_no] = bank;
});
}
},
async getCurrency() {
const res = await getDictByCode('currency_type');
if (res && res.code === 0) {
this.currencyOptions = res.data?.map((item) => ({
text: item.fun_item_text,
value: item.fun_item_code
}));
}
},
async getGoldRangeData() {
const res = await getGoldRange({ mt4_login: this.selectedMtLoginOut.mt4_login, mt4_server: this.selectedMtLoginOut.mt4_server });
if (res && res.code === 0) {
this.goldRange = res.data;
}
},
async getRate() {
const params = {
mt4_server: this.selectedMtLoginOut?.mt4_server,
mt4_login: this.selectedMtLoginOut?.mt4_login,
exchange_currency: this.transferFormData?.currency_type,
type: 'mt4',
io: 'o'
};
const res = await getExchangeRate(params);
if (res && res.code === 0) {
this.exchangeRate = res.data.exchange_rate;
this.rateSign = res.data.exchange_rate_sign;
}
},
showDetailDialog() {
this.$refs.transferForm.validateField(['mt4_login_out', 'mt4_server_in', 'mt4_login_in', 'transfer_type', 'mt4_login_name', 'usd_amount']).then(() => {
this.$refs.alertDialog.open();
});
},
closeDetailDialog() {
this.$refs.alertDialog.close();
},
async handleSaveTransfer() {
this.$refs.transferForm.validate().then(async (fields) => {
this.submitBtnLoading = true;
const res = await saveTransfer({
...fields,
qcc_language: UserLanguage,
mt4_server_out: this.selectedMtLoginOut?.mt4_server,
mt4_server_in: this.transferFormData.mt4_server_in
});
this.closeDetailDialog();
this.submitBtnLoading = false;
if (res && res.code === 0) {
uni.redirectTo({
url: '/pages/capital/transfer/success/index'
});
} else {
this.$nextTick(() => {
this.$cusModal.showModal({
type: 'message',
status: 'warning',
contentText: res.msg ?? this.$t('common.error.sysError')
});
})
}
});
},
mtLoginOutChange(val) {
this.selectedMtLoginOut = this.mtlogins[val];
if (this.selectedMtLoginOut) {
if (this.selectedMtLoginOut.ifCent === 'YES') {
this.availableMoneyOut = (
((this.selectedMtLoginOut.margin_free ?? 0) - (this.selectedMtLoginOut.margin ?? 0) - (this.selectedMtLoginOut.mt4_credit ?? 0)) /
100
).toFixed(2);
} else if (this.selectedMtLoginOut.ifCent === 'NO') {
this.availableMoneyOut = (
(((this.selectedMtLoginOut.margin_free ?? 0) - (this.selectedMtLoginOut.margin ?? 0) - (this.selectedMtLoginOut.mt4_credit ?? 0)) * 100) /
100
).toFixed(2);
}
this.mtLoginInOptions = this.mtLoginOptions.filter((item) => item.value !== val);
this.getGoldRangeData();
}
},
transTypeChange(val){
this.selectedMtLoginIn = undefined
this.transferFormData.mt4_server_in = undefined
this.transferFormData.mt4_login_in = undefined
this.transferFormData.mt4_login_name = undefined
if(val == 0) {
this.showTransferOut = false
this.showTransferOwn = true
}else if (val == 1){
this.showTransferOut = true
this.showTransferOwn = false
}else {
this.showTransferOut = false
this.showTransferOwn = false
}
},
mtLoginInChange(val) {
this.selectedMtLoginIn = this.mtlogins[val];
this.transferFormData.mt4_server_in = this.mtlogins[val].mt4_server;
},
currencyChange(val) {
this.getRate();
},
bankChange(val) {
this.selectedBank = this.banks[val];
this.transferFormData.currency_type = this.selectedBank.bank_currency;
this.getRate();
}
},
computed: {
filteredCurrencyOptions() {
return this.currencyOptions.filter((item) => item.value === this.selectedBank?.bank_currency);
}
},
watch: {
'transferFormData.usd_amount': {
handler(newVal, oldVal) {
this.currency_amount = this.exchangeRate && newVal ? this.exchangeRate * newVal : undefined;
this.subsidy = this.subsidyRate && newVal ? (this.subsidyRate * newVal) / 100 : undefined;
}
},
goldRange: {
handler(newVal, oldVal) {
this.unavailableAmountTip = `${this.$t('mtTransfer.minAmount')} $${newVal?.tran_min ?? 0}`;
}
},
exchangeRate: {
handler(newVal, oldVal) {
this.currency_amount = newVal && this.transferFormData.usd_amount ? newVal * this.transferFormData.usd_amount : '-';
}
}
},
created() {
this.getIfOTParams();
this.getBankListData();
this.getCurrency();
this.getMtServerOptions();
},
onLoad(params) {
if (params.mtLogin) {
this.paramsMtLogin = params.mtLogin;
}
this.getMtLoginData();
}
};
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>