diff --git a/common/http.api.js b/common/http.api.js index 24fd3bf..49c2af6 100644 --- a/common/http.api.js +++ b/common/http.api.js @@ -93,6 +93,9 @@ const install = (Vue, vm) => { // 发送消息 let SendMessageApi = (params = {}) => vm.$u.post('api/ChatAI/CreateChat', params); + // 获取图形验证码 + let GetCaptcha = (params = {}) => vm.$u.get('api/Login/GetCaptcha', params); + // 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下 vm.$u.api = { LoginApp, @@ -132,7 +135,8 @@ const install = (Vue, vm) => { getVerifyInfo, getInfoByCard, updateCard, - SendMessageApi + SendMessageApi, + GetCaptcha }; } diff --git a/pages.json b/pages.json index f210c44..4ae8a6e 100644 --- a/pages.json +++ b/pages.json @@ -66,6 +66,14 @@ "navigationStyle": "custom" } }, + { + "path": "pages/home/userInfo/index", + "style": { + "navigationBarTitleText": "个人信息", + "enablePullDownRefresh": false, + "navigationStyle": "custom" + } + }, { "path": "pages/login/login/login", "style": { diff --git a/pages/home/userInfo/index.vue b/pages/home/userInfo/index.vue new file mode 100644 index 0000000..5e29740 --- /dev/null +++ b/pages/home/userInfo/index.vue @@ -0,0 +1,330 @@ + + + + + diff --git a/pages/login/login/index.vue b/pages/login/login/index.vue index b2ce040..28edfca 100644 --- a/pages/login/login/index.vue +++ b/pages/login/login/index.vue @@ -37,40 +37,98 @@ - 手机号 + + 手机号 + {{ errors.phone }} - 密码 + 密码 + {{ + errors.password + }} - 验证码 + + + 图形验证码 + + + + + + + {{ + errors.captcha + }} + + + + + + 验证码 - 获取验证码 + {{ codeText }} + {{ errors.code }} @@ -85,22 +143,196 @@ export default { data() { return { - isTeacher: true, // 是否是教师 + isTeacher: false, // 是否是教师 phone: "", password: "", code: "", + captcha: "", // 图形验证码 + captchaId: "", // 图形验证码ID + captchaUrl: "", // 图形验证码URL,实际使用时需替换 loginType: "code", // 默认验证码登录,与图片一致 + codeText: "获取验证码", + countdown: 60, + timer: null, + errors: { + phone: "", + password: "", + code: "", + captcha: "", + }, }; }, + mounted() { + this.refreshCaptcha(); + }, + beforeDestroy() { + if (this.timer) { + clearInterval(this.timer); + } + }, methods: { switchLoginType(type) { this.loginType = type; + this.clearErrors(); }, + + // 刷新图形验证码 + refreshCaptcha() { + // 获取图形验证码 + this.$u.api.GetCaptcha().then((res) => { + console.log("获取图形验证码...", res); + this.captchaId = res.captchaId; + this.captchaUrl = "data:image/png;base64," + res.imageBase64; + }); + }, + + // 获取短信验证码 getCode() { - // 获取验证码 + if (!this.validatePhone()) { + return; + } + + if (this.loginType === "code" && !this.validateCaptcha()) { + return; + } + + if (this.codeText !== "获取验证码") { + return; + } + + // 模拟发送验证码 + this.startCountdown(); + + // 实际应用中应该调用API发送验证码 + uni.showToast({ + title: "验证码已发送", + icon: "success", + }); }, + + // 开始倒计时 + startCountdown() { + this.countdown = 60; + this.codeText = `${this.countdown}秒后重新获取`; + this.timer = setInterval(() => { + this.countdown--; + this.codeText = `${this.countdown}秒后重新获取`; + if (this.countdown <= 0) { + clearInterval(this.timer); + this.codeText = "获取验证码"; + } + }, 1000); + }, + + // 校验手机号 + validatePhone() { + if (!this.phone) { + this.errors.phone = "请输入手机号"; + return false; + } + + if (!/^1[3-9]\d{9}$/.test(this.phone)) { + this.errors.phone = "手机号格式不正确"; + return false; + } + + this.errors.phone = ""; + return true; + }, + + // 校验密码 + validatePassword() { + if (!this.password) { + this.errors.password = "请输入密码"; + return false; + } + + // if (this.password.length < 6) { + // this.errors.password = "密码不能少于6位"; + // return false; + // } + + this.errors.password = ""; + return true; + }, + + // 校验图形验证码 + validateCaptcha() { + if (!this.captcha) { + this.errors.captcha = "请输入图形验证码"; + return false; + } + + // if (this.captcha.length < 4) { + // this.errors.captcha = "图形验证码错误请重新输入"; + // return false; + // } + + // 实际应用中应该验证图形验证码是否正确 + this.errors.captcha = ""; + return true; + }, + + // 校验短信验证码 + validateCode() { + if (!this.code) { + this.errors.code = "请输入验证码"; + return false; + } + + if (this.code.length < 4) { + this.errors.code = "验证码错误请重新输入"; + return false; + } + + this.errors.code = ""; + return true; + }, + + // 清除所有错误提示 + clearErrors() { + this.errors = { + phone: "", + password: "", + code: "", + captcha: "", + }; + }, + + // 登录 login() { - // 登录 + let isValid = true; + + // 校验手机号 + if (!this.validatePhone()) { + isValid = false; + } + + // 根据登录类型校验其他字段 + if (this.loginType === "psd") { + if (!this.validatePassword()) { + isValid = false; + } + } else { + if (!this.validateCaptcha()) { + isValid = false; + } + + if (!this.validateCode()) { + isValid = false; + } + } + + if (!isValid) { + return; + } + + // 校验通过,执行登录 + uni.showLoading({ + title: "登录中...", + }); + + }, }, }; @@ -116,7 +348,7 @@ export default { flex-direction: column; box-sizing: border-box; - background-image: url(/static//common/images/images_bg.png); + background-image: url(/static/common/images/images_bg.png); background-repeat: no-repeat; background-size: 100% 100%; background-position: 50%; @@ -130,7 +362,7 @@ export default { .logo-container { display: flex; align-items: center; - margin-bottom: 20rpx; + margin-bottom: 32rpx; .logo-icon { width: 48rpx; @@ -217,23 +449,18 @@ export default { .form-label { display: block; position: relative; - padding-left: 30rpx; + // padding-left: 30rpx; font-family: PingFang SC; font-size: 28rpx; color: #333333; margin-bottom: 16rpx; + } - &::before { - content: ""; - position: absolute; - left: 0; - top: 50%; - transform: translateY(-50%); - width: 20rpx; - height: 20rpx; - border: 2rpx solid #4370fe; - border-radius: 4rpx; - } + .image_icon { + width: 28rpx; + height: 28rpx; + vertical-align: text-top; + margin-right: 16rpx; } &:nth-child(2) { @@ -264,13 +491,38 @@ export default { right: 0; top: 50%; transform: translateY(-50%); + width: 220rpx; height: 60rpx; line-height: 60rpx; - padding: 0 30rpx; + padding-left: 30rpx; color: #4370fe; font-size: 28rpx; - border-left: 1px solid #557bf9; + border-left: 1px solid #b7c1ff; } + + .captcha-img { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); + height: 60rpx; + width: 220rpx; + padding-left: 30rpx; + border-left: 1px solid #b7c1ff; + + image { + width: 80%; + height: 100%; + } + } + } + + .error-tip { + display: block; + font-size: 24rpx; + color: #FF6481; + margin-top: 10rpx; + padding-left: 10rpx; } } } diff --git a/static/common/images/icon_password.png b/static/common/images/icon_password.png new file mode 100644 index 0000000..ab913f3 Binary files /dev/null and b/static/common/images/icon_password.png differ diff --git a/static/common/images/icon_phoneNumber.png b/static/common/images/icon_phoneNumber.png new file mode 100644 index 0000000..b55bcd0 Binary files /dev/null and b/static/common/images/icon_phoneNumber.png differ diff --git a/static/common/images/icon_verificationCode.png b/static/common/images/icon_verificationCode.png new file mode 100644 index 0000000..2145560 Binary files /dev/null and b/static/common/images/icon_verificationCode.png differ diff --git a/static/common/images/images_bg_dialog.png b/static/common/images/images_bg_dialog.png new file mode 100644 index 0000000..abb8e81 Binary files /dev/null and b/static/common/images/images_bg_dialog.png differ