优化uniapp

This commit is contained in:
hero920103 committed 2026-11-11 16:58:30 +08:00
1 parent 4f1acaa451
commit 8fc52c574f
49 files changed
+1952 -197

No files matched your search

+150
View File
@@ -0,0 +1,150 @@
<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>