Files
yunzerwebsiteallinone/uniapp/pages/onboarding/register.vue
T
2026-11-11 16:58:30 +08:00

151 lines
4.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="page">
<view class="hero">
<text class="eyebrow">YUNZE WORKSPACE</text>
<text class="title">设置登录密码</text>
<text class="desc">手机号 {{ mobileMask || '已验证' }} 尚未注册,设置密码后即可使用工作台</text>
</view>
<view class="card">
<view class="field">
<text class="label">登录密码</text>
<input v-model="password" class="input" type="password" placeholder="至少 6 位" :maxlength="32" />
</view>
<view class="field">
<text class="label">确认密码</text>
<input v-model="confirmPassword" class="input" type="password" placeholder="再输入一次" :maxlength="32" />
</view>
<text class="hint">密码至少 6 位;微信号会在注册时自动绑定,下次可直接进入</text>
<view v-if="errorMsg" class="error"><text>{{ errorMsg }}</text></view>
<button class="submit" :disabled="loading" @tap="handleSubmit">
{{ loading ? '注册中…' : '完成注册' }}
</button>
</view>
</view>
</template>
<script setup>
/**
* 手机号授权后未查到账号:设置密码完成注册(后端同时绑定微信 openid 并签发 tid=0 令牌)。
* 注册完成后回到工作台,由 nav 自动继续进入刚才点击的模块。
*/
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { onboardingRegister } from '@/api/onboarding.js'
import { setAuthTokens, setTid, setTenantName } from '@/utils/auth.js'
import { guestMerge } from '@/api/guest.js'
import { getGuestToken, clearGuestToken } from '@/utils/guest.js'
import { clearHomeCache } from '@/api/workspace.js'
const token = ref('')
const mobileMask = ref('')
const password = ref('')
const confirmPassword = ref('')
const loading = ref(false)
const errorMsg = ref('')
onLoad((options = {}) => {
token.value = options.token || ''
mobileMask.value = decodeURIComponent(options.mobile_mask || '')
if (!token.value) {
errorMsg.value = '授权会话已失效,请返回工作台重新授权手机号'
}
})
async function handleSubmit() {
if (loading.value) return
errorMsg.value = ''
if (!token.value) {
errorMsg.value = '授权会话已失效,请返回工作台重新授权手机号'
return
}
if (password.value.length < 6) {
errorMsg.value = '密码长度不能少于 6 位'
return
}
if (password.value !== confirmPassword.value) {
errorMsg.value = '两次输入的密码不一致'
return
}
loading.value = true
try {
const res = await onboardingRegister({
token: token.value,
password: password.value,
confirmPassword: confirmPassword.value
})
if (!res || !res.tokens || !res.tokens.access_token) throw new Error('注册失败,未返回登录态')
setAuthTokens(res.tokens)
setTid(0)
setTenantName('')
clearHomeCache()
// 注册前以游客身份产生的数据并入正式账号
if (getGuestToken()) {
try {
await guestMerge()
} catch (e) {
console.warn('[onboarding] guest merge failed:', e)
}
clearGuestToken()
}
uni.showToast({ title: '注册成功', icon: 'success' })
setTimeout(() => uni.reLaunch({ url: '/pages/nav/nav' }), 500)
} catch (e) {
errorMsg.value = (e && e.message) || '注册失败,请重试'
} finally {
loading.value = false
}
}
</script>
<style lang="scss" scoped>
@import '@/src/styles/page-common.scss';
.page {
min-height: 100vh;
padding: 0 $page-padding-x 60rpx;
box-sizing: border-box;
background: linear-gradient(160deg, #eaf3ff 0%, #f8fafc 42%, #f8fafc 100%);
}
.hero { padding: 120rpx 8rpx 56rpx; }
.eyebrow { display: block; font-size: 20rpx; font-weight: 700; letter-spacing: 3rpx; color: #6e9de5; }
.title { display: block; margin-top: 14rpx; font-size: 46rpx; font-weight: 700; color: #17345f; }
.desc { display: block; margin-top: 16rpx; font-size: 25rpx; line-height: 1.6; color: #64748b; }
.card {
@include card;
padding: 36rpx 30rpx 40rpx;
}
.field { margin-bottom: 28rpx; }
.label { display: block; margin-bottom: 12rpx; font-size: 25rpx; font-weight: 600; color: #334155; }
.input {
height: 88rpx;
padding: 0 24rpx;
border: 1rpx solid #dce7f7;
border-radius: $radius-md;
background: #fbfdff;
font-size: 28rpx;
color: $color-text;
box-sizing: border-box;
}
.hint { display: block; font-size: 22rpx; line-height: 1.6; color: $color-text-muted; }
.error { margin-top: 20rpx; font-size: 24rpx; color: $color-danger; }
.submit {
margin-top: 40rpx;
height: 92rpx;
line-height: 92rpx;
border: none;
border-radius: $radius-full;
background: linear-gradient(135deg, #60a5fa, #2563eb);
color: #ffffff;
font-size: 30rpx;
font-weight: 600;
box-shadow: 0 10rpx 24rpx rgba(37, 99, 235, .22);
&::after { border: none; }
&[disabled] { opacity: .6; }
}
</style>