调整表格滚动条
This commit is contained in:
parent
022c18c6be
commit
ca9f4b2862
|
|
@ -85,37 +85,28 @@
|
|||
</TransferForm>
|
||||
<div class="transfer-type verify" v-if="transferType === 'external'">
|
||||
<div class="type-title">验证方式</div>
|
||||
<div class="tab">
|
||||
<el-button
|
||||
:type="verifyType === 'email' ? 'primary' : 'default'"
|
||||
@click="handleVerifyTabClick('email')"
|
||||
>邮箱验证</el-button
|
||||
>
|
||||
<el-button
|
||||
:type="verifyType === 'phone' ? 'primary' : 'default'"
|
||||
@click="handleVerifyTabClick('phone')"
|
||||
>手机号验证</el-button
|
||||
>
|
||||
</div>
|
||||
<div class="username">{{ verifyType === 'email' ? userInfo.email : userInfo.phone }}</div>
|
||||
<el-form
|
||||
class="verify-form"
|
||||
:model="transferForm"
|
||||
:rules="transferFormRules"
|
||||
:model="verifyForm"
|
||||
:rules="verifyFormRules"
|
||||
ref="verifyFormRef"
|
||||
>
|
||||
<el-form-item prop="code">
|
||||
<el-input
|
||||
v-model="transferForm.code"
|
||||
style="max-width: 300px"
|
||||
placeholder="请输入验证码"
|
||||
>
|
||||
</el-input>
|
||||
|
||||
<el-button type="primary" @click="handleSendCode" :disabled="sendState.isCounting">{{
|
||||
sendState.isCounting ? `${sendState.countdown}s后重新获取` : '发送验证码'
|
||||
}}</el-button>
|
||||
<el-form-item :label="t('personalCenter.verifyMethod')" prop="verifyType">
|
||||
<el-radio-group v-model="verifyForm.verifyType" @change="onVerifyTypeChange">
|
||||
<el-radio label="email" :disabled="!userInfo.email">邮箱验证</el-radio>
|
||||
<el-radio label="phone" :disabled="!userInfo.mobile">手机号验证</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('personalCenter.verifyAccount')">
|
||||
<span class="verify-account">{{ verifyForm.verifyType === 'email' ? userInfo.email : userInfo.mobile }}</span>
|
||||
</el-form-item>
|
||||
<UserCaptcha
|
||||
prop="code"
|
||||
v-model="verifyForm.code"
|
||||
@sendCode="handleSendCode"
|
||||
:show-send-button="true"
|
||||
:send-state="sendState"
|
||||
/>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-button type="primary" @click="handleSubmit" v-auth="'user_transfer'">提交转账</el-button>
|
||||
|
|
@ -129,10 +120,13 @@ defineOptions({
|
|||
})
|
||||
//组件
|
||||
import TransferForm from '@/components/common/Form.vue'
|
||||
import UserCaptcha from '@/views/user/components/Captcha.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
//配置
|
||||
import { internalFormItem, externalFormItem } from './options'
|
||||
import { rules } from './rules'
|
||||
import { codeRules } from '@/views/user/config/rules'
|
||||
|
||||
//接口
|
||||
import { getTransferWalletOptionsApi, transferApi } from '@/api/modules/funding/transfer'
|
||||
|
|
@ -142,7 +136,10 @@ import { getStorage } from '@/utils/storage'
|
|||
|
||||
import { useUserStore } from '@/stores/modules/user'
|
||||
const userStore = useUserStore()
|
||||
console.log('userStore:', userStore);
|
||||
import { sendCaptcha, initCaptchaState, clearCaptchaTimer } from '@/utils/sendCaptcha'
|
||||
|
||||
const { t } = useI18n()
|
||||
/**
|
||||
* @description 转账类型
|
||||
* @default internal
|
||||
|
|
@ -160,6 +157,13 @@ const createDefaultTransferForm = () => ({
|
|||
// 最大可转账金额
|
||||
MaxOutAmount: '',
|
||||
type: '',
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 创建默认验证码表单数据
|
||||
*/
|
||||
const createDefaultVerifyForm = () => ({
|
||||
verifyType: 'email',
|
||||
code: '',
|
||||
})
|
||||
|
||||
|
|
@ -167,11 +171,25 @@ const createDefaultTransferForm = () => ({
|
|||
* @description 转账表单数据
|
||||
*/
|
||||
const transferForm = ref(createDefaultTransferForm())
|
||||
|
||||
/**
|
||||
* @description 验证码表单数据
|
||||
*/
|
||||
const verifyForm = ref(createDefaultVerifyForm())
|
||||
|
||||
/**
|
||||
* @description 主转账表单和验证码表单引用
|
||||
*/
|
||||
const mainTransferFormRef = ref()
|
||||
const verifyFormRef = ref()
|
||||
|
||||
/**
|
||||
* @description 验证码表单校验规则
|
||||
*/
|
||||
const verifyFormRules = ref({
|
||||
verifyType: [{ required: true, message: t('personalCenter.pleaseSelectVerifyMethod'), trigger: 'change' }],
|
||||
code: codeRules().code,
|
||||
})
|
||||
const transferFormItemOptions = computed(() =>
|
||||
transferType.value === 'internal' ? internalFormItem : externalFormItem,
|
||||
)
|
||||
|
|
@ -202,10 +220,9 @@ const transferFormOptionsMap = ref({
|
|||
*/
|
||||
//获取userInfo
|
||||
const userInfo = getStorage<any>('userInfo')
|
||||
const verifyType = ref('email')
|
||||
|
||||
// 发送验证码
|
||||
const sendState = ref<any>({
|
||||
// 发送验证码状态
|
||||
const sendState = ref({
|
||||
isCounting: false,
|
||||
countdown: 0,
|
||||
})
|
||||
|
|
@ -220,78 +237,85 @@ const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaS
|
|||
// 手机验证码状态
|
||||
const { isCounting: phoneIsCounting, countdown: phoneCountdown } = phoneCaptchaState
|
||||
|
||||
// 统一更新sendState的方法
|
||||
const updateSendState = (type: string) => {
|
||||
if (type === 'email') {
|
||||
sendState.value = {
|
||||
isCounting: emailIsCounting,
|
||||
countdown: emailCountdown,
|
||||
}
|
||||
} else {
|
||||
sendState.value = {
|
||||
isCounting: phoneIsCounting,
|
||||
countdown: phoneCountdown,
|
||||
}
|
||||
}
|
||||
}
|
||||
// 初始化时根据当前activeTab更新sendState(避免刷新后丢失)
|
||||
const initSendState = () => {
|
||||
const currentType = verifyType.value === 'email' ? 'email' : 'phone'
|
||||
updateSendState(currentType)
|
||||
}
|
||||
onMounted(() => {
|
||||
// 页面加载时立即执行,恢复倒计时
|
||||
initSendState()
|
||||
})
|
||||
// 监听verifyType变化,同步sendState
|
||||
watch(
|
||||
verifyType,
|
||||
(newTab, oldTab) => {
|
||||
verifyType.value = newTab
|
||||
console.log('verifyType.value', verifyType.value)
|
||||
// 只有“主动切换tab”(oldTab有值)时才处理,初始化时(oldTab为undefined)不触发
|
||||
if (oldTab === undefined) return
|
||||
|
||||
if (newTab === 'email' || newTab === 'phone') {
|
||||
// 主动切换到邮箱/手机页时,同步当前类型的倒计时状态(不再无脑重置)
|
||||
updateSendState(newTab)
|
||||
} else if (newTab === 'code') {
|
||||
// 切换到验证码页时,根据存储的类型更新状态
|
||||
const currentType: string = getStorage('forgotType', 'session') || 'email'
|
||||
updateSendState(currentType)
|
||||
}
|
||||
},
|
||||
{ immediate: false }, // 关键:关闭立即执行,避免刷新时触发
|
||||
// 当前验证方式的倒计时状态
|
||||
const currentIsCounting = computed(() =>
|
||||
verifyForm.value.verifyType === 'email' ? emailIsCounting.value : phoneIsCounting.value
|
||||
)
|
||||
const currentCountdown = computed(() =>
|
||||
verifyForm.value.verifyType === 'email' ? emailCountdown.value : phoneCountdown.value
|
||||
)
|
||||
|
||||
// 定义发送验证码接口
|
||||
const sendCodeApi = async () => {
|
||||
// 发送验证码参数
|
||||
const sendParams = {
|
||||
email: userInfo.email,
|
||||
mobile: userInfo.mobile,
|
||||
reg_type: verifyType.value === 'email' ? 1 : 2,
|
||||
type: 'resetPass_code',
|
||||
// 更新sendState的方法
|
||||
const updateSendState = () => {
|
||||
const type = verifyForm.value.verifyType
|
||||
// 创建新对象以触发响应式更新
|
||||
sendState.value = {
|
||||
isCounting: type === 'email' ? emailIsCounting.value : phoneIsCounting.value,
|
||||
countdown: type === 'email' ? emailCountdown.value : phoneCountdown.value,
|
||||
}
|
||||
return userStore.sendCode(sendParams)
|
||||
}
|
||||
|
||||
// 监听倒计时状态变化,同步到 sendState
|
||||
watch(
|
||||
emailIsCounting,
|
||||
() => updateSendState()
|
||||
)
|
||||
watch(
|
||||
emailCountdown,
|
||||
() => updateSendState()
|
||||
)
|
||||
watch(
|
||||
phoneIsCounting,
|
||||
() => updateSendState()
|
||||
)
|
||||
watch(
|
||||
phoneCountdown,
|
||||
() => updateSendState()
|
||||
)
|
||||
|
||||
// 切换验证方式时清除验证码
|
||||
const onVerifyTypeChange = () => {
|
||||
verifyForm.value.code = ''
|
||||
nextTick(() => {
|
||||
verifyFormRef.value?.clearValidate(['code'])
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
// 页面加载完成
|
||||
})
|
||||
|
||||
// 定义发送验证码接口
|
||||
const sendCodeApi = async (receiver: string) => {
|
||||
// 发送验证码参数
|
||||
const type = verifyForm.value.verifyType
|
||||
const params: any = {
|
||||
reg_type: userStore.userInfo!.reg_type,
|
||||
type: 'transfer_code',
|
||||
}
|
||||
if (type === 'email') {
|
||||
params.email = receiver
|
||||
} else {
|
||||
params.mobile = receiver
|
||||
// 从手机号中提取区号
|
||||
const match = receiver.match(/^\+(\d{1,4})/)
|
||||
params.mobile_area = match ? '+' + match[1] : '+86'
|
||||
}
|
||||
return userStore.sendCode(params)
|
||||
}
|
||||
|
||||
//发送验证码
|
||||
const handleSendCode = async () => {
|
||||
const currentType = verifyType.value
|
||||
// 确定类型:手机/邮箱
|
||||
const type: string = currentType || 'email'
|
||||
const type = verifyForm.value.verifyType
|
||||
|
||||
if (type === 'phone') {
|
||||
// 场景1:发送手机验证码
|
||||
if (!userInfo.phone) {
|
||||
if (!userInfo.mobile) {
|
||||
ElMessage.error('请先绑定手机号')
|
||||
return
|
||||
}
|
||||
|
||||
// 执行发送
|
||||
await sendCaptcha(type, userInfo.phone, phoneCaptchaState, () => sendCodeApi())
|
||||
updateSendState(type)
|
||||
await sendCaptcha(type, userInfo.mobile, phoneCaptchaState, sendCodeApi)
|
||||
} else {
|
||||
// 场景2:发送邮箱验证码
|
||||
if (!userInfo.email) {
|
||||
|
|
@ -300,8 +324,7 @@ const handleSendCode = async () => {
|
|||
}
|
||||
|
||||
// 执行发送
|
||||
await sendCaptcha(type, userInfo.email, emailCaptchaState, () => sendCodeApi())
|
||||
updateSendState(type)
|
||||
await sendCaptcha(type, userInfo.email, emailCaptchaState, sendCodeApi)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -357,6 +380,9 @@ const resetTransferForm = async () => {
|
|||
MaxOutAmount: getDefaultMaxOutAmount(),
|
||||
})
|
||||
|
||||
// 重置验证码表单
|
||||
Object.assign(verifyForm.value, createDefaultVerifyForm())
|
||||
|
||||
await nextTick()
|
||||
verifyFormRef.value?.clearValidate?.()
|
||||
}
|
||||
|
|
@ -376,16 +402,12 @@ const handleTransferTabClick = async (type: string) => {
|
|||
* @description 切换验证方式
|
||||
* @param type 验证方式
|
||||
*/
|
||||
const handleVerifyTabClick = (type: string) => {
|
||||
verifyType.value = type
|
||||
}
|
||||
|
||||
const handleVerifyParams = (type: string) => {
|
||||
if (type === 'external') {
|
||||
if (verifyType.value === 'email') {
|
||||
if (verifyForm.value.verifyType === 'email') {
|
||||
return userInfo.email
|
||||
} else {
|
||||
return userInfo.phone
|
||||
return userInfo.mobile
|
||||
}
|
||||
} else {
|
||||
return transferForm.value.transferInAccount
|
||||
|
|
@ -418,8 +440,8 @@ const handleSubmit = async () => {
|
|||
} else {
|
||||
await transferApi({
|
||||
...params,
|
||||
verify_type: verifyType.value === 'email' ? '1' : '2',
|
||||
verify_code: transferForm.value.code,
|
||||
verify_type: verifyForm.value.verifyType === 'email' ? '1' : '2',
|
||||
verify_code: verifyForm.value.code,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -503,17 +525,26 @@ const handleSubmit = async () => {
|
|||
}
|
||||
|
||||
.verify {
|
||||
.tab,
|
||||
.username {
|
||||
margin-bottom: 10px;
|
||||
:deep(.el-radio-group) {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.verify-account {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.verify-form {
|
||||
.el-form-item {
|
||||
:deep(.el-form-item__content) {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
max-width: 500px;
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__content) {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@
|
|||
>
|
||||
<el-button
|
||||
:type="dialogType === 'leverage' ? 'primary' : 'default'"
|
||||
@click="dialogType = 'leverage'"
|
||||
@click="handleChangeToLeverage"
|
||||
>修改杠杆</el-button
|
||||
>
|
||||
</div>
|
||||
|
|
@ -249,7 +249,7 @@ const dialogVisible = ref(false)
|
|||
const dialogTitle = ref('')
|
||||
const dialogType = ref('add')
|
||||
|
||||
const accountList = ref([])
|
||||
const accountList = ref<any[]>([])
|
||||
const getAccoundList = async () => {
|
||||
const res = await getAllAccount({ username: '' })
|
||||
console.log(res)
|
||||
|
|
@ -432,6 +432,18 @@ const handleSetting = (id: string) => {
|
|||
dialogType.value = 'setting'
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 修改杠杆
|
||||
*/
|
||||
const handleChangeToLeverage = () => {
|
||||
// 切换到杠杆表单时,设置默认值为当前账户的杠杆值
|
||||
const currentAccount = accountList.value.find((item: any) => item.account_id === account_id)
|
||||
if (currentAccount?.wallets_trade?.lever) {
|
||||
subAccountForm.value.leverage = currentAccount.wallets_trade.lever
|
||||
}
|
||||
dialogType.value = 'leverage'
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 复制推广二维码和推广链接方法
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export const positionOrderTableColumns = [
|
|||
//平仓价格
|
||||
{ label: '平仓价格', prop: 'closePrice' },
|
||||
//金额
|
||||
{ label: '金额', prop: 'amount' },
|
||||
{ label: '平仓盈亏', prop: 'closeProfitLoss', align: 'center' as const, width: '150px' },
|
||||
//创建时间
|
||||
{ label: '创建时间', prop: 'createdTime' },
|
||||
]
|
||||
|
|
@ -379,7 +379,7 @@ const handleMarketFormLinkage = async (type: 'level' | 'parentAccountName', valu
|
|||
...item,
|
||||
varietyName: item.name,
|
||||
varietyCode: item.code,
|
||||
pointDifference: item.target_point_diff,
|
||||
pointDifference: dialogType.value === 'add' ? 0 : item.target_point_diff, // 添加时初始化为0,编辑时继承上级值
|
||||
assignedPointDifference: '',
|
||||
}))
|
||||
}
|
||||
|
|
@ -760,7 +760,7 @@ const handleCancel = async () => {
|
|||
|
||||
.table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@
|
|||
<el-input v-for="(item, index) in inputList" :key="index" v-model="inputList[index]" class="captcha-input-item"
|
||||
:maxlength="1" @input="handleInput(index, $event)" @focus="handleFocus(index)" @keyup.delete="handleDelete(index)"
|
||||
ref="inputRefs" type="text" />
|
||||
<el-button type="primary" class="form-btn" v-if="showSendButton" @click="sendCode" :disabled="sendState.isCounting">{{
|
||||
sendState.isCounting ? `${sendState.countdown}s后重新获取` : '发送验证码' }}</el-button>
|
||||
<el-button type="primary" class="form-btn" v-if="showSendButton" @click="sendCode" :disabled="isCounting">{{
|
||||
isCounting ? `${countdown}s后重新获取` : '发送验证码' }}</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick, toRefs, reactive, computed } from 'vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'Captcha'
|
||||
|
|
@ -39,6 +40,21 @@ const props = defineProps({
|
|||
default: 'code' // 和父组件rules中的key一致
|
||||
},
|
||||
})
|
||||
|
||||
// 本地倒计时状态
|
||||
const isCounting = ref(false)
|
||||
const countdown = ref(0)
|
||||
|
||||
// 监听外部 sendState 变化
|
||||
watch(
|
||||
() => props.sendState,
|
||||
(newVal) => {
|
||||
isCounting.value = newVal.isCounting
|
||||
countdown.value = newVal.countdown
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
const { showSendButton } = toRefs(props)
|
||||
const emit = defineEmits(['update:modelValue', 'change', 'finish', 'sendCode'])
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue