consumer模块完成度85%,测试连接supabase

This commit is contained in:
2026-01-28 17:28:50 +08:00
parent 66aa909193
commit a4fa00c935
18 changed files with 2108 additions and 1573 deletions

View File

@@ -1,353 +1,103 @@
<template>
<view class="change-password-page">
<view class="header">
<view class="back-btn" @click="goBack">
<text class="back-icon"></text>
</view>
<text class="header-title">修改密码</text>
</view>
<view class="content">
<form @submit="onSubmit">
<!-- 当前密码 -->
<view class="form-item">
<text class="label">当前密码</text>
<input
class="input"
type="password"
placeholder="请输入当前密码"
v-model="form.currentPassword"
:disabled="loading"
required
/>
</view>
<!-- 新密码 -->
<view class="form-item">
<text class="label">新密码</text>
<input
class="input"
type="password"
placeholder="请输入新密码6-20位字符"
v-model="form.newPassword"
:disabled="loading"
required
/>
<text class="hint">6-20位字符建议包含字母、数字和特殊符号</text>
</view>
<!-- 确认新密码 -->
<view class="form-item">
<text class="label">确认新密码</text>
<input
class="input"
type="password"
placeholder="请再次输入新密码"
v-model="form.confirmPassword"
:disabled="loading"
required
/>
</view>
<!-- 提交按钮 -->
<button
class="submit-btn"
form-type="submit"
:disabled="loading || !isFormValid"
:loading="loading"
>
{{ loading ? '处理中...' : '确认修改' }}
</button>
</form>
<!-- 忘记密码提示 -->
<view class="forgot-password">
<text class="forgot-text" @click="goToForgotPassword">忘记密码?</text>
</view>
</view>
<!-- 成功提示 -->
<view v-if="showSuccess" class="success-modal" @click="hideSuccess">
<view class="success-content" @click.stop>
<text class="success-icon">✓</text>
<text class="success-title">修改成功</text>
<text class="success-text">密码已成功修改,请使用新密码登录</text>
<button class="success-btn" @click="hideSuccess">确定</button>
</view>
</view>
</view>
<view class="page-container">
<view class="form-group">
<view class="input-item">
<text class="label">旧密码</text>
<input class="input" type="password" placeholder="请输入旧密码" v-model="oldPassword" />
</view>
<view class="input-item">
<text class="label">新密码</text>
<input class="input" type="password" placeholder="请输入新密码" v-model="newPassword" />
</view>
<view class="input-item">
<text class="label">确认密码</text>
<input class="input" type="password" placeholder="请再次输入新密码" v-model="confirmPassword" />
</view>
</view>
<button class="submit-btn" @click="handleSubmit">确认修改</button>
</view>
</template>
<script setup lang="uts">
import { ref, computed } from 'vue'
import supa from '@/components/supadb/aksupainstance.uts'
import { ref } from 'vue'
// 表单数据
const form = ref({
currentPassword: '',
newPassword: '',
confirmPassword: ''
})
const oldPassword = ref('')
const newPassword = ref('')
const confirmPassword = ref('')
const loading = ref<boolean>(false)
const showSuccess = ref<boolean>(false)
// 表单验证
const isFormValid = computed((): boolean => {
const { currentPassword, newPassword, confirmPassword } = form.value
return currentPassword.length >= 6 &&
newPassword.length >= 6 &&
newPassword.length <= 20 &&
newPassword === confirmPassword
})
// 提交表单
const onSubmit = async () => {
if (!isFormValid.value) {
uni.showToast({
title: '请填写完整且正确的密码信息',
icon: 'none'
})
return
}
loading.value = true
try {
// 调用 Supabase 更新密码
const { error } = await supa.auth.updateUser({
password: form.value.newPassword
})
if (error !== null) {
throw error
}
// 成功
showSuccess.value = true
// 清除表单
form.value = {
currentPassword: '',
newPassword: '',
confirmPassword: ''
}
} catch (error: any) {
console.error('修改密码失败:', error)
let errorMessage = '修改密码失败'
if (error.message?.includes('invalid_credentials')) {
errorMessage = '当前密码错误'
} else if (error.message?.includes('password')) {
errorMessage = '新密码不符合要求'
}
uni.showToast({
title: errorMessage,
icon: 'none'
})
} finally {
loading.value = false
}
}
// 导航函数
const goBack = () => {
uni.navigateBack()
}
const goToForgotPassword = () => {
uni.navigateTo({
url: '/pages/user/forgot-password'
})
}
const hideSuccess = () => {
showSuccess.value = false
goBack()
const handleSubmit = () => {
if (!oldPassword.value || !newPassword.value || !confirmPassword.value) {
uni.showToast({
title: '请填写完整信息',
icon: 'none'
})
return
}
if (newPassword.value !== confirmPassword.value) {
uni.showToast({
title: '两次输入的密码不一致',
icon: 'none'
})
return
}
// TODO: Call API to change password
uni.showLoading({ title: '提交中...' })
setTimeout(() => {
uni.hideLoading()
uni.showToast({
title: '修改成功',
icon: 'success'
})
setTimeout(() => {
uni.navigateBack()
}, 1500)
}, 1000)
}
</script>
<style>
.change-password-page {
min-height: 100vh;
background-color: #f5f5f5;
.page-container {
padding: 20px;
background-color: #f5f5f5;
min-height: 100vh;
}
.header {
background-color: #ffffff;
padding: 15px;
display: flex;
align-items: center;
border-bottom: 1px solid #e5e5e5;
.form-group {
background-color: #fff;
border-radius: 8px;
padding: 0 15px;
margin-bottom: 30px;
}
.back-btn {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
.input-item {
display: flex;
align-items: center;
height: 50px;
border-bottom: 1px solid #eee;
}
.back-icon {
font-size: 24px;
color: #333;
}
.header-title {
font-size: 18px;
font-weight: bold;
color: #333;
flex: 1;
}
.content {
padding: 20px;
}
.form-item {
margin-bottom: 20px;
background-color: #ffffff;
border-radius: 10px;
padding: 15px;
.input-item:last-child {
border-bottom: none;
}
.label {
display: block;
font-size: 16px;
color: #333;
margin-bottom: 10px;
font-weight: bold;
width: 80px;
font-size: 14px;
color: #333;
}
.input {
width: 100%;
height: 44px;
border: 1px solid #ddd;
border-radius: 8px;
padding: 0 15px;
font-size: 16px;
box-sizing: border-box;
}
.input:focus {
border-color: #007aff;
outline: none;
}
.input:disabled {
background-color: #f9f9f9;
color: #999;
}
.hint {
display: block;
font-size: 12px;
color: #999;
margin-top: 5px;
flex: 1;
font-size: 14px;
}
.submit-btn {
width: 100%;
height: 50px;
background-color: #007aff;
color: #ffffff;
border-radius: 25px;
font-size: 16px;
font-weight: bold;
border: none;
margin-top: 30px;
background-color: #007aff;
color: #fff;
border-radius: 25px;
font-size: 16px;
}
.submit-btn:disabled {
background-color: #cccccc;
}
.forgot-password {
text-align: center;
margin-top: 20px;
}
.forgot-text {
color: #007aff;
font-size: 14px;
text-decoration: underline;
}
/* 成功提示模态框 */
.success-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.success-content {
width: 280px;
background-color: #ffffff;
border-radius: 15px;
padding: 30px 20px;
text-align: center;
}
.success-icon {
display: block;
width: 60px;
height: 60px;
line-height: 60px;
background-color: #4cd964;
color: #ffffff;
font-size: 30px;
border-radius: 50%;
margin: 0 auto 20px;
}
.success-title {
display: block;
font-size: 18px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.success-text {
display: block;
font-size: 14px;
color: #666;
margin-bottom: 20px;
line-height: 1.4;
}
.success-btn {
width: 100%;
height: 44px;
background-color: #007aff;
color: #ffffff;
border-radius: 22px;
font-size: 16px;
border: none;
}
/* 响应式优化 */
@media screen and (min-width: 768px) {
.change-password-page {
max-width: 500px;
margin: 0 auto;
border-left: 1px solid #e5e5e5;
border-right: 1px solid #e5e5e5;
}
.content {
padding: 40px;
}
}
</style>
</style>