From ce5e84197b43dec8c01717b116cb77535ad3c91e Mon Sep 17 00:00:00 2001 From: zhangwei <1504152376@qq.com> Date: 星期三, 25 六月 2025 16:21:42 +0800 Subject: [PATCH] '登录注册' --- src/views/register/index.vue | 433 +++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 299 insertions(+), 134 deletions(-) diff --git a/src/views/register/index.vue b/src/views/register/index.vue index d92a8dc..ba4182c 100644 --- a/src/views/register/index.vue +++ b/src/views/register/index.vue @@ -18,18 +18,22 @@ <el-form ref="ruleFormRef" style="max-width: 600px" - :model="ruleForm" - :rules="rules" + :model="state.ruleForm" + :rules="state.rules" label-width="auto" + size="large" > - <el-form-item label="娉ㄥ唽韬唤" prop="resource"> - <el-radio-group v-model="ruleForm.resource"> - <el-radio value="Sponsorship">渚涘簲鍟�</el-radio> - <el-radio value="Venue">浠g悊鏈烘瀯</el-radio> - <el-radio value="cgr">閲囪喘浜�</el-radio> + <el-form-item label="娉ㄥ唽韬唤" prop="exRoleCode"> + <el-radio-group v-model="state.ruleForm.exRoleCode"> + <el-radio + v-for="item in state.roleList" + :key="item.id" + :value="item.code" + >{{ item.name }}</el-radio + > </el-radio-group> </el-form-item> - <el-form-item label="浼佷笟鍚嶇О" prop="name"> + <!-- <el-form-item label="浼佷笟鍚嶇О" prop="name"> <el-input v-model="ruleForm.name" placeholder="璇疯緭鍏ヨ惀涓氭墽鐓т笂鐨勪紒涓氬悕绉�" @@ -37,8 +41,20 @@ </el-form-item> <el-form-item label="鐢ㄦ埛鍚�" prop="region"> <el-input v-model="ruleForm.region" placeholder="璇疯緭鍏ョ敤鎴峰悕" /> + </el-form-item> --> + <el-form-item label="濮撳悕" prop="nickName"> + <el-input + v-model="state.ruleForm.nickName" + placeholder="璇疯緭鍏ュ鍚�" + /> </el-form-item> - <el-form-item label="鐧诲綍瀵嗙爜" prop="password"> + <el-form-item label="鎵嬫満鍙风爜" prop="phone"> + <el-input + v-model="state.ruleForm.phone" + placeholder="璇疯緭鍏ユ偍鐨勬墜鏈哄彿鐮�" + /> + </el-form-item> + <!-- <el-form-item label="鐧诲綍瀵嗙爜" prop="password"> <el-input v-model="ruleForm.password" placeholder="8-20浣嶆暟瀛�+澶у皬鍐欏瓧姣�+鐗规畩瀛楃鐨勭粍鍚�" @@ -55,48 +71,74 @@ v-model="ruleForm.repassword" placeholder="璇疯緭鍏ヨ仈绯讳汉濮撳悕" /> - </el-form-item> - <el-form-item label="閭" prop="repassword"> + </el-form-item> --> + <el-form-item label="閭" prop="email"> <el-input - v-model="ruleForm.repassword" + v-model="state.ruleForm.email" placeholder="璇疯緭鍏ヨ仈绯婚偖绠�" /> </el-form-item> - <el-form-item label="鎵嬫満鍙风爜" prop="repassword"> - <el-input - v-model="ruleForm.repassword" - placeholder="璇疯緭鍏ユ偍鐨勬墜鏈哄彿鐮�" - /> + <el-form-item label="楠岃瘉鐮�" class="login-animation3" prop="code"> + <el-col :span="15"> + <el-input + ref="codeRef" + v-model="state.ruleForm.code" + text + maxlength="4" + placeholder="璇疯緭鍏ラ獙璇佺爜" + clearable + autocomplete="off" + /> + </el-col> + <el-col :span="1" /> + <el-col :span="8"> + <div + :class="[ + state.expirySeconds > 0 + ? 'login-content-code' + : 'login-content-code-expired' + ]" + @click="getCaptcha" + > + <img + class="login-content-code-img" + width="130px" + height="38px" + :src="state.captchaImage" + style="cursor: pointer" + /> + </div> + </el-col> </el-form-item> - <el-form-item label="鎵嬫満鍙风爜" prop="repassword"> + <el-form-item prop="phoneVCode" label="鎵嬫満楠岃瘉鐮�"> <el-input - v-model="ruleForm.repassword" - placeholder="璇疯緭鍏ユ偍鐨勬墜鏈哄彿鐮�" - /> - </el-form-item> - <el-form-item prop="validationCode" label="鎵嬫満楠岃瘉鐮�"> - <el-input - v-model.number="ruleForm.validationCode" + v-model.number="state.ruleForm.phoneVCode" class="form-input" placeholder="璇疯緭鍏ラ獙璇佺爜" > <template #suffix> - <span id="suffix-span"> + <span v-if="state.phoneSeconds == 0" id="suffix-span"> <span id="suffix-span-2" ref="spanRef" - @click="sendValidationCode(ruleForm.repassword)" + @click="sendValidationCode(state.ruleForm.phone)" > - {{ isSendValidationCode }} + 鑾峰彇楠岃瘉鐮� + </span> + </span> + <span v-else id="suffix-span"> + <span id="suffix-span-2" ref="spanRef"> + {{ state.phoneSeconds }}绉掑悗閲嶆柊鑾峰彇 </span> </span> </template> </el-input> </el-form-item> - <el-form-item prop="repassword" label=" "> - <el-checkbox value="Online activities" name="type"> - 鎴戝凡闃呰骞跺悓鎰� 銆婇潪鏀块噰鎷涙爣閲囪喘浜ゆ槗骞冲彴鐢ㄦ埛鍗忚銆� - </el-checkbox> + <el-form-item label=" "> + <el-checkbox v-model="checked1" name="type" />鎴戝凡闃呰骞跺悓鎰� + <el-link type="primary" :underline="false" + >銆婇潪鏀块噰鎷涙爣閲囪喘浜ゆ槗骞冲彴鐢ㄦ埛鍗忚銆�</el-link + > </el-form-item> <el-form-item label=" "> <el-button type="primary" @click="submitForm(ruleFormRef)"> @@ -104,7 +146,8 @@ </el-button> </el-form-item> <el-form-item label=" "> - <span>宸叉湁璐﹀彿锛熺珛鍗崇櫥褰�</span> + <span>宸叉湁璐﹀彿锛�</span> + <el-link type="primary" :underline="false">绔嬪嵆鐧诲綍</el-link> </el-form-item> </el-form> </div> @@ -114,120 +157,197 @@ </template> <script lang="ts" setup> -import { reactive, ref } from "vue"; +import { + reactive, + computed, + ref, + onMounted, + defineAsyncComponent, + onUnmounted, + watch +} from "vue"; import type { FormInstance, FormRules } from "element-plus"; - -interface RuleForm { - name: string; - region: string; - count: string; - password: string; - repassword: string; - validationCode: string; - date1: string; - date2: string; - delivery: boolean; - location: string; - type: string[]; - resource: string; - desc: string; -} - -const ruleFormRef = ref<FormInstance>(); -const ruleForm = reactive<RuleForm>({ - name: "", - region: "", - password: "", - validationCode: "", - repassword: "", - count: "", - date1: "", - date2: "", - delivery: false, - location: "", - type: [], - resource: "", - desc: "" +import { + captcha, + phoneNumberCode, + register, + exRole +} from "@/api/register/index.ts"; +import { useRoute, useRouter } from "vue-router"; +import { message } from "@/utils/message"; +defineOptions({ + name: "Register" }); + +const route = useRoute(); +const router = useRouter(); +const checked1 = ref(false); +const state = reactive({ + isShowPassword: false, + ruleForm: { + account: "", + nickName: "", + phone: "", + phoneVCode: "", + // tenantId: props.tenantInfo.id, + code: "", + codeId: 0, + email: "", + exRoleCode: "" + }, + rules: { + phoneVCode: [ + { + required: true, + message: "璇疯緭鍏ユ墜鏈洪獙璇佺爜", + trigger: "blur" + } + ], + nickName: [ + { + required: true, + message: "璇疯緭鍏ュ鍚�", + trigger: "blur" + } + ], + phone: [ + { + required: true, + message: "璇疯緭鍏ユ偍鐨勬墜鏈哄彿鐮�", + trigger: "blur" + } + ], + exRoleCode: [ + { + required: true, + message: "璇烽�夋嫨瑙掕壊", + trigger: "blur" + } + ] + // code: [{ required: true, message: t('message.account.placeholder4'), trigger: 'blur' }], + }, + loading: { + signIn: false + }, + captchaImage: "", + rotateVerifyVisible: false, + // rotateVerifyImg: verifyImg, + // rotateVerifyImg: themeConfig.value.logoUrl, + secondVerEnabled: false, + // captchaEnabled: false, + isPassRotate: false, + capsLockVisible: false, + hideTenantForLogin: false, + expirySeconds: 60, // 楠岃瘉鐮佽繃鏈熸椂闂� + phoneSeconds: 0, // 鎵嬫満楠岃瘉鐮佸�掕鏃� + roleList: [] +}); +// 楠岃瘉鐮佽繃鏈熻鏃跺櫒 +let timer: any = null; +let phonetimer: any = null; + +// 椤甸潰鍒濆鍖� +onMounted(async () => { + // 鑻RL甯︽湁Token鍙傛暟锛堢涓夋柟鐧诲綍锛� + const accessToken = route.query.token; + // if (accessToken) await saveTokenAndInitRoutes(accessToken); + // watch( + // () => themeConfig.value.isLoaded, + // isLoaded => { + // if (isLoaded) { + // 鑾峰彇鐧诲綍閰嶇疆 + // state.hideTenantForLogin = themeConfig.value.hideTenantForLogin ?? true; + // state.secondVerEnabled = themeConfig.value.secondVer ?? true; + // state.captchaEnabled = themeConfig.value.captcha ?? true; + + // 鑾峰彇楠岃瘉鐮� + getCaptcha(); + exRole().then(res => { + state.roleList = res.result; + }); + // 娉ㄥ唽楠岃瘉鐮佽繃鏈熻鏃跺櫒 + // if (state.captchaEnabled) { + timer = setInterval(() => { + if (state.expirySeconds > 0) state.expirySeconds -= 1; + }, 1000); + + // } + // } + // }, + // { immediate: true } + // ); + + // 妫�娴嬪ぇ灏忓啓鎸夐敭/CapsLK + document.addEventListener("keyup", handleKeyPress); +}); + +// 椤甸潰鍗歌浇 +onUnmounted(() => { + // 閿�姣侀獙璇佺爜杩囨湡璁℃椂鍣� + clearInterval(timer); + timer = null; + clearInterval(phonetimer); + phonetimer = null; + + document.removeEventListener("keyup", handleKeyPress); +}); + +// 妫�娴嬪ぇ灏忓啓鎸夐敭 +const handleKeyPress = (e: KeyboardEvent) => { + if (e.getModifierState != undefined) + state.capsLockVisible = e.getModifierState("CapsLock"); +}; +// 鑾峰彇楠岃瘉鐮� +const getCaptcha = async () => { + // if (!state.captchaEnabled) return; + + state.ruleForm.code = ""; + const res = await captcha(); + console.log(res); + + state.captchaImage = "data:text/html;base64," + res.result?.img; + state.expirySeconds = res.result?.expirySeconds; + state.ruleForm.codeId = res.result?.id; +}; +const ruleFormRef = ref<FormInstance>(); const locationOptions = ["Home", "Company", "School"]; - -const rules = reactive<FormRules<RuleForm>>({ - name: [ - { required: true, message: "Please input Activity name", trigger: "blur" }, - { min: 3, max: 5, message: "Length should be 3 to 5", trigger: "blur" } - ], - region: [ - { - required: true, - message: "Please select Activity zone", - trigger: "change" - } - ], - count: [ - { - required: true, - message: "Please select Activity count", - trigger: "change" - } - ], - date1: [ - { - type: "date", - required: true, - message: "Please pick a date", - trigger: "change" - } - ], - date2: [ - { - type: "date", - required: true, - message: "Please pick a time", - trigger: "change" - } - ], - location: [ - { - required: true, - message: "Please select a location", - trigger: "change" - } - ], - type: [ - { - type: "array", - required: true, - message: "Please select at least one activity type", - trigger: "change" - } - ], - resource: [ - { - required: true, - message: "Please select activity resource", - trigger: "change" - } - ], - desc: [ - { required: true, message: "Please input activity form", trigger: "blur" } - ] -}); // 楠岃瘉鐮佸尯鍩熸枃瀛楄鏄� const spanRef = ref(); -const isSendValidationCode = ref<string>("鑾峰彇楠岃瘉鐮�"); const submitForm = async (formEl: FormInstance | undefined) => { if (!formEl) return; await formEl.validate((valid, fields) => { if (valid) { - console.log("submit!"); - } else { - console.log("error submit!", fields); - } + state.ruleForm.account = state.ruleForm.phone; + register(state.ruleForm).then(res => { + if (res?.code == 200) { + router.replace("/RegisterSucess"); + return message("娉ㄥ唽鎴愬姛锛�", { type: "success" }); + } else { + return message(res?.message, { type: "warning" }); + } + }); + } else if (!checked1.value) + return message("璇峰嬀閫夌敤鎴峰崗璁�", { type: "warning" }); }); }; -const sendValidationCode = () => {}; +const sendValidationCode = async () => { + if (!state.ruleForm.phone) { + return message("璇峰厛杈撳叆鎵嬫満鍙�", { type: "warning" }); + } + if (!state.ruleForm.code) { + return message("璇峰厛杈撳叆楠岃瘉鐮�", { type: "warning" }); + } + const res = await phoneNumberCode(state.ruleForm); + if (res?.code != 200) { + return message(res?.message, { type: "warning" }); + } + state.phoneSeconds = 60; + phonetimer = setInterval(() => { + if (state.phoneSeconds > 0) state.phoneSeconds -= 1; + }, 1000); +}; const resetForm = (formEl: FormInstance | undefined) => { if (!formEl) return; @@ -296,4 +416,49 @@ } } } +.el-form-item { + align-items: center; +} +#suffix-span { + cursor: pointer; +} +.login-content-code { + display: flex; + align-items: center; + justify-content: space-around; + position: relative; + + .login-content-code-img { + width: 100%; + height: 40px; + line-height: 40px; + background-color: #ffffff; + border: 1px solid rgb(220, 223, 230); + cursor: pointer; + transition: all ease 0.2s; + border-radius: 4px; + user-select: none; + + &:hover { + border-color: #c0c4cc; + transition: all ease 0.2s; + } + } +} + +.login-content-code-expired { + @extend .login-content-code; + &::before { + content: "楠岃瘉鐮佸凡杩囨湡"; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 4px; + background-color: rgba(0, 0, 0, 0.5); + color: #ffffff; + text-align: center; + } +} </style> -- Gitblit v1.9.1