2
This commit is contained in:
@@ -63,29 +63,46 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 手机号 -->
|
||||
<!-- 邮箱 -->
|
||||
<view class="input-group">
|
||||
<view class="input-container" :class="{ focused: phoneFocused, filled: form.phone }">
|
||||
<view class="input-container" :class="{ focused: emailFocused, filled: form.email }">
|
||||
<view class="input-icon">
|
||||
<svg viewBox="0 0 24 24" class="icon">
|
||||
<path d="M6.62,10.79C8.06,13.62 10.38,15.94 13.21,17.38L15.41,15.18C15.69,14.9 16.08,14.82 16.43,14.93C17.55,15.3 18.75,15.5 20,15.5A1,1 0 0,1 21,16.5V20A1,1 0 0,1 20,21A17,17 0 0,1 3,4A1,1 0 0,1 4,3H7.5A1,1 0 0,1 8.5,4C8.5,5.25 8.7,6.45 9.07,7.57C9.18,7.92 9.1,8.31 8.82,8.59L6.62,10.79Z"/>
|
||||
<path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-1 4l-7 4-7-4V6l7 4 7-4v2z"/>
|
||||
</svg>
|
||||
</view>
|
||||
<input
|
||||
class="input-field"
|
||||
v-model.trim="form.phone"
|
||||
type="number"
|
||||
placeholder="请输入手机号"
|
||||
maxlength="11"
|
||||
@focus="phoneFocused = true"
|
||||
@blur="phoneFocused = false"
|
||||
v-model.trim="form.email"
|
||||
type="text"
|
||||
placeholder="请输入邮箱地址"
|
||||
@focus="emailFocused = true"
|
||||
@blur="emailFocused = false"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 验证码 -->
|
||||
<view class="input-group">
|
||||
<view class="input-container" :class="{ focused: codeFocused, filled: form.code }">
|
||||
<view class="input-icon">
|
||||
<svg viewBox="0 0 24 24" class="icon">
|
||||
<path d="M3 10h18v2H3v-2zm0 6h12v2H3v-2zM3 6h18v2H3V6z"/>
|
||||
</svg>
|
||||
</view>
|
||||
<input
|
||||
class="input-field"
|
||||
v-model.trim="form.code"
|
||||
type="number" maxlength="6"
|
||||
placeholder="请输入6位验证码"
|
||||
@focus="codeFocused = true"
|
||||
@blur="codeFocused = false"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 密码 -->
|
||||
<view class="input-group">
|
||||
<view class="input-container" :class="{ focused: passwordFocused, filled: form.password }">
|
||||
<view class="input-container" :class="{ focused: pwdFocused, filled: form.password }">
|
||||
<view class="input-icon">
|
||||
<svg viewBox="0 0 24 24" class="icon">
|
||||
<path d="M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z"/>
|
||||
@@ -95,30 +112,16 @@
|
||||
class="input-field"
|
||||
v-model.trim="form.password"
|
||||
password
|
||||
placeholder="请输入密码(至少6位)"
|
||||
@focus="passwordFocused = true"
|
||||
@blur="passwordFocused = false"
|
||||
placeholder="请设置登录密码(至少6位)"
|
||||
@focus="pwdFocused = true"
|
||||
@blur="pwdFocused = false"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 确认密码 -->
|
||||
<!-- 发送验证码按钮 -->
|
||||
<view class="input-group">
|
||||
<view class="input-container" :class="{ focused: confirmPasswordFocused, filled: form.confirmPassword }">
|
||||
<view class="input-icon">
|
||||
<svg viewBox="0 0 24 24" class="icon">
|
||||
<path d="M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z"/>
|
||||
</svg>
|
||||
</view>
|
||||
<input
|
||||
class="input-field"
|
||||
v-model.trim="form.confirmPassword"
|
||||
password
|
||||
placeholder="请再次输入密码"
|
||||
@focus="confirmPasswordFocused = true"
|
||||
@blur="confirmPasswordFocused = false"
|
||||
/>
|
||||
</view>
|
||||
<button class="login-button" :disabled="countdown>0 || sending" @click="sendCode">{{ btnText }}</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -148,39 +151,70 @@ export default {
|
||||
form: {
|
||||
shopName: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
password: '',
|
||||
confirmPassword: ''
|
||||
email: '',
|
||||
code: '',
|
||||
password: ''
|
||||
},
|
||||
shopNameFocused: false,
|
||||
nameFocused: false,
|
||||
phoneFocused: false,
|
||||
passwordFocused: false,
|
||||
confirmPasswordFocused: false
|
||||
emailFocused: false,
|
||||
codeFocused: false,
|
||||
pwdFocused: false,
|
||||
countdown: 0,
|
||||
timer: null,
|
||||
sending: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
btnText(){
|
||||
if (this.countdown > 0) return `${this.countdown}s`
|
||||
if (this.sending) return '发送中...'
|
||||
return '获取验证码'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
validate() {
|
||||
const phone = String(this.form.phone || '').trim();
|
||||
const ok = /^1[3-9]\d{9}$/.test(phone);
|
||||
if (!ok) { uni.showToast({ title: '请输入正确的手机号', icon: 'none' }); return false }
|
||||
if (!this.form.password) { uni.showToast({ title: '请输入密码', icon: 'none' }); return false }
|
||||
if (this.form.password.length < 6) { uni.showToast({ title: '密码至少6位', icon: 'none' }); return false }
|
||||
if (!this.form.confirmPassword) { uni.showToast({ title: '请确认密码', icon: 'none' }); return false }
|
||||
if (this.form.password !== this.form.confirmPassword) { uni.showToast({ title: '两次密码不一致', icon: 'none' }); return false }
|
||||
const email = String(this.form.email || '').trim();
|
||||
const ok = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/.test(email);
|
||||
if (!ok) { uni.showToast({ title: '请输入正确的邮箱地址', icon: 'none' }); return false }
|
||||
if (!/^\d{6}$/.test(String(this.form.code||'').trim())) { uni.showToast({ title: '验证码格式不正确', icon: 'none' }); return false }
|
||||
if (String(this.form.password||'').length < 6) { uni.showToast({ title: '密码至少6位', icon: 'none' }); return false }
|
||||
return true;
|
||||
},
|
||||
|
||||
startCountdown(sec){
|
||||
this.countdown = sec
|
||||
if (this.timer) clearInterval(this.timer)
|
||||
this.timer = setInterval(() => {
|
||||
if (this.countdown<=1) { clearInterval(this.timer); this.timer=null; this.countdown=0; return }
|
||||
this.countdown--
|
||||
}, 1000)
|
||||
},
|
||||
async sendCode(){
|
||||
if (this.sending || this.countdown>0) return
|
||||
const e = String(this.form.email||'').trim()
|
||||
const ok = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/.test(e)
|
||||
if (!ok) return uni.showToast({ title: '请输入正确的邮箱地址', icon: 'none' })
|
||||
this.sending = true
|
||||
try {
|
||||
const res = await post('/api/auth/email/send', { email: e, scene: 'login' })
|
||||
const cd = Number(res && res.cooldownSec || 60)
|
||||
this.startCountdown(cd)
|
||||
uni.showToast({ title: '验证码已发送', icon: 'none' })
|
||||
} catch(e) {
|
||||
const msg = (e && e.message) || '发送失败'
|
||||
uni.showToast({ title: msg, icon: 'none' })
|
||||
} finally { this.sending=false }
|
||||
},
|
||||
async onRegister() {
|
||||
if (!this.validate()) return;
|
||||
const phone = String(this.form.phone||'').trim();
|
||||
const email = String(this.form.email||'').trim();
|
||||
const name = String(this.form.name||'').trim();
|
||||
const password = String(this.form.password||'');
|
||||
try {
|
||||
const data = await post('/api/auth/register', { phone, name: name || undefined, password });
|
||||
const data = await post('/api/auth/email/register', { email, code: String(this.form.code||'').trim(), name, password: String(this.form.password||'') });
|
||||
if (data && data.token) {
|
||||
uni.setStorageSync('TOKEN', data.token)
|
||||
if (data.user && data.user.phone) uni.setStorageSync('USER_MOBILE', data.user.phone)
|
||||
if (data.user && data.user.email) uni.setStorageSync('USER_EMAIL', data.user.email)
|
||||
if (name) try { uni.setStorageSync('USER_NAME', name) } catch(_) {}
|
||||
uni.showToast({ title: '注册成功', icon: 'none' })
|
||||
setTimeout(() => { uni.reLaunch({ url: '/pages/index/index' }) }, 300)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user