运动员新增短信验证

This commit is contained in:
马梓彭 2026-03-31 17:49:42 +08:00
parent 6186c7723c
commit 07e147a390

View File

@ -160,13 +160,21 @@
<!-- 联系电话 -->
<el-form-item label="联系电话" prop="mobile">
<el-input v-model="formData.mobile" placeholder="请输入联系电话" class="fee-input">
<!-- <template #append>
<el-button type="primary" @click="onSendCode" >
{{ isSendCode ? '已发送' : '发送验证码' }}
</el-button>
</template> -->
</el-input>
<el-input v-model="formData.mobile" placeholder="请输入联系电话" style="width: 360px;"></el-input>
<el-button
v-if="needVerificationCode"
type="text"
@click="onSendCode"
style="margin-left: 8px;"
:disabled="sending || !isPhoneValid">
{{ sending ? `${sendTimer}s` : '获取验证码' }}
</el-button>
<el-tag v-else type="info" style="margin-left: 8px;">手机号未变更</el-tag>
</el-form-item>
<!-- 验证码 -->
<el-form-item label="验证码" prop="verificationCode" v-if="needVerificationCode">
<el-input v-model="formData.verificationCode" placeholder="请输入验证码" maxlength="6" style="width: 360px;"></el-input>
</el-form-item>
</el-form>
@ -181,14 +189,14 @@
</template>
<script setup name="sysMenu">
import { defineAsyncComponent, ref, reactive, nextTick } from 'vue';
import { defineAsyncComponent, ref, reactive, nextTick, computed } from 'vue';
import { ElMessage, ElForm } from 'element-plus';
import SysMenuApi from '/@/api/SysMenuApi';
import { auths } from '/@/utils/authFunction';
import ProTable from '/@/components/ProTable/index.vue';
import { teamPageGet, teamDetailGet, teamAddPost, teamDeleteDelete, teamUpdatePut } from '/@/api/match/unitUser';
import { appuserAthletePageGet, appuserAthleteAddPost, appuserAthleteUpdatePut, appuserLeaderPageGet, appuserCoachPageGet } from '/@/api/match/appuser';
import { commonOcrRecognizeIdcardPost, commonOcrRecognizePassportPost } from '/@/api/match/common';
import { commonOcrRecognizeIdcardPost, commonOcrRecognizePassportPost, commonSmsSendVerificationCodePost } from '/@/api/match/common';
// 定义表单引用类型
const formRef = ref();
const activeTab = ref('first')
@ -200,6 +208,7 @@ const getDefaultFormData = () => ({
idCardImageUrl: '',
birthDate: '',
mobile: '',
verificationCode: '',
});
const statusList = ref({
1: 'info',
@ -216,25 +225,46 @@ const initParam = ref({
refresh: true,
})
const formRules = ref({
name: [
{ required: true, message: '请输入运动员姓名', trigger: 'blur' }
],
idCardNumber: [
{ required: true, message: '请输入身份证号', trigger: 'change' }
],
gender: [
{ required: true, message: '请选择性别', trigger: 'change' }
],
mobile: [
{ required: true, message: '请输入联系电话', trigger: 'blur' }
],
idCardImageUrl: [
{ required: true, message: '请上传身份证照片', trigger: 'change' }
],
birthDate: [
{ required: true, message: '请选择出生日期', trigger: 'change' }
],
const formRules = computed(() => {
const baseRules = {
name: [
{ required: true, message: '请输入运动员姓名', trigger: 'blur' }
],
idCardNumber: [
{ required: true, message: '请输入身份证号', trigger: 'change' }
],
gender: [
{ required: true, message: '请选择性别', trigger: 'change' }
],
mobile: [
{ required: true, message: '请输入联系电话', trigger: 'blur' },
{
validator: (rule, value, cb) => {
const reg = /^1[3-9]\d{9}$/;
if (!value) return cb(new Error('请输入联系电话'));
if (!reg.test(value)) return cb(new Error('请输入正确的手机号'));
cb();
},
trigger: 'blur'
}
],
idCardImageUrl: [
{ required: true, message: '请上传身份证照片', trigger: 'change' }
],
birthDate: [
{ required: true, message: '请选择出生日期', trigger: 'change' }
],
};
// 只在需要验证码时添加验证码验证规则
if (needVerificationCode.value) {
baseRules.verificationCode = [
{ required: true, message: '请输入验证码', trigger: 'blur' },
{ len: 6, message: '验证码长度为6位', trigger: 'blur' }
];
}
return baseRules;
});
const columns = ref([
@ -272,6 +302,24 @@ const isShowDialog = ref(false);
const dialogTitle = ref('新增');
const tableRefteam = ref(null);
// 验证码相关
const sending = ref(false);
const sendTimer = ref(0);
const sendInterval = ref(null);
const originalMobile = ref('');
const isPhoneValid = computed(() => {
const reg = /^1[3-9]\d{9}$/;
return reg.test(formData.value.mobile);
});
const isMobileChanged = computed(() => {
if (!formData.value.id) return true;
return formData.value.mobile !== originalMobile.value;
});
const needVerificationCode = computed(() => {
return isMobileChanged.value;
});
// 团队新增弹窗相关
const isShowTeamDialog = ref(false);
const teamFormRef = ref();
@ -475,9 +523,21 @@ const onTeamSubmit = () => {
};
const onOpenMenu = (row) => {
// 重置验证码相关状态
if (sendInterval.value) {
clearInterval(sendInterval.value);
sendInterval.value = null;
}
sending.value = false;
sendTimer.value = 0;
dialogTitle.value = row ? '编辑' : '新增';
formData.value = getDefaultFormData();
ocrType.value = 'idcard';
// 保存原始手机号
originalMobile.value = '';
if (row && typeof row === 'object') {
formData.value = {
...getDefaultFormData(),
@ -489,6 +549,7 @@ const onOpenMenu = (row) => {
birthDate: row.birthDate ?? '',
mobile: row.mobile ?? row.mobile ?? '',
};
originalMobile.value = row.mobile ?? row.mobile ?? '';
}
isShowDialog.value = true;
};
@ -528,21 +589,37 @@ const onDeleteTeam = async (id) => {
// const isSendCode = ref(false)
// const timer = ref(null)
// const second = ref(60)
// const onSendCode = async () => {
// if (second.value != 60) return ElMessage.error(`请${second.value}秒重新发送`)
// timer.value = setInterval(() => {
// if (second.value > 0) {
// second.value--
// } else {
// clearInterval(timer.value)
// isSendCode.value = false
// second.value = 60
// }
// }, 1000)
// }
const onSendCode = async () => {
if (!isPhoneValid.value) {
ElMessage.error('请输入正确的手机号');
return;
}
if (!isMobileChanged.value) {
ElMessage.warning('手机号未变更,无需获取验证码');
return;
}
sending.value = true;
sendTimer.value = 60;
try {
const res = await commonSmsSendVerificationCodePost({ phone: formData.value.mobile });
if (res.succeeded) {
ElMessage.success('验证码已发送');
sendInterval.value = setInterval(() => {
sendTimer.value -= 1;
if (sendTimer.value <= 0) {
clearInterval(sendInterval.value);
sending.value = false;
}
}, 1000);
} else {
ElMessage.error(res.errors || res.msg || '发送验证码失败');
sending.value = false;
}
} catch (err) {
sending.value = false;
ElMessage.error(err && err.message ? err.message : '发送验证码失败');
}
};
const handleAvatarSuccess = async (response,
uploadFile) => {
@ -601,6 +678,13 @@ const onSubmit = () => {
ElMessage.success(dialogTitle.value + '成功');
isShowDialog.value = false;
initParam.value.refresh = !initParam.value.refresh;
// 清理计时器
if (sendInterval.value) {
clearInterval(sendInterval.value);
sendInterval.value = null;
}
sending.value = false;
sendTimer.value = 0;
} else {
ElMessage.error(res.errors || res.msg || dialogTitle.value + '失败');
}
@ -613,6 +697,13 @@ const onSubmit = () => {
// 取消
const onCancel = () => {
// 清理计时器
if (sendInterval.value) {
clearInterval(sendInterval.value);
sendInterval.value = null;
}
sending.value = false;
sendTimer.value = 0;
isShowDialog.value = false;
};
</script>