login.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <route lang="json5" type="page">
  2. {
  3. layout: 'default',
  4. style: {
  5. navigationStyle: 'custom',
  6. },
  7. }
  8. </route>
  9. <script lang="ts" setup>
  10. import { t } from '@/locale'
  11. import { useUserStore } from '@/store/user'
  12. import { goBack, toPage } from '@/utils/page'
  13. import { toast } from '@/utils/toast'
  14. defineOptions({
  15. name: 'Login', // 登录
  16. })
  17. // 获取屏幕边界到安全区域距离
  18. const systemInfo = uni.getSystemInfoSync()
  19. const safeAreaInsets = systemInfo.safeAreaInsets
  20. // 用户状态管理
  21. const userStore = useUserStore()
  22. // 表单数据
  23. const formData = ref({
  24. username: '',
  25. password: '',
  26. })
  27. // 表单验证
  28. function validateForm() {
  29. return new Promise((resolve) => {
  30. // 验证用户名
  31. if (!formData.value.username.trim()) {
  32. toast.error(t('auth.login.error.emptyUsername'))
  33. resolve(false)
  34. return
  35. }
  36. // 验证密码
  37. if (!formData.value.password.trim()) {
  38. toast.error(t('auth.login.error.emptyPassword'))
  39. resolve(false)
  40. return
  41. }
  42. // 验证密码长度
  43. if (formData.value.password.length < 6 || formData.value.password.length > 20) {
  44. toast.error(t('auth.login.error.passwordLength'))
  45. resolve(false)
  46. return
  47. }
  48. resolve(true)
  49. })
  50. }
  51. // 登录处理
  52. async function handleLogin() {
  53. try {
  54. // 表单验证
  55. const isValid = await validateForm()
  56. if (!isValid)
  57. return
  58. // 准备登录数据
  59. const loginData = {
  60. account: formData.value.username,
  61. pwd: formData.value.password,
  62. }
  63. // 获取页面参数中的跳转地址(如果有的话)
  64. const pages = getCurrentPages()
  65. const currentPage = pages[pages.length - 1] as any
  66. const redirectUrl = currentPage?.options?.redirect
  67. // 调用 userStore 中的登录方法,传入跳转地址
  68. await userStore.login(loginData, redirectUrl)
  69. }
  70. catch (error) {
  71. // 错误处理已在 userStore.login 中处理
  72. console.error('Login error:', error)
  73. }
  74. }
  75. </script>
  76. <template>
  77. <view class="login-page min-h-screen bg-white">
  78. <!-- 背景图片区域 -->
  79. <view class="auth-bg-section relative">
  80. <!-- 自定义导航栏 -->
  81. <view :style="{ paddingTop: `${safeAreaInsets?.top}px` }">
  82. <view class="h-88rpx flex items-center px-24rpx">
  83. <wd-icon name="thin-arrow-left" size="32rpx" @click="goBack" />
  84. </view>
  85. </view>
  86. <!-- Logo和标语 -->
  87. <view class="pb-60rpx pt-60rpx text-center">
  88. <view class="mb-20rpx flex items-center justify-center">
  89. <image src="/static/logo.png" class="mr-16rpx h-60rpx w-60rpx" />
  90. </view>
  91. </view>
  92. </view>
  93. <!-- 表单内容区域 -->
  94. <view class="flex flex-col px-20rpx">
  95. <view class="mb-40rpx" />
  96. <!-- 登录表单 -->
  97. <wd-form ref="form" :model="formData">
  98. <view class="mb-40rpx space-y-32rpx">
  99. <wd-input
  100. v-model="formData.username"
  101. prop="username"
  102. :placeholder="t('auth.login.username.placeholder')"
  103. no-border
  104. custom-class="bandhu-auth-input-field"
  105. />
  106. <wd-input
  107. v-model="formData.password"
  108. prop="password"
  109. :placeholder="t('auth.login.password.placeholder')"
  110. no-border show-password
  111. custom-class="bandhu-auth-input-field"
  112. />
  113. </view>
  114. <!-- 登录按钮 -->
  115. <wd-button
  116. type="error"
  117. size="large"
  118. custom-class="mb-60rpx w-full bandhu-auth-primary-btn"
  119. @click="handleLogin"
  120. >
  121. {{ t('auth.login.button') }}
  122. </wd-button>
  123. </wd-form>
  124. <!-- 注册提示 -->
  125. <view class="mb-200rpx text-center">
  126. <text class="text-28rpx text-#5C5C5C">
  127. {{ t('auth.login.noAccount') }}
  128. </text>
  129. <view class="mt-52rpx">
  130. <wd-button
  131. type="error"
  132. plain
  133. custom-style="width: 200rpx; height: 72rpx; border-radius: 36rpx; font-size: 28rpx;"
  134. @click="toPage('/pages/register/register')"
  135. >
  136. {{ t('auth.login.register') }}
  137. </wd-button>
  138. </view>
  139. </view>
  140. <!-- 忘记密码 -->
  141. <view class="text-center">
  142. <text class="text-28rpx text-#5C5C5C" @click="toPage('/pages/forgotPassword/forgotPassword')">
  143. {{ t('auth.login.forgotPassword') }}
  144. </text>
  145. </view>
  146. </view>
  147. </view>
  148. </template>
  149. <style lang="scss" scoped>
  150. // 登录页面特有样式(如果有的话)
  151. </style>