调整表格滚动条

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> </TransferForm>
<div class="transfer-type verify" v-if="transferType === 'external'"> <div class="transfer-type verify" v-if="transferType === 'external'">
<div class="type-title">验证方式</div> <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 <el-form
class="verify-form" class="verify-form"
:model="transferForm" :model="verifyForm"
:rules="transferFormRules" :rules="verifyFormRules"
ref="verifyFormRef" ref="verifyFormRef"
> >
<el-form-item prop="code"> <el-form-item :label="t('personalCenter.verifyMethod')" prop="verifyType">
<el-input <el-radio-group v-model="verifyForm.verifyType" @change="onVerifyTypeChange">
v-model="transferForm.code" <el-radio label="email" :disabled="!userInfo.email">邮箱验证</el-radio>
style="max-width: 300px" <el-radio label="phone" :disabled="!userInfo.mobile">手机号验证</el-radio>
placeholder="请输入验证码" </el-radio-group>
>
</el-input>
<el-button type="primary" @click="handleSendCode" :disabled="sendState.isCounting">{{
sendState.isCounting ? `${sendState.countdown}s后重新获取` : '发送验证码'
}}</el-button>
</el-form-item> </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> </el-form>
</div> </div>
<el-button type="primary" @click="handleSubmit" v-auth="'user_transfer'">提交转账</el-button> <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 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 { internalFormItem, externalFormItem } from './options'
import { rules } from './rules' import { rules } from './rules'
import { codeRules } from '@/views/user/config/rules'
// //
import { getTransferWalletOptionsApi, transferApi } from '@/api/modules/funding/transfer' import { getTransferWalletOptionsApi, transferApi } from '@/api/modules/funding/transfer'
@ -142,7 +136,10 @@ import { getStorage } from '@/utils/storage'
import { useUserStore } from '@/stores/modules/user' import { useUserStore } from '@/stores/modules/user'
const userStore = useUserStore() const userStore = useUserStore()
console.log('userStore:', userStore);
import { sendCaptcha, initCaptchaState, clearCaptchaTimer } from '@/utils/sendCaptcha' import { sendCaptcha, initCaptchaState, clearCaptchaTimer } from '@/utils/sendCaptcha'
const { t } = useI18n()
/** /**
* @description 转账类型 * @description 转账类型
* @default internal * @default internal
@ -160,6 +157,13 @@ const createDefaultTransferForm = () => ({
// //
MaxOutAmount: '', MaxOutAmount: '',
type: '', type: '',
})
/**
* @description 创建默认验证码表单数据
*/
const createDefaultVerifyForm = () => ({
verifyType: 'email',
code: '', code: '',
}) })
@ -167,11 +171,25 @@ const createDefaultTransferForm = () => ({
* @description 转账表单数据 * @description 转账表单数据
*/ */
const transferForm = ref(createDefaultTransferForm()) const transferForm = ref(createDefaultTransferForm())
/**
* @description 验证码表单数据
*/
const verifyForm = ref(createDefaultVerifyForm())
/** /**
* @description 主转账表单和验证码表单引用 * @description 主转账表单和验证码表单引用
*/ */
const mainTransferFormRef = ref() const mainTransferFormRef = ref()
const verifyFormRef = ref() const verifyFormRef = ref()
/**
* @description 验证码表单校验规则
*/
const verifyFormRules = ref({
verifyType: [{ required: true, message: t('personalCenter.pleaseSelectVerifyMethod'), trigger: 'change' }],
code: codeRules().code,
})
const transferFormItemOptions = computed(() => const transferFormItemOptions = computed(() =>
transferType.value === 'internal' ? internalFormItem : externalFormItem, transferType.value === 'internal' ? internalFormItem : externalFormItem,
) )
@ -202,10 +220,9 @@ const transferFormOptionsMap = ref({
*/ */
//userInfo //userInfo
const userInfo = getStorage<any>('userInfo') const userInfo = getStorage<any>('userInfo')
const verifyType = ref('email')
// //
const sendState = ref<any>({ const sendState = ref({
isCounting: false, isCounting: false,
countdown: 0, countdown: 0,
}) })
@ -220,78 +237,85 @@ const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaS
// //
const { isCounting: phoneIsCounting, countdown: phoneCountdown } = phoneCaptchaState const { isCounting: phoneIsCounting, countdown: phoneCountdown } = phoneCaptchaState
// sendState //
const updateSendState = (type: string) => { const currentIsCounting = computed(() =>
if (type === 'email') { verifyForm.value.verifyType === 'email' ? emailIsCounting.value : phoneIsCounting.value
sendState.value = { )
isCounting: emailIsCounting, const currentCountdown = computed(() =>
countdown: emailCountdown, verifyForm.value.verifyType === 'email' ? emailCountdown.value : phoneCountdown.value
}
} 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 }, //
) )
// // sendState
const sendCodeApi = async () => { const updateSendState = () => {
// const type = verifyForm.value.verifyType
const sendParams = { //
email: userInfo.email, sendState.value = {
mobile: userInfo.mobile, isCounting: type === 'email' ? emailIsCounting.value : phoneIsCounting.value,
reg_type: verifyType.value === 'email' ? 1 : 2, countdown: type === 'email' ? emailCountdown.value : phoneCountdown.value,
type: 'resetPass_code',
} }
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 handleSendCode = async () => {
const currentType = verifyType.value const type = verifyForm.value.verifyType
// /
const type: string = currentType || 'email'
if (type === 'phone') { if (type === 'phone') {
// 1 // 1
if (!userInfo.phone) { if (!userInfo.mobile) {
ElMessage.error('请先绑定手机号') ElMessage.error('请先绑定手机号')
return return
} }
// //
await sendCaptcha(type, userInfo.phone, phoneCaptchaState, () => sendCodeApi()) await sendCaptcha(type, userInfo.mobile, phoneCaptchaState, sendCodeApi)
updateSendState(type)
} else { } else {
// 2 // 2
if (!userInfo.email) { if (!userInfo.email) {
@ -300,8 +324,7 @@ const handleSendCode = async () => {
} }
// //
await sendCaptcha(type, userInfo.email, emailCaptchaState, () => sendCodeApi()) await sendCaptcha(type, userInfo.email, emailCaptchaState, sendCodeApi)
updateSendState(type)
} }
} }
@ -357,6 +380,9 @@ const resetTransferForm = async () => {
MaxOutAmount: getDefaultMaxOutAmount(), MaxOutAmount: getDefaultMaxOutAmount(),
}) })
//
Object.assign(verifyForm.value, createDefaultVerifyForm())
await nextTick() await nextTick()
verifyFormRef.value?.clearValidate?.() verifyFormRef.value?.clearValidate?.()
} }
@ -376,16 +402,12 @@ const handleTransferTabClick = async (type: string) => {
* @description 切换验证方式 * @description 切换验证方式
* @param type 验证方式 * @param type 验证方式
*/ */
const handleVerifyTabClick = (type: string) => {
verifyType.value = type
}
const handleVerifyParams = (type: string) => { const handleVerifyParams = (type: string) => {
if (type === 'external') { if (type === 'external') {
if (verifyType.value === 'email') { if (verifyForm.value.verifyType === 'email') {
return userInfo.email return userInfo.email
} else { } else {
return userInfo.phone return userInfo.mobile
} }
} else { } else {
return transferForm.value.transferInAccount return transferForm.value.transferInAccount
@ -418,8 +440,8 @@ const handleSubmit = async () => {
} else { } else {
await transferApi({ await transferApi({
...params, ...params,
verify_type: verifyType.value === 'email' ? '1' : '2', verify_type: verifyForm.value.verifyType === 'email' ? '1' : '2',
verify_code: transferForm.value.code, verify_code: verifyForm.value.code,
}) })
} }
@ -503,17 +525,26 @@ const handleSubmit = async () => {
} }
.verify { .verify {
.tab, :deep(.el-radio-group) {
.username { display: flex;
margin-bottom: 10px; gap: 20px;
}
.verify-account {
font-weight: 500;
color: #333;
} }
} }
.verify-form { .verify-form {
.el-form-item { max-width: 500px;
:deep(.el-form-item__content) {
flex-wrap: nowrap; :deep(.el-form-item) {
} margin-bottom: 20px;
}
:deep(.el-form-item__content) {
flex-wrap: nowrap;
} }
} }
} }

View File

@ -194,7 +194,7 @@
> >
<el-button <el-button
:type="dialogType === 'leverage' ? 'primary' : 'default'" :type="dialogType === 'leverage' ? 'primary' : 'default'"
@click="dialogType = 'leverage'" @click="handleChangeToLeverage"
>修改杠杆</el-button >修改杠杆</el-button
> >
</div> </div>
@ -249,7 +249,7 @@ const dialogVisible = ref(false)
const dialogTitle = ref('') const dialogTitle = ref('')
const dialogType = ref('add') const dialogType = ref('add')
const accountList = ref([]) const accountList = ref<any[]>([])
const getAccoundList = async () => { const getAccoundList = async () => {
const res = await getAllAccount({ username: '' }) const res = await getAllAccount({ username: '' })
console.log(res) console.log(res)
@ -432,6 +432,18 @@ const handleSetting = (id: string) => {
dialogType.value = 'setting' 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: 复制推广二维码和推广链接方法 * @description: 复制推广二维码和推广链接方法
*/ */

View File

@ -110,7 +110,7 @@ export const positionOrderTableColumns = [
//平仓价格 //平仓价格
{ label: '平仓价格', prop: 'closePrice' }, { label: '平仓价格', prop: 'closePrice' },
//金额 //金额
{ label: '金额', prop: 'amount' }, { label: '平仓盈亏', prop: 'closeProfitLoss', align: 'center' as const, width: '150px' },
//创建时间 //创建时间
{ label: '创建时间', prop: 'createdTime' }, { label: '创建时间', prop: 'createdTime' },
] ]

View File

@ -379,7 +379,7 @@ const handleMarketFormLinkage = async (type: 'level' | 'parentAccountName', valu
...item, ...item,
varietyName: item.name, varietyName: item.name,
varietyCode: item.code, varietyCode: item.code,
pointDifference: item.target_point_diff, pointDifference: dialogType.value === 'add' ? 0 : item.target_point_diff, // 0
assignedPointDifference: '', assignedPointDifference: '',
})) }))
} }
@ -760,7 +760,7 @@ const handleCancel = async () => {
.table-wrapper { .table-wrapper {
flex: 1; 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" <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)" :maxlength="1" @input="handleInput(index, $event)" @focus="handleFocus(index)" @keyup.delete="handleDelete(index)"
ref="inputRefs" type="text" /> ref="inputRefs" type="text" />
<el-button type="primary" class="form-btn" v-if="showSendButton" @click="sendCode" :disabled="sendState.isCounting">{{ <el-button type="primary" class="form-btn" v-if="showSendButton" @click="sendCode" :disabled="isCounting">{{
sendState.isCounting ? `${sendState.countdown}s后重新获取` : '发送验证码' }}</el-button> isCounting ? `${countdown}s后重新获取` : '发送验证码' }}</el-button>
</el-form-item> </el-form-item>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, nextTick, toRefs, reactive, computed } from 'vue'
defineOptions({ defineOptions({
name: 'Captcha' name: 'Captcha'
@ -39,6 +40,21 @@ const props = defineProps({
default: 'code' // ruleskey 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 { showSendButton } = toRefs(props)
const emit = defineEmits(['update:modelValue', 'change', 'finish', 'sendCode']) const emit = defineEmits(['update:modelValue', 'change', 'finish', 'sendCode'])