Przeglądaj źródła

✨ feat(ui): 新增卡片组件并优化登录注册页面

- 创建新的卡片组件,包含 Card/CardHeader/CardContent/CardFooter 子组件
- 重构登录页面,使用渐变背景和现代化表单设计
- 更新注册页面,添加密码可见性切换和图标支持
- 增强个人中心页面,添加用户信息展示和统计卡片

💄 style(auth): 统一认证页面视觉风格

- 使用 Tailwind CSS 重构样式系统
- 添加图标和加载动画效果
- 优化移动端交互体验
yourname 4 miesięcy temu
rodzic
commit
7c7264430c

+ 54 - 0
mini/src/components/ui/card.tsx

@@ -0,0 +1,54 @@
+import { View } from '@tarojs/components'
+import { cn } from '@/utils/cn'
+
+interface CardProps {
+  className?: string
+  children: React.ReactNode
+}
+
+export function Card({ className, children }: CardProps) {
+  return (
+    <View className={cn("bg-white rounded-xl shadow-sm", className)}>
+      {children}
+    </View>
+  )
+}
+
+interface CardHeaderProps {
+  className?: string
+  children: React.ReactNode
+}
+
+export function CardHeader({ className, children }: CardHeaderProps) {
+  return (
+    <View className={cn("p-4 border-b border-gray-100", className)}>
+      {children}
+    </View>
+  )
+}
+
+interface CardContentProps {
+  className?: string
+  children: React.ReactNode
+}
+
+export function CardContent({ className, children }: CardContentProps) {
+  return (
+    <View className={cn("p-4", className)}>
+      {children}
+    </View>
+  )
+}
+
+interface CardFooterProps {
+  className?: string
+  children: React.ReactNode
+}
+
+export function CardFooter({ className, children }: CardFooterProps) {
+  return (
+    <View className={cn("p-4 border-t border-gray-100", className)}>
+      {children}
+    </View>
+  )
+}

+ 112 - 102
mini/src/pages/login/index.tsx

@@ -1,14 +1,14 @@
 import { View, Input, Button, Text, Image } from '@tarojs/components'
 import { useState, useEffect } from 'react'
 import Taro from '@tarojs/taro'
-import './index.css'
 import { useAuth } from '@/utils/auth'
+import { cn } from '@/utils/cn'
 
 export default function Login() {
   const [username, setUsername] = useState('')
   const [password, setPassword] = useState('')
   const [showPassword, setShowPassword] = useState(false)
-  const { login, isLoading } = useAuth() // 使用 useAuth 获取登录方法和加载状态
+  const { login, isLoading } = useAuth()
 
   // 设置导航栏标题
   useEffect(() => {
@@ -48,7 +48,7 @@ export default function Login() {
 
     if (password.trim().length < 6) {
       Taro.showToast({
-        title: '密码至少6个字符',
+        title: '密码至少6',
         icon: 'none',
         duration: 2000
       })
@@ -56,13 +56,11 @@ export default function Login() {
     }
     
     try {
-      // 显示加载动画
       Taro.showLoading({
         title: '登录中...',
         mask: true
       })
 
-      // 使用 useAuth 提供的 login 方法,传递符合 LoginRequest 类型的参数
       await login({
         username: username.trim(),
         password: password.trim()
@@ -76,11 +74,6 @@ export default function Login() {
         duration: 1500
       })
       
-      // 重置表单
-      setUsername('')
-      setPassword('')
-      
-      // 登录成功后跳转到首页
       setTimeout(() => {
         Taro.switchTab({ url: '/pages/index/index' })
       }, 1500)
@@ -89,7 +82,6 @@ export default function Login() {
       
       const errorMessage = error.message || '登录失败'
       
-      // 根据错误类型显示不同的提示
       if (errorMessage.includes('用户名或密码错误')) {
         Taro.showToast({
           title: '用户名或密码错误',
@@ -115,23 +107,12 @@ export default function Login() {
 
   const goToRegister = () => {
     Taro.navigateTo({ 
-      url: '/pages/register/index',
-      success: () => {
-        console.log('跳转到注册页面')
-      },
-      fail: (error) => {
-        console.error('跳转失败:', error)
-        Taro.showToast({
-          title: '页面跳转失败',
-          icon: 'none'
-        })
-      }
+      url: '/pages/register/index'
     })
   }
 
   const handleUsernameInput = (e: any) => {
     const value = e.detail.value
-    // 限制输入字符
     if (value.length <= 20) {
       setUsername(value.replace(/\s+/g, ''))
     }
@@ -144,92 +125,121 @@ export default function Login() {
     }
   }
 
-  // 处理键盘完成事件
-  const handleInputConfirm = () => {
-    if (username && password && !isLoading) {
-      handleLogin()
-    }
-  }
-
   return (
-    <View className="login-container">
-      <View className="login-header">
-        <Image 
-          className="login-logo"
-          src="https://source.unsplash.com/400x400/?minimal,logo,blue"
-          mode="aspectFit"
-          lazyLoad
-        />
-        <View className="login-title-container">
-          <Text className="login-title">欢迎回来</Text>
-          <Text className="login-subtitle">请使用您的账号登录系统</Text>
-        </View>
-      </View>
-      
-      <View className="login-form">
-        <View className="form-item">
-          <Text className="form-label">用户名</Text>
-          <View className="input-wrapper">
-            <Input
-              className="form-input"
-              placeholder="请输入用户名"
-              value={username}
-              onInput={handleUsernameInput}
-              onConfirm={handleInputConfirm}
-              maxlength={20}
-              type="text"
-              confirmType="next"
-              adjustPosition
-            />
+    <View className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-indigo-50">
+      <View className="flex-1 px-6 py-12">
+        {/* Logo区域 */}
+        <View className="flex flex-col items-center mb-10">
+          <View className="w-20 h-20 mb-4 rounded-full bg-white shadow-lg flex items-center justify-center">
+            <View className="i-heroicons-user-circle-20-solid w-12 h-12 text-blue-500" />
           </View>
+          <Text className="text-2xl font-bold text-gray-900 mb-1">欢迎回来</Text>
+          <Text className="text-gray-600 text-sm">请使用您的账号登录系统</Text>
         </View>
-        
-        <View className="form-item">
-          <Text className="form-label">密码</Text>
-          <View className="input-wrapper">
-            <Input
-              className="form-input"
-              placeholder="请输入密码"
-              password={!showPassword}
-              value={password}
-              onInput={handlePasswordInput}
-              onConfirm={handleInputConfirm}
-              maxlength={20}
-              type={showPassword ? 'text' : undefined}
-              confirmType="done"
-              adjustPosition
-            />
+
+        {/* 登录表单 */}
+        <View className="bg-white rounded-2xl shadow-sm p-6">
+          <View className="space-y-5">
+            {/* 用户名输入框 */}
+            <View className="space-y-2">
+              <Text className="text-sm font-medium text-gray-700">用户名</Text>
+              <View className="relative">
+                <View className="absolute left-3 top-1/2 -translate-y-1/2">
+                  <View className="i-heroicons-user-20-solid w-5 h-5 text-gray-400" />
+                </View>
+                <Input
+                  className="w-full h-12 pl-10 pr-4 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
+                  placeholder="请输入用户名"
+                  value={username}
+                  onInput={handleUsernameInput}
+                  maxlength={20}
+                  type="text"
+                  confirmType="next"
+                />
+              </View>
+            </View>
+
+            {/* 密码输入框 */}
+            <View className="space-y-2">
+              <Text className="text-sm font-medium text-gray-700">密码</Text>
+              <View className="relative">
+                <View className="absolute left-3 top-1/2 -translate-y-1/2">
+                  <View className="i-heroicons-lock-closed-20-solid w-5 h-5 text-gray-400" />
+                </View>
+                <Input
+                  className="w-full h-12 pl-10 pr-12 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
+                  placeholder="请输入密码"
+                  password={!showPassword}
+                  value={password}
+                  onInput={handlePasswordInput}
+                  maxlength={20}
+                  type={showPassword ? 'text' : 'password'}
+                  confirmType="done"
+                />
+                <View 
+                  className="absolute right-3 top-1/2 -translate-y-1/2"
+                  onClick={() => setShowPassword(!showPassword)}
+                >
+                  <View className={cn(
+                    "w-5 h-5 text-gray-400",
+                    showPassword ? "i-heroicons-eye-20-solid" : "i-heroicons-eye-slash-20-solid"
+                  )} />
+                </View>
+              </View>
+            </View>
+
+            {/* 忘记密码 */}
+            <View className="flex justify-end">
+              <Text className="text-sm text-blue-500 hover:text-blue-600">忘记密码?</Text>
+            </View>
+
+            {/* 登录按钮 */}
+            <Button
+              className={cn(
+                "w-full h-12 rounded-lg font-medium text-white transition-all duration-200",
+                isLoading || !username || !password
+                  ? "bg-gray-300 cursor-not-allowed"
+                  : "bg-blue-500 hover:bg-blue-600 active:bg-blue-700 shadow-lg"
+              )}
+              loading={isLoading}
+              onClick={handleLogin}
+              disabled={isLoading || !username || !password}
+            >
+              {isLoading ? (
+                <View className="flex items-center justify-center">
+                  <View className="i-heroicons-arrow-path-20-solid animate-spin w-5 h-5 mr-2" />
+                  登录中...
+                </View>
+              ) : (
+                '安全登录'
+              )}
+            </Button>
           </View>
-        </View>
-        
-        <Button
-          className={`login-button ${isLoading ? 'loading' : ''}`}
-          loading={isLoading}
-          onClick={handleLogin}
-          disabled={isLoading || !username || !password}
-        >
-          {isLoading ? '登录中...' : '安全登录'}
-        </Button>
-        
-        <View className="login-footer">
-          <Text className="footer-text">
-            还没有账号? 
-            <Text className="link-text" onClick={goToRegister}>
-              立即注册
+
+          {/* 注册链接 */}
+          <View className="mt-6 text-center">
+            <Text className="text-sm text-gray-600">
+              还没有账号? 
+              <Text 
+                className="text-blue-500 font-medium hover:text-blue-600" 
+                onClick={goToRegister}
+              >
+                立即注册
+              </Text>
             </Text>
-          </Text>
+          </View>
         </View>
-      </View>
-      
-      <View className="login-footer-info">
-        <Text className="footer-tip">登录即表示您同意我们的</Text>
-        <View className="footer-links">
-          <Text className="link-text">用户协议</Text>
-          <Text className="link-separator">和</Text>
-          <Text className="link-text">隐私政策</Text>
+
+        {/* 协议声明 */}
+        <View className="mt-8 text-center">
+          <Text className="text-xs text-gray-500">
+            登录即表示您同意
+            <Text className="text-blue-500 mx-1">用户协议</Text>
+            和
+            <Text className="text-blue-500 mx-1">隐私政策</Text>
+          </Text>
         </View>
       </View>
     </View>
   )
-}
-    
+}

+ 234 - 7
mini/src/pages/profile/index.tsx

@@ -1,16 +1,243 @@
-import React from 'react'
-import { View, Text } from '@tarojs/components'
+import { useState, useEffect } from 'react'
+import { View, Text, Image, Button, ScrollView } from '@tarojs/components'
+import Taro from '@tarojs/taro'
 import { TabBarLayout } from '@/layouts/tab-bar-layout'
+import { useAuth } from '@/utils/auth'
+import { cn } from '@/utils/cn'
+
+interface UserProfile {
+  id: number
+  username: string
+  email?: string
+  avatar?: string
+  createdAt: string
+  lastLoginAt?: string
+}
 
 const ProfilePage: React.FC = () => {
+  const [userProfile, setUserProfile] = useState<UserProfile | null>(null)
+  const [loading, setLoading] = useState(true)
+  const { user, logout } = useAuth()
+
+  useEffect(() => {
+    if (user) {
+      setUserProfile({
+        id: user.id,
+        username: user.username,
+        email: user.email,
+        avatar: user.avatar || 'https://source.unsplash.com/200x200/?avatar,face',
+        createdAt: new Date().toISOString(),
+        lastLoginAt: new Date().toISOString()
+      })
+    }
+    setLoading(false)
+  }, [user])
+
+  const handleLogout = async () => {
+    try {
+      Taro.showModal({
+        title: '退出登录',
+        content: '确定要退出登录吗?',
+        success: async (res) => {
+          if (res.confirm) {
+            Taro.showLoading({ title: '退出中...' })
+            await logout()
+            Taro.hideLoading()
+            Taro.showToast({
+              title: '已退出登录',
+              icon: 'success',
+              duration: 1500
+            })
+            setTimeout(() => {
+              Taro.reLaunch({ url: '/pages/index/index' })
+            }, 1500)
+          }
+        }
+      })
+    } catch (error) {
+      Taro.hideLoading()
+      Taro.showToast({
+        title: '退出失败,请重试',
+        icon: 'none'
+      })
+    }
+  }
+
+  const handleEditProfile = () => {
+    Taro.showToast({
+      title: '功能开发中...',
+      icon: 'none'
+    })
+  }
+
+  const handleSettings = () => {
+    Taro.showToast({
+      title: '功能开发中...',
+      icon: 'none'
+    })
+  }
+
+  const menuItems = [
+    {
+      icon: 'i-heroicons-user-circle-20-solid',
+      title: '编辑资料',
+      onClick: handleEditProfile,
+      color: 'text-blue-500'
+    },
+    {
+      icon: 'i-heroicons-cog-6-tooth-20-solid',
+      title: '设置',
+      onClick: handleSettings,
+      color: 'text-gray-500'
+    },
+    {
+      icon: 'i-heroicons-shield-check-20-solid',
+      title: '隐私政策',
+      onClick: () => Taro.showToast({ title: '功能开发中...', icon: 'none' }),
+      color: 'text-green-500'
+    },
+    {
+      icon: 'i-heroicons-question-mark-circle-20-solid',
+      title: '帮助与反馈',
+      onClick: () => Taro.showToast({ title: '功能开发中...', icon: 'none' }),
+      color: 'text-purple-500'
+    }
+  ]
+
+  if (loading) {
+    return (
+      <TabBarLayout activeKey="profile">
+        <View className="flex-1 flex items-center justify-center">
+          <View className="i-heroicons-arrow-path-20-solid animate-spin w-8 h-8 text-blue-500" />
+        </View>
+      </TabBarLayout>
+    )
+  }
+
+  if (!userProfile) {
+    return (
+      <TabBarLayout activeKey="profile">
+        <View className="flex-1 flex items-center justify-center">
+          <View className="text-center">
+            <View className="i-heroicons-exclamation-circle-20-solid w-12 h-12 text-gray-400 mx-auto mb-4" />
+            <Text className="text-gray-600 mb-4">请先登录</Text>
+            <Button
+              className="bg-blue-500 text-white px-6 py-2 rounded-lg"
+              onClick={() => Taro.navigateTo({ url: '/pages/login/index' })}
+            >
+              去登录
+            </Button>
+          </View>
+        </View>
+      </TabBarLayout>
+    )
+  }
+
   return (
     <TabBarLayout activeKey="profile">
-      <View className="p-4">
-        <Text className="text-2xl font-bold text-gray-900">个人中心</Text>
-        <View className="mt-4">
-          <Text className="text-gray-600">这里展示个人信息</Text>
+      <ScrollView className="flex-1 bg-gray-50">
+        {/* 用户信息卡片 */}
+        <View className="bg-white rounded-b-3xl shadow-sm pb-8">
+          <View className="flex flex-col items-center pt-8 pb-6">
+            <View className="relative">
+              <Image
+                className="w-24 h-24 rounded-full border-4 border-white shadow-lg"
+                src={userProfile.avatar || 'https://source.unsplash.com/200x200/?avatar'}
+                mode="aspectFill"
+              />
+              <View className="absolute -bottom-2 -right-2 w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center shadow-md">
+                <View className="i-heroicons-camera-20-solid w-4 h-4 text-white" />
+              </View>
+            </View>
+            <Text className="text-xl font-bold text-gray-900 mt-4">{userProfile.username}</Text>
+            {userProfile.email && (
+              <Text className="text-sm text-gray-600 mt-1">{userProfile.email}</Text>
+            )}
+            <View className="flex items-center mt-2">
+              <View className="i-heroicons-calendar-20-solid w-4 h-4 text-gray-400 mr-1" />
+              <Text className="text-xs text-gray-500">
+                注册于 {new Date(userProfile.createdAt).toLocaleDateString('zh-CN')}
+              </Text>
+            </View>
+          </View>
+
+          {/* 统计信息 */}
+          <View className="px-6">
+            <View className="grid grid-cols-3 gap-4 text-center">
+              <View className="bg-gray-50 rounded-xl p-4">
+                <Text className="text-2xl font-bold text-blue-500">0</Text>
+                <Text className="text-xs text-gray-600 mt-1">收藏</Text>
+              </View>
+              <View className="bg-gray-50 rounded-xl p-4">
+                <Text className="text-2xl font-bold text-green-500">0</Text>
+                <Text className="text-xs text-gray-600 mt-1">点赞</Text>
+              </View>
+              <View className="bg-gray-50 rounded-xl p-4">
+                <Text className="text-2xl font-bold text-purple-500">0</Text>
+                <Text className="text-xs text-gray-600 mt-1">关注</Text>
+              </View>
+            </View>
+          </View>
+        </View>
+
+        {/* 功能菜单 */}
+        <View className="px-4 pt-6">
+          <View className="bg-white rounded-2xl shadow-sm overflow-hidden">
+            {menuItems.map((item, index) => (
+              <View
+                key={index}
+                className="flex items-center px-4 py-4 active:bg-gray-50 transition-colors duration-150"
+                onClick={item.onClick}
+              >
+                <View className={cn("w-6 h-6 mr-3", item.color, item.icon)} />
+                <Text className="flex-1 text-gray-800">{item.title}</Text>
+                <View className="i-heroicons-chevron-right-20-solid w-5 h-5 text-gray-400" />
+              </View>
+            ))}
+          </View>
+        </View>
+
+        {/* 账号信息 */}
+        <View className="px-4 pt-6">
+          <View className="bg-white rounded-2xl shadow-sm p-4">
+            <Text className="text-sm font-medium text-gray-700 mb-3">账号信息</Text>
+            <View className="space-y-3">
+              <View className="flex justify-between items-center">
+                <Text className="text-sm text-gray-600">用户ID</Text>
+                <Text className="text-sm text-gray-900 font-mono">{userProfile.id}</Text>
+              </View>
+              {userProfile.lastLoginAt && (
+                <View className="flex justify-between items-center">
+                  <Text className="text-sm text-gray-600">最近登录</Text>
+                  <Text className="text-sm text-gray-900">
+                    {new Date(userProfile.lastLoginAt).toLocaleString('zh-CN')}
+                  </Text>
+                </View>
+              )}
+            </View>
+          </View>
+        </View>
+
+        {/* 退出登录按钮 */}
+        <View className="px-4 pt-6 pb-8">
+          <Button
+            className="w-full h-12 bg-red-500 text-white rounded-xl font-medium hover:bg-red-600 active:bg-red-700 transition-colors duration-200"
+            onClick={handleLogout}
+          >
+            <View className="flex items-center justify-center">
+              <View className="i-heroicons-arrow-left-on-rectangle-20-solid w-5 h-5 mr-2" />
+              退出登录
+            </View>
+          </Button>
+        </View>
+
+        {/* 版本信息 */}
+        <View className="pb-8">
+          <Text className="text-center text-xs text-gray-400">
+            v1.0.0 - 小程序版
+          </Text>
         </View>
-      </View>
+      </ScrollView>
     </TabBarLayout>
   )
 }

+ 148 - 98
mini/src/pages/register/index.tsx

@@ -1,17 +1,18 @@
 import { View, Input, Button, Text, Image } from '@tarojs/components'
 import { useState, useEffect } from 'react'
 import Taro from '@tarojs/taro'
-import { useAuth } from '@/utils/auth' // 导入 useAuth Hook
-import './index.css'
+import { useAuth } from '@/utils/auth'
+import { cn } from '@/utils/cn'
 
 export default function Register() {
   const [username, setUsername] = useState('')
   const [email, setEmail] = useState('')
   const [password, setPassword] = useState('')
   const [confirmPassword, setConfirmPassword] = useState('')
-  const { register, isLoading } = useAuth() // 使用 useAuth 获取注册方法和加载状态
+  const [showPassword, setShowPassword] = useState(false)
+  const [showConfirmPassword, setShowConfirmPassword] = useState(false)
+  const { register, isLoading } = useAuth()
 
-  // 设置导航栏标题
   useEffect(() => {
     Taro.setNavigationBarTitle({
       title: '创建账号'
@@ -65,7 +66,6 @@ export default function Register() {
       return
     }
 
-    // 邮箱格式验证(如果填写了邮箱)
     if (email.trim() && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim())) {
       Taro.showToast({
         title: '请输入有效的邮箱地址',
@@ -76,13 +76,11 @@ export default function Register() {
     }
 
     try {
-      // 显示加载动画
       Taro.showLoading({
         title: '注册中...',
         mask: true
       })
 
-      // 使用 useAuth 提供的 register 方法
       await register({
         username: username.trim(),
         password: password.trim(),
@@ -97,7 +95,6 @@ export default function Register() {
         duration: 1500
       })
       
-      // 注册成功后跳转到首页
       setTimeout(() => {
         Taro.switchTab({ url: '/pages/index/index' })
       }, 1500)
@@ -118,103 +115,156 @@ export default function Register() {
   }
 
   return (
-    <View className="register-container">
-      <View className="register-header">
-        <Image 
-          className="register-logo"
-          src="https://source.unsplash.com/200x200/?avatar"
-          mode="aspectFit"
-        />
-        <View className="register-title-container">
-          <Text className="register-title">创建账号</Text>
-          <Text className="register-subtitle">欢迎加入我们的小程序</Text>
-        </View>
-      </View>
-      
-      <View className="register-form">
-        <View className="form-item">
-          <Text className="form-label">用户名</Text>
-          <View className="input-wrapper">
-            <Input
-              className="form-input"
-              placeholder="请输入用户名(3-20个字符)"
-              value={username}
-              onInput={(e) => setUsername(e.detail.value)}
-              maxlength={20}
-            />
-          </View>
-        </View>
-        
-        <View className="form-item">
-          <Text className="form-label">邮箱(可选)</Text>
-          <View className="input-wrapper">
-            <Input
-              className="form-input"
-              placeholder="请输入邮箱地址"
-              type="text"
-              value={email}
-              onInput={(e) => setEmail(e.detail.value)}
-              maxlength={50}
-            />
+    <View className="min-h-screen bg-gradient-to-br from-green-50 via-white to-emerald-50">
+      <View className="flex-1 px-6 py-12">
+        {/* Logo区域 */}
+        <View className="flex flex-col items-center mb-10">
+          <View className="w-20 h-20 mb-4 rounded-full bg-white shadow-lg flex items-center justify-center">
+            <View className="i-heroicons-user-plus-20-solid w-12 h-12 text-green-500" />
           </View>
+          <Text className="text-2xl font-bold text-gray-900 mb-1">创建账号</Text>
+          <Text className="text-gray-600 text-sm">欢迎加入我们的小程序社区</Text>
         </View>
-        
-        <View className="form-item">
-          <Text className="form-label">密码</Text>
-          <View className="input-wrapper">
-            <Input
-              className="form-input"
-              placeholder="请输入密码(至少6位)"
-              password
-              value={password}
-              onInput={(e) => setPassword(e.detail.value)}
-              maxlength={20}
-            />
+
+        {/* 注册表单 */}
+        <View className="bg-white rounded-2xl shadow-sm p-6">
+          <View className="space-y-5">
+            {/* 用户名输入框 */}
+            <View className="space-y-2">
+              <Text className="text-sm font-medium text-gray-700">用户名</Text>
+              <View className="relative">
+                <View className="absolute left-3 top-1/2 -translate-y-1/2">
+                  <View className="i-heroicons-user-20-solid w-5 h-5 text-gray-400" />
+                </View>
+                <Input
+                  className="w-full h-12 pl-10 pr-4 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
+                  placeholder="请输入用户名(3-20个字符)"
+                  value={username}
+                  onInput={(e) => setUsername(e.detail.value)}
+                  maxlength={20}
+                />
+              </View>
+            </View>
+
+            {/* 邮箱输入框 */}
+            <View className="space-y-2">
+              <Text className="text-sm font-medium text-gray-700">邮箱(可选)</Text>
+              <View className="relative">
+                <View className="absolute left-3 top-1/2 -translate-y-1/2">
+                  <View className="i-heroicons-envelope-20-solid w-5 h-5 text-gray-400" />
+                </View>
+                <Input
+                  className="w-full h-12 pl-10 pr-4 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
+                  placeholder="请输入邮箱地址"
+                  type="text"
+                  value={email}
+                  onInput={(e) => setEmail(e.detail.value)}
+                  maxlength={50}
+                />
+              </View>
+            </View>
+
+            {/* 密码输入框 */}
+            <View className="space-y-2">
+              <Text className="text-sm font-medium text-gray-700">密码</Text>
+              <View className="relative">
+                <View className="absolute left-3 top-1/2 -translate-y-1/2">
+                  <View className="i-heroicons-lock-closed-20-solid w-5 h-5 text-gray-400" />
+                </View>
+                <Input
+                  className="w-full h-12 pl-10 pr-12 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
+                  placeholder="请输入密码(至少6位)"
+                  password={!showPassword}
+                  value={password}
+                  onInput={(e) => setPassword(e.detail.value)}
+                  maxlength={20}
+                />
+                <View 
+                  className="absolute right-3 top-1/2 -translate-y-1/2"
+                  onClick={() => setShowPassword(!showPassword)}
+                >
+                  <View className={cn(
+                    "w-5 h-5 text-gray-400",
+                    showPassword ? "i-heroicons-eye-20-solid" : "i-heroicons-eye-slash-20-solid"
+                  )} />
+                </View>
+              </View>
+            </View>
+
+            {/* 确认密码输入框 */}
+            <View className="space-y-2">
+              <Text className="text-sm font-medium text-gray-700">确认密码</Text>
+              <View className="relative">
+                <View className="absolute left-3 top-1/2 -translate-y-1/2">
+                  <View className="i-heroicons-lock-closed-20-solid w-5 h-5 text-gray-400" />
+                </View>
+                <Input
+                  className="w-full h-12 pl-10 pr-12 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
+                  placeholder="请再次输入密码"
+                  password={!showConfirmPassword}
+                  value={confirmPassword}
+                  onInput={(e) => setConfirmPassword(e.detail.value)}
+                  maxlength={20}
+                />
+                <View 
+                  className="absolute right-3 top-1/2 -translate-y-1/2"
+                  onClick={() => setShowConfirmPassword(!showConfirmPassword)}
+                >
+                  <View className={cn(
+                    "w-5 h-5 text-gray-400",
+                    showConfirmPassword ? "i-heroicons-eye-20-solid" : "i-heroicons-eye-slash-20-solid"
+                  )} />
+                </View>
+              </View>
+            </View>
+
+            {/* 注册按钮 */}
+            <Button
+              className={cn(
+                "w-full h-12 rounded-lg font-medium text-white transition-all duration-200",
+                isLoading || !username || !password || !confirmPassword
+                  ? "bg-gray-300 cursor-not-allowed"
+                  : "bg-green-500 hover:bg-green-600 active:bg-green-700 shadow-lg"
+              )}
+              loading={isLoading}
+              onClick={handleRegister}
+              disabled={isLoading || !username || !password || !confirmPassword}
+            >
+              {isLoading ? (
+                <View className="flex items-center justify-center">
+                  <View className="i-heroicons-arrow-path-20-solid animate-spin w-5 h-5 mr-2" />
+                  注册中...
+                </View>
+              ) : (
+                '立即注册'
+              )}
+            </Button>
           </View>
-        </View>
-        
-        <View className="form-item">
-          <Text className="form-label">确认密码</Text>
-          <View className="input-wrapper">
-            <Input
-              className="form-input"
-              placeholder="请再次输入密码"
-              password
-              value={confirmPassword}
-              onInput={(e) => setConfirmPassword(e.detail.value)}
-              maxlength={20}
-            />
+
+          {/* 登录链接 */}
+          <View className="mt-6 text-center">
+            <Text className="text-sm text-gray-600">
+              已有账号? 
+              <Text 
+                className="text-green-500 font-medium hover:text-green-600" 
+                onClick={goToLogin}
+              >
+                立即登录
+              </Text>
+            </Text>
           </View>
         </View>
-        
-        <Button
-          className={`register-button ${isLoading ? 'loading' : ''}`}
-          loading={isLoading}
-          onClick={handleRegister}
-          disabled={isLoading || !username || !password || !confirmPassword}
-        >
-          {isLoading ? '注册中...' : '立即注册'}
-        </Button>
-        
-        <View className="register-footer">
-          <Text className="footer-text">
-            已有账号? 
-            <Text className="link-text" onClick={goToLogin}>
-              立即登录
-            </Text>
+
+        {/* 协议声明 */}
+        <View className="mt-8 text-center">
+          <Text className="text-xs text-gray-500">
+            注册即表示您同意
+            <Text className="text-green-500 mx-1">用户协议</Text>
+            和
+            <Text className="text-green-500 mx-1">隐私政策</Text>
           </Text>
         </View>
       </View>
-      
-      <View className="register-footer-info">
-        <Text className="footer-tip">注册即表示您同意我们的</Text>
-        <View className="footer-links">
-          <Text className="link-text">用户协议</Text>
-          <Text className="link-separator">和</Text>
-          <Text className="link-text">隐私政策</Text>
-        </View>
-      </View>
     </View>
   )
-}
-    
+}