调整表格滚动条

This commit is contained in:
2026-05-11 13:16:24 +08:00
parent 022c18c6be
commit ca9f4b2862
5 changed files with 169 additions and 110 deletions

View File

@ -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,
}
}
}
// activeTabsendState
const initSendState = () => {
const currentType = verifyType.value === 'email' ? 'email' : 'phone'
updateSendState(currentType)
}
onMounted(() => {
//
initSendState()
})
// verifyTypesendState
watch(
verifyType,
(newTab, oldTab) => {
verifyType.value = newTab
console.log('verifyType.value', verifyType.value)
// taboldTaboldTabundefined
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;
}
}
}

View File

@ -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: 复制推广二维码和推广链接方法
*/

View File

@ -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' },
]

View File

@ -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;
}
}

View File

@ -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' // ruleskey
},
})
//
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'])