Init applications

This commit is contained in:
NVWA Bot
2026-01-05 06:17:07 +00:00
commit b3dbfc86d3
193 changed files with 35016 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
<template>
<view class="flex flex-col items-center justify-center space-y-4">
Index123
</view>
</template>
<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app'
import { auth } from '@/lib/nvwa'
import { AUTH_REQUIRED } from '@/lib/config'
import redirectToLogin from '@/custom/redirect-to-login'
onLoad(async () => {
// 如果需要认证,检查登录状态
if (AUTH_REQUIRED) {
try {
const userProfile = await auth.currentUser()
if (!userProfile) {
// 未登录,重定向到登录页
await redirectToLogin()
return
}
console.log("current user profile", userProfile)
} catch (error) {
// 获取用户信息失败,重定向到登录页
await redirectToLogin()
return
}
} else {
// 不需要认证,可以尝试获取用户信息(但不强制)
const userProfile = await auth.currentUser()
console.log("current user profile", userProfile)
}
})
</script>
<style></style>

View File

@@ -0,0 +1,214 @@
<template>
<view class="flex flex-col items-center justify-center min-h-screen bg-gray-50 px-5">
<view class="w-full max-w-md">
<!-- Logo -->
<view class="flex justify-center mb-10 mt-20">
<image class="h-24 w-24" src="/static/logo.png" mode="aspectFit"></image>
</view>
<!-- 登录方式切换 -->
<view class="flex gap-2 mb-6">
<button
:class="loginType === 'username' ? 'bg-blue-500 text-white' : 'bg-white text-gray-700 border border-gray-300'"
class="flex-1 py-2 rounded-full text-sm"
@click="loginType = 'username'"
>
用户名登录
</button>
<button
:class="loginType === 'phone' ? 'bg-blue-500 text-white' : 'bg-white text-gray-700 border border-gray-300'"
class="flex-1 py-2 rounded-full text-sm"
@click="loginType = 'phone'"
>
手机号登录
</button>
</view>
<!-- 登录表单 -->
<view v-if="loginType === 'username'" class="space-y-4">
<view>
<uni-easyinput
shape="circle"
placeholder="请输入用户名"
border="surround"
v-model="username"
:clearable="true"
></uni-easyinput>
</view>
<view>
<uni-easyinput
shape="circle"
placeholder="请输入密码"
type="password"
border="surround"
v-model="password"
:clearable="true"
></uni-easyinput>
</view>
</view>
<view v-else class="space-y-4">
<view>
<uni-easyinput
shape="circle"
placeholder="请输入手机号"
border="surround"
v-model="phoneNumber"
type="number"
:clearable="true"
></uni-easyinput>
</view>
<view>
<uni-easyinput
shape="circle"
placeholder="请输入密码"
type="password"
border="surround"
v-model="password"
:clearable="true"
></uni-easyinput>
</view>
<view class="flex items-center" @click="rememberMe = !rememberMe">
<uni-icons :type="rememberMe ? 'checkbox-filled' : 'circle'" size="20" :color="rememberMe ? '#007AFF' : '#999'"></uni-icons>
<text class="ml-2 text-xs text-gray-600">记住我</text>
</view>
</view>
<!-- 错误提示 -->
<view v-if="errorMessage" class="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
<text class="text-red-600 text-sm">{{ errorMessage }}</text>
</view>
<!-- 登录按钮 -->
<button
class="w-full rounded-full bg-blue-500 border border-blue-500 text-white py-3 mt-6"
:disabled="isLoading"
@click="handleLogin"
>
{{ isLoading ? '登录中...' : '登录' }}
</button>
<!-- 注册链接 -->
<view class="mt-6 text-center">
<text class="text-gray-600 text-sm">还没有账户</text>
<text class="text-blue-500 text-sm ml-1" @click="goToRegister">立即注册</text>
</view>
<!-- 其他登录方式 -->
<view class="mt-10 text-center">
<view class="text-gray-600 text-sm mb-5">其他登录方式</view>
<view class="flex justify-center gap-4">
<view class="p-2" @click="handleWechatLogin">
<uni-icons type="weixin" size="40" color="#07C160"></uni-icons>
</view>
<view class="p-2" @click="handleQQLogin">
<uni-icons type="qq" size="40" color="#12B7F5"></uni-icons>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { auth, localStorage } from '@/lib/nvwa'
const LOGIN_BACK_URL_KEY = "LOGIN_BACK_URL"
const loginType = ref<'username' | 'phone'>('username')
const username = ref<string>('')
const phoneNumber = ref<string>('')
const password = ref<string>('')
const rememberMe = ref<boolean>(false)
const isLoading = ref<boolean>(false)
const errorMessage = ref<string>('')
onLoad(async () => {
// 检查是否已登录
const user = await auth.currentUser()
if (user) {
const url = await localStorage.get(LOGIN_BACK_URL_KEY) || '/pages/home'
uni.reLaunch({
url
})
}
})
const handleLogin = async () => {
if (isLoading.value) return
// 验证输入
if (!password.value || password.value.length < 6) {
errorMessage.value = '密码至少需要6个字符'
return
}
if (loginType.value === 'username') {
if (!username.value || username.value.trim().length === 0) {
errorMessage.value = '请输入用户名'
return
}
} else {
if (!phoneNumber.value || phoneNumber.value.trim().length === 0) {
errorMessage.value = '请输入手机号'
return
}
}
isLoading.value = true
errorMessage.value = ''
try {
if (loginType.value === 'username') {
await auth.signInWithUsername(username.value.trim(), password.value)
} else {
await auth.signInWithPhoneNumber(
phoneNumber.value.trim(),
password.value,
rememberMe.value
)
}
// 登录成功,跳转
const url = await localStorage.get(LOGIN_BACK_URL_KEY) || '/pages/home'
await localStorage.remove(LOGIN_BACK_URL_KEY)
uni.reLaunch({
url
})
} catch (error: any) {
errorMessage.value = error?.message || '登录失败,请重试'
uni.showToast({
title: errorMessage.value,
icon: 'none'
})
} finally {
isLoading.value = false
}
}
const goToRegister = () => {
uni.navigateTo({
url: '/pages/user/register'
})
}
const handleWechatLogin = () => {
uni.showToast({
title: '微信登录功能开发中',
icon: 'none'
})
}
const handleQQLogin = () => {
uni.showToast({
title: 'QQ登录功能开发中',
icon: 'none'
})
}
</script>
<style scoped>
/* 使用 Tailwind CSS 类名,无需额外样式 */
</style>

View File

@@ -0,0 +1,213 @@
<template>
<view class="flex flex-col items-center justify-center min-h-screen bg-gray-50 px-5">
<view class="w-full max-w-md">
<!-- Logo -->
<view class="flex justify-center mb-10 mt-20">
<image class="h-24 w-24" src="/static/logo.png" mode="aspectFit"></image>
</view>
<!-- 注册标题 -->
<view class="text-center mb-8">
<text class="text-2xl font-bold text-gray-800">创建账户</text>
</view>
<!-- 注册表单 -->
<view class="space-y-4">
<view>
<uni-easyinput
shape="circle"
placeholder="请输入姓名"
border="surround"
v-model="name"
:clearable="true"
></uni-easyinput>
</view>
<view>
<uni-easyinput
shape="circle"
placeholder="请输入用户名至少3个字符"
border="surround"
v-model="username"
:clearable="true"
></uni-easyinput>
</view>
<view>
<uni-easyinput
shape="circle"
placeholder="请输入邮箱(可选)"
border="surround"
v-model="email"
type="email"
:clearable="true"
></uni-easyinput>
</view>
<view>
<uni-easyinput
shape="circle"
placeholder="请输入头像URL可选"
border="surround"
v-model="image"
:clearable="true"
></uni-easyinput>
</view>
<view>
<uni-easyinput
shape="circle"
placeholder="请输入密码至少6个字符"
type="password"
border="surround"
v-model="password"
:clearable="true"
></uni-easyinput>
</view>
<view>
<uni-easyinput
shape="circle"
placeholder="请再次输入密码"
type="password"
border="surround"
v-model="confirmPassword"
:clearable="true"
></uni-easyinput>
</view>
</view>
<!-- 错误提示 -->
<view v-if="errorMessage" class="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
<text class="text-red-600 text-sm">{{ errorMessage }}</text>
</view>
<!-- 注册按钮 -->
<button
class="w-full rounded-full bg-blue-500 border border-blue-500 text-white py-3 mt-6"
:disabled="isLoading"
@click="handleRegister"
>
{{ isLoading ? '注册中...' : '注册' }}
</button>
<!-- 登录链接 -->
<view class="mt-6 text-center">
<text class="text-gray-600 text-sm">已有账户</text>
<text class="text-blue-500 text-sm ml-1" @click="goToLogin">立即登录</text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { auth } from '@/lib/nvwa'
const name = ref<string>('')
const username = ref<string>('')
const email = ref<string>('')
const image = ref<string>('')
const password = ref<string>('')
const confirmPassword = ref<string>('')
const isLoading = ref<boolean>(false)
const errorMessage = ref<string>('')
onLoad(async () => {
// 检查是否已登录
const user = await auth.currentUser()
if (user) {
uni.reLaunch({
url: '/pages/home'
})
}
})
const validateForm = (): boolean => {
errorMessage.value = ''
if (!name.value || name.value.trim().length < 2) {
errorMessage.value = '姓名至少需要2个字符'
return false
}
if (!username.value || username.value.trim().length < 3) {
errorMessage.value = '用户名至少需要3个字符'
return false
}
if (!password.value || password.value.length < 6) {
errorMessage.value = '密码至少需要6个字符'
return false
}
if (password.value !== confirmPassword.value) {
errorMessage.value = '两次输入的密码不一致'
return false
}
if (email.value && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value)) {
errorMessage.value = '请输入有效的邮箱地址'
return false
}
if (image.value && !/^https?:\/\/.+/.test(image.value)) {
errorMessage.value = '请输入有效的图片URL'
return false
}
return true
}
const handleRegister = async () => {
if (isLoading.value) return
if (!validateForm()) {
uni.showToast({
title: errorMessage.value,
icon: 'none'
})
return
}
isLoading.value = true
errorMessage.value = ''
try {
await auth.signUp({
name: name.value.trim(),
username: username.value.trim(),
password: password.value,
email: email.value.trim() || undefined,
image: image.value.trim() || '',
})
// 注册成功,跳转到首页
uni.showToast({
title: '注册成功',
icon: 'success'
})
setTimeout(() => {
uni.reLaunch({
url: '/pages/home'
})
}, 1500)
} catch (error: any) {
errorMessage.value = error?.message || '注册失败,请重试'
uni.showToast({
title: errorMessage.value,
icon: 'none'
})
} finally {
isLoading.value = false
}
}
const goToLogin = () => {
uni.navigateTo({
url: '/pages/user/login'
})
}
</script>
<style scoped>
/* 使用 Tailwind CSS 类名,无需额外样式 */
</style>