Merge remote-tracking branch 'origin/yueyixin'

This commit is contained in:
2026-05-26 16:21:40 +08:00
commit d2b51ffe5f
4 changed files with 131 additions and 229 deletions

View File

@ -153,7 +153,7 @@ const transferType = ref('internal')
* @description 创建默认转账表单数据
*/
const createDefaultTransferForm = ():any => ({
transferOutAccount: -1,
transferOutAccount: '',
transferInAccount: '',
transferAmount: '',
remark: '',
@ -357,6 +357,8 @@ const getTransferWalletOptions = async () => {
const data: any = await getTransferWalletOptionsApi()
transferFormOptionsMap.value.transferOutAccount = data
transferFormOptionsMap.value.transferInAccount = data.filter((item: any) => item.value !== -1)
transferForm.value.transferOutAccount = -1
}
/**
* @description 页面加载完成需要渲染的数据

View File

@ -41,23 +41,18 @@ import { getStorage } from '@/utils/storage'
import dayjs from 'dayjs'
//
import { getRecentSevenDays } from '@/utils/handleTime.ts'
/**
* @description: 定义搜索数据
*/
//
const dateRange = {
start: dayjs().subtract(7, 'day').format('YYYY-MM-DD'),
end: dayjs().format('YYYY-MM-DD'),
}
const searchForm = ref({
const initTime = getRecentSevenDays()
const searchForm = ref<any>({
accountName: '',
orderId: '2',
tradeType: '',
start_time: dateRange.start,
end_time: dateRange.end,
startTime: dateRange.start,
endTime: dateRange.end,
dateRange: [initTime.start, initTime.end],
subAccountName: '',
})
const searchOptions = ref(search)
@ -85,6 +80,13 @@ const total = ref(0)
const getCustomerTradeOrderList = async () => {
try {
startLoading()
// dateRange
let startTime = initTime.start
let endTime = initTime.end
if (searchForm.value.dateRange && searchForm.value.dateRange.length === 2) {
startTime = dayjs(searchForm.value.dateRange[0]).format('YYYY-MM-DD HH:mm:ss')
endTime = dayjs(searchForm.value.dateRange[1]).format('YYYY-MM-DD HH:mm:ss')
}
const params = {
page: currentPage.value,
page_size: pageSize.value,
@ -92,8 +94,8 @@ const getCustomerTradeOrderList = async () => {
account_id: searchForm.value.subAccountName,
order_no: '',
type: searchForm.value.tradeType,
start_time: dateRange.start,
end_time: dateRange.end,
start_time: startTime,
end_time: endTime,
}
console.log(params)
const data: any = await getCustomTradeOrderListApi(params)
@ -165,10 +167,7 @@ const handleReset = () => {
accountName: '',
orderId: '',
tradeType: '',
startTime: dateRange.start,
endTime: dateRange.end,
start_time: dateRange.start,
end_time: dateRange.end,
dateRange: [initTime.start, initTime.end],
subAccountName: '',
}
getCustomerTradeOrderList()

View File

@ -57,18 +57,19 @@ export const search = [
],
width: '140px'
},
// // 开始时间
// {
// prop: "startTime", label: '注册开始时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
// valueFormat: 'YYYY-MM-DD',
// width: '140px'
// },
// // 结束时间
// {
// prop: "endTime", label: '注册结束时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
// valueFormat: 'YYYY-MM-DD',
// width: '140px'
// },
// 时间范围
{
label: '时间',
prop: 'dateRange',
type: 'date' as const,
dateType: 'datetimerange' as const,
placeholder: '请选择时间范围',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
width: '340'
},
]
/**

View File

@ -2,15 +2,16 @@
<div class="user-card">
<UserHeader />
<UserText :user-text="userText" @back="handleBack" />
<UserTabs v-model="activeTab" :hide-tab="hideTab" :tab-list="tabList" />
<UserTabs v-model="activeTab" :hide-tab="false" :tab-list="tabList" />
<el-form class="user-form" ref="forgotPasswordFormRef" :model="forgotPasswordForm" :rules="forgotPasswordRules">
<Transition name="form-switch" mode="out-in">
<el-form-item v-if="activeTab === 'email'" key="form-email-item" prop="email">
<!-- 邮箱输入 -->
<el-form-item prop="email" v-if="activeTab === 'email'">
<el-input v-model="forgotPasswordForm.email" placeholder="请输入邮箱" clearable size="large" />
</el-form-item>
<el-form-item class="phone-item" prop="phone" v-else-if="activeTab === 'phone'" key="form-phone-item">
<!-- 手机号输入 -->
<el-form-item class="phone-item" prop="phone" v-else-if="activeTab === 'phone'">
<el-select v-model="forgotPasswordForm.countryCode" :teleported="false" value-key="code" placeholder="国家"
size="large">
<el-option v-for="item in countryOptions" :key="item.code" :label="item.code" :value="item.code">
@ -22,26 +23,23 @@
</el-select>
<el-input v-model="forgotPasswordForm.phone" placeholder="请输入手机号" clearable size="large" />
</el-form-item>
<UserCaptcha v-model="forgotPasswordForm.code" v-else-if="activeTab === 'code'" key="form-code-item"
@sendCode="handleSendCode" :show-send-button="showSendButton" :send-state="sendState" />
<div v-else-if="activeTab === 'password'" key="form-password-group">
<!-- 验证码输入 -->
<UserCaptcha ref="captchaRef" v-model="forgotPasswordForm.code" @sendCode="handleSendCode" :show-send-button="showSendButton"
:send-state="sendState" />
<!-- 密码输入验证码发送后才可输入 -->
<el-form-item prop="password">
<el-input v-model="forgotPasswordForm.password" placeholder="请输入新密码" type="password" show-password clearable
size="large" />
<el-input v-model="forgotPasswordForm.password" :placeholder="codeSent ? '请输入新密码' : '请先发送验证码'"
:disabled="!codeSent" type="password" show-password clearable size="large" />
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input v-model="forgotPasswordForm.confirmPassword" placeholder="请确认新密码" type="password" show-password
clearable size="large" />
<el-input v-model="forgotPasswordForm.confirmPassword" :placeholder="codeSent ? '请确认新密码' : '请先发送验证码'"
:disabled="!codeSent" type="password" show-password clearable size="large" />
</el-form-item>
</div>
</Transition>
<div class="forgot-next">
<div :class="{ active: activeTab === 'email' || activeTab === 'phone' }"></div>
<div :class="{ active: activeTab === 'code' }"></div>
<div :class="{ active: activeTab === 'password' }"></div>
</div>
<el-form-item class="form-submit">
<el-button type="primary" @click="handleForgotPassword">{{ activeTab === 'password' ? '去登录' : '继续'
<el-button type="primary" @click="handleForgotPassword">{{ codeSent ? '重置密码' : '发送验证码'
}}</el-button>
</el-form-item>
</el-form>
@ -78,22 +76,24 @@ const router = useRouter()
//userText
const userText = ref({
backText: '返回',
title: '恢复密码',
title: '忘记密码',
text: '请输入您注册时使用的邮箱或手机号',
account: '',
})
//tabs
// tabs -
const tabList = ref([
{ label: '邮箱', name: 'email' },
{ label: '手机', name: 'phone' },
])
const activeTab = ref<string>('email')
const hideTab = ref<boolean>(false)
//
const codeSent = ref(false)
//
const forgotPasswordFormRef = ref<FormInstance>()
const captchaRef = ref()
const forgotPasswordForm = ref({
email: '',
countryCode: '+86',
@ -110,13 +110,31 @@ const forgotPasswordRules = ref<FormRules>({
code: codeRules().code
})
// activeTab
watch(activeTab, (newTab, oldTab) => {
codeSent.value = false
forgotPasswordForm.value.password = ''
forgotPasswordForm.value.confirmPassword = ''
//
captchaRef.value?.clear()
//
if (newTab === 'phone') {
forgotPasswordForm.value.email = ''
forgotPasswordFormRef.value?.clearValidate(['email'])
} else if (newTab === 'email') {
forgotPasswordForm.value.phone = ''
forgotPasswordFormRef.value?.clearValidate(['phone'])
}
forgotPasswordFormRef.value?.clearValidate(['code', 'password', 'confirmPassword'])
})
//
const showSendButton = ref<boolean>(true)
const sendState = ref<object>({
isCounting: false,
countdown: 0,
})
//
//
const emailCaptchaState = initCaptchaState('email', 60, 'forgot_email'); //
const phoneCaptchaState = initCaptchaState('phone', 60, 'forgot_phone'); //
//
@ -126,7 +144,6 @@ const { isCounting: phoneIsCounting, countdown: phoneCountdown } = phoneCaptchaS
//
// sendState
const updateSendState = (type: string) => {
if (type === 'email') {
@ -142,143 +159,62 @@ const updateSendState = (type: string) => {
}
}
// activeTabsendState
watch(activeTab, (newTab) => {
if (newTab === 'email' || newTab === 'phone') {
// /sendState
sendState.value = { isCounting: false, countdown: 0 }
} else if (newTab === 'code') {
//
const currentType: string = getStorage('forgotType', 'session') || 'email'
updateSendState(currentType)
}
})
//
const sendCodeApi = async () => {
//
const sendParams = {
email: forgotPasswordForm.value.email,
mobile: forgotPasswordForm.value.phone,
type:'transfer_code'
type: 'transfer_code'
}
return userStore.sendCode(sendParams)
}
//
const handleSendCode = async () => {
//
const type: string = getStorage('forgotType', 'session') || 'email'
// tab
const type = activeTab.value
const receiver = type === 'phone' ? forgotPasswordForm.value.phone : forgotPasswordForm.value.email;
const currentCaptchaState = type === 'phone' ? phoneCaptchaState : emailCaptchaState;
//
//
await sendCaptcha(
type,
receiver,
currentCaptchaState, //
() => sendCodeApi() // Promise
currentCaptchaState,
() => sendCodeApi()
);
//
updateSendState(type)
//
codeSent.value = true
}
//
const handleBack = () => {
//
if (activeTab.value === 'password') {
activeTab.value = 'code'
userText.value = {
...userText.value,
title: '双重验证',
text: '请输入发送的验证码',
account: getStorage('forgot', 'session') || ''
}
//
forgotPasswordForm.value.password = ''
forgotPasswordForm.value.confirmPassword = ''
forgotPasswordFormRef.value?.clearValidate(['password', 'confirmPassword'])
}
// /
else if (activeTab.value === 'code') {
const getForgotType: string = getStorage('forgotType', 'session') || 'email'
activeTab.value = getForgotType
hideTab.value = false
userText.value = {
...userText.value,
title: '恢复密码',
text: '请输入您注册时使用的邮箱或手机号',
account: ''
}
//
forgotPasswordForm.value.code = ''
forgotPasswordFormRef.value?.clearValidate(['code'])
}
// /
else {
activeTab.value = 'email'
forgotPasswordForm.value.email = ''
forgotPasswordForm.value.phone = ''
forgotPasswordFormRef.value?.clearValidate(['email', 'phone'])
router.push('/user/login')
}
}
//
//
const handleForgotPassword = async () => {
if (!forgotPasswordFormRef.value) return
try {
const currentTab = activeTab.value;
const getForgotType: string = getStorage('forgotType', 'session') || 'email'
// 1/
if (currentTab === 'email' || currentTab === 'phone') {
//
await forgotPasswordFormRef.value.validateField(currentTab)
//
setStorage('forgotType', currentTab, 'session')
setStorage('forgot', currentTab === 'email' ? forgotPasswordForm.value.email : forgotPasswordForm.value.phone, 'session')
//
hideTab.value = true
activeTab.value = 'code'
userText.value = {
...userText.value,
title: '双重验证',
text: '请输入发送的验证码',
account: currentTab === 'email' ? forgotPasswordForm.value.email : forgotPasswordForm.value.phone
}
updateSendState(getForgotType)
}
// tab
await forgotPasswordFormRef.value.validateField(activeTab.value)
// 2
else if (currentTab === 'code') {
//
await forgotPasswordFormRef.value.validateField(currentTab)
//
activeTab.value = 'password'
userText.value = {
...userText.value,
title: '设置新密码',
text: '请设置您的新登录密码',
account: getStorage('forgot', 'session') || ''
}
}
await forgotPasswordFormRef.value.validateField('code')
// 3
else if (currentTab === 'password') {
// +
//
await forgotPasswordFormRef.value.validateField(['password', 'confirmPassword'])
//
const forgotParams = {
mobile: forgotPasswordForm.value.phone,
email: forgotPasswordForm.value.email,
mobile: activeTab.value === 'phone' ? forgotPasswordForm.value.phone : undefined,
email: activeTab.value === 'email' ? forgotPasswordForm.value.email : undefined,
code: forgotPasswordForm.value.code,
// login_password1: md5Encrypt(forgotPasswordForm.value.password),
// login_password2: md5Encrypt(forgotPasswordForm.value.confirmPassword),
login_password1: forgotPasswordForm.value.password,
login_password2: forgotPasswordForm.value.confirmPassword,
}
@ -287,8 +223,6 @@ const handleForgotPassword = async () => {
await userStore.forgotPassword(forgotParams)
//
removeStorage('forgotType', 'session')
removeStorage('forgot', 'session')
forgotPasswordForm.value = {
email: '',
countryCode: '+86',
@ -297,12 +231,16 @@ const handleForgotPassword = async () => {
confirmPassword: '',
code: ''
}
}
codeSent.value = false
//
ElMessage.success('密码重置成功,请登录')
router.push('/user/login')
} catch (error) {
console.error('表单提交失败:', error)
}
}
// 4.
//
onUnmounted(() => {
clearCaptchaTimer(emailCaptchaState);
clearCaptchaTimer(phoneCaptchaState);
@ -316,43 +254,5 @@ onUnmounted(() => {
flex-wrap: nowrap;
}
}
.forgot-next {
display: flex;
justify-content: center;
width: 100%;
margin-bottom: 20px;
margin-top: 60px;
div {
position: relative;
height: 4px;
width: 40px;
background: rgb(209 213 219 / var(--tw-bg-opacity, 1));
border-radius: 999px;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 0;
background-color: var(--el-color-primary);
transition: all 0.3s ease-out;
border-radius: 999px;
}
&:nth-child(2) {
margin: 0 10px;
}
}
.active {
&::before {
width: 100%;
}
}
}
}
</style>