Эх сурвалжийг харах

feat: 登录注册获取用户信息接口调试

liangan 3 долоо хоног өмнө
parent
commit
eb16bc1078

+ 2 - 2
env/.env

@@ -10,7 +10,7 @@ VITE_APP_PUBLIC_BASE=/
 # 登录页面
 VITE_LOGIN_URL = '/pages/login/index'
 # 第一个请求地址
-VITE_SERVER_BASEURL = 'http://192.168.0.100:8101'
+VITE_SERVER_BASEURL = 'http://124.222.152.234:8101'
 # 第二个请求地址
 VITE_API_SECONDARY_URL = 'https://ukw0y1.laf.run'
 
@@ -27,5 +27,5 @@ VITE_UPLOAD_BASEURL__WEIXIN_TRIAL = 'https://ukw0y1.laf.run/upload'
 VITE_UPLOAD_BASEURL__WEIXIN_RELEASE = 'https://ukw0y1.laf.run/upload'
 
 # h5是否需要配置代理
-VITE_APP_PROXY=true
+VITE_APP_PROXY=false
 VITE_APP_PROXY_PREFIX = '/api'

+ 12 - 7
src/api/login.ts

@@ -1,14 +1,12 @@
-import type { ICaptcha, IUpdateInfo, IUpdatePassword, IUserInfoVo, IUserLogin } from './types/login'
+import type { ICaptcha, IUpdateInfo, IUpdatePassword, IUserLogin } from './types/login'
 import { http } from '@/utils/http'
 
 /**
  * 登录表单
  */
 export interface ILoginForm {
-  username: string
-  password: string
-  code: string
-  uuid: string
+  account: string
+  pwd: string
 }
 
 /**
@@ -19,19 +17,26 @@ export function getCode() {
   return http.get<ICaptcha>('/user/getCode')
 }
 
+/**
+ * 用户注册
+ * @param registerForm 注册表单
+ */
+export function register(registerForm: any) {
+  return http.post<any>('/cif/api/user/register', registerForm)
+}
 /**
  * 用户登录
  * @param loginForm 登录表单
  */
 export function login(loginForm: ILoginForm) {
-  return http.post<IUserLogin>('/user/login', loginForm)
+  return http.post<IUserLogin>('/cif/api/user/login', loginForm)
 }
 
 /**
  * 获取用户信息
  */
 export function getUserInfo() {
-  return http.get<IUserInfoVo>('/user/info')
+  return http.get<any>('/cif/api/user/getUserInfo')
 }
 
 /**

+ 9 - 6
src/interceptors/request.ts

@@ -1,4 +1,3 @@
-import { useUserStore } from '@/store'
 import { getEnvBaseUrl } from '@/utils'
 import { platform } from '@/utils/platform'
 import { stringifyQuery } from '@/utils/queryString'
@@ -51,11 +50,15 @@ const httpInterceptor = {
       platform, // 可选,与 uniapp 定义的平台一致,告诉后台来源
       ...options.header,
     }
-    // 3. 添加 token 请求头标识
-    const userStore = useUserStore()
-    const { token } = userStore.userInfo as unknown as IUserInfo
-    if (token) {
-      options.header.Authorization = `Bearer ${token}`
+    // 判断是否为登录接口
+    const isLoginApi = options.url?.includes('/login') || options.url?.includes('/register')
+
+    // 如果不是登录接口,添加 token 请求头
+    if (!isLoginApi) {
+      const token = uni.getStorageSync('token')
+      if (token) {
+        options.header.Token = token
+      }
     }
   },
 }

+ 82 - 16
src/pages/login/login.vue

@@ -8,9 +8,13 @@
 </route>
 
 <script lang="ts" setup>
+import type { ILoginForm } from '@/api/login'
 // 必须导入需要用到的页面生命周期(即使在当前页面上没有直接使用到)
 // eslint-disable-next-line unused-imports/no-unused-imports
 import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
+import { login } from '@/api/login'
+import { useUserStore } from '@/store/user'
+import { toast } from '@/utils/toast'
 
 defineOptions({
   name: 'Login', // 登录
@@ -20,27 +24,89 @@ defineOptions({
 const systemInfo = uni.getSystemInfoSync()
 const safeAreaInsets = systemInfo.safeAreaInsets
 
+// 用户状态管理
+const userStore = useUserStore()
+
 // 表单数据
 const formData = ref({
   username: '',
   password: '',
 })
 
-// 表单验证规则
-const rules = {
-  username: [
-    { required: true, message: 'Please enter mobile number or username' },
-  ],
-  password: [
-    { required: true, message: 'Please enter password' },
-    { min: 6, max: 20, message: 'Password should be 6-20 characters' },
-  ],
+// 登录处理
+async function handleLogin() {
+  try {
+    // 表单验证
+    const isValid = await validateForm()
+    if (!isValid)
+      return
+
+    // 显示加载状态
+    uni.showLoading({
+      title: 'Logging in...',
+      mask: true,
+    })
+
+    // 准备登录数据,根据 ILoginForm 接口要求
+    const loginData: ILoginForm = {
+      account: formData.value.username,
+      pwd: formData.value.password,
+    }
+
+    // 调用登录接口
+    const res = await login(loginData)
+    uni.hideLoading()
+    // 登录成功,使用 userStore 管理用户状态和 token
+    uni.setStorageSync('token', res.data.token)
+    // 使用状态管理工具设置用户信息,会自动处理 token 存储
+    userStore.getUserInfo()
+    // 登录成功提示
+    toast.success('Login successful!')
+  }
+  catch (error) {
+    uni.hideLoading()
+    uni.showToast({
+      title: error.message || 'Login failed',
+      icon: 'none',
+    })
+  }
 }
 
-// 登录处理
-function handleLogin() {
-  // TODO: 实现登录逻辑
-  console.log('Login:', formData.value)
+// 表单验证
+function validateForm() {
+  return new Promise((resolve) => {
+    // 验证用户名
+    if (!formData.value.username.trim()) {
+      uni.showToast({
+        title: 'Please enter username or phone number',
+        icon: 'none',
+      })
+      resolve(false)
+      return
+    }
+
+    // 验证密码
+    if (!formData.value.password.trim()) {
+      uni.showToast({
+        title: 'Please enter password',
+        icon: 'none',
+      })
+      resolve(false)
+      return
+    }
+
+    // 验证密码长度
+    if (formData.value.password.length < 6 || formData.value.password.length > 20) {
+      uni.showToast({
+        title: 'Password should be 6-20 characters',
+        icon: 'none',
+      })
+      resolve(false)
+      return
+    }
+
+    resolve(true)
+  })
 }
 
 // 跳转注册页
@@ -87,7 +153,7 @@ function goBack() {
       <view class="mb-40rpx" />
 
       <!-- 登录表单 -->
-      <wd-form ref="form" :model="formData" :rules="rules">
+      <wd-form ref="form" :model="formData">
         <view class="mb-40rpx space-y-32rpx">
           <wd-input
             v-model="formData.username"
@@ -99,9 +165,9 @@ function goBack() {
           <wd-input
             v-model="formData.password"
             prop="password"
-            show-password
+
             placeholder="Password 6-20 characters"
-            no-border
+            no-border show-password
             custom-class="bandhu-auth-input-field"
           />
         </view>

+ 1 - 1
src/pages/mine/mine.vue

@@ -61,7 +61,7 @@ const menuList = ref([
       </view> -->
       <!-- 未登录 -->
       <view class="ml-24rpx">
-        <wd-button size="small" custom-class="mr-20rpx! bg-transparent!" plain>
+        <wd-button size="small" custom-class="mr-20rpx! bg-transparent!" plain @click="toPage('/pages/register/register')">
           Register
         </wd-button>
         <wd-button size="small">

+ 101 - 42
src/pages/register/register.vue

@@ -8,9 +8,8 @@
 </route>
 
 <script lang="ts" setup>
-// 必须导入需要用到的页面生命周期(即使在当前页面上没有直接使用到)
-// eslint-disable-next-line unused-imports/no-unused-imports
-import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
+import { register } from '@/api/login'
+import { toast } from '@/utils/toast'
 
 defineOptions({
   name: 'Register', // 注册
@@ -22,47 +21,29 @@ const safeAreaInsets = systemInfo.safeAreaInsets
 
 // 表单数据
 const formData = ref({
-  username: '',
-  mobile: '',
+  name: '',
+  phone: '',
   verificationCode: '',
-  password: '',
-  referrerCode: '',
+  pwd: '',
+  code: '',
 })
 
 // 验证码倒计时
 const countdown = ref(0)
-const countdownTimer = ref<NodeJS.Timeout | null>(null)
-
-// 表单验证规则
-const rules = {
-  username: [
-    { required: true, message: 'Please enter username' },
-  ],
-  mobile: [
-    { required: true, message: 'Please enter mobile number' },
-    { pattern: /^1[3-9]\d{9}$/, message: 'Please enter valid mobile number' },
-  ],
-  verificationCode: [
-    { required: true, message: 'Please enter verification code' },
-  ],
-  password: [
-    { required: true, message: 'Please enter password' },
-    { min: 6, max: 20, message: 'Password should be 6-20 characters' },
-  ],
-}
+const countdownTimer = ref<any>(null)
 
 // 获取验证码
 function getVerificationCode() {
-  if (!formData.value.mobile) {
+  if (!formData.value.phone) {
     uni.showToast({
-      title: 'Please enter mobile number first',
+      title: 'Please enter phone number first',
       icon: 'none',
     })
     return
   }
 
   // TODO: 实现获取验证码逻辑
-  console.log('Get verification code for:', formData.value.mobile)
+  console.log('Get verification code for:', formData.value.phone)
 
   // 开始倒计时
   countdown.value = 60
@@ -76,9 +57,87 @@ function getVerificationCode() {
 }
 
 // 注册处理
-function handleRegister() {
-  // TODO: 实现注册逻辑
-  console.log('Register:', formData.value)
+async function handleRegister() {
+  try {
+    // 表单验证
+    const isValid = await validateForm()
+    if (!isValid)
+      return
+
+    // 显示加载状态
+    uni.showLoading({
+      title: 'Registering...',
+      mask: true,
+    })
+
+    // 调用注册接口
+    const registerData = {
+      name: formData.value.name,
+      phone: formData.value.phone,
+      verificationCode: formData.value.verificationCode,
+      pwd: formData.value.pwd,
+      code: formData.value.code,
+    }
+
+    await register(registerData)
+
+    uni.hideLoading()
+    // 注册成功
+    toast.info('Registration successful!')
+    setTimeout(() => {
+      uni.navigateTo({ url: '/pages/login/login' })
+    }, 1500)
+  }
+  catch (error) {
+    uni.hideLoading()
+    toast.error(error.message || 'Registration failed')
+  }
+}
+
+// 表单验证
+function validateForm() {
+  return new Promise((resolve) => {
+    // 验证必填字段
+    if (!formData.value.name.trim()) {
+      toast.info('Please enter name')
+      resolve(false)
+      return
+    }
+
+    if (!formData.value.phone.trim()) {
+      toast.info('Please enter phone number')
+      resolve(false)
+      return
+    }
+
+    // 验证手机号格式
+    if (!formData.value.phone.trim()) {
+      toast.info('Please enter valid phone number')
+      resolve(false)
+      return
+    }
+
+    if (!formData.value.verificationCode.trim()) {
+      toast.info('Please enter verification code')
+      resolve(false)
+      return
+    }
+
+    if (!formData.value.pwd.trim()) {
+      toast.info('Please enter password')
+      resolve(false)
+      return
+    }
+
+    // 验证密码长度
+    if (formData.value.pwd.length < 6 || formData.value.pwd.length > 20) {
+      toast.info('Password should be 6-20 characters')
+      resolve(false)
+      return
+    }
+
+    resolve(true)
+  })
 }
 
 // 跳转登录页
@@ -125,18 +184,18 @@ onUnmounted(() => {
       <view class="mb-40rpx" />
 
       <!-- 注册表单 -->
-      <wd-form ref="form" :model="formData" :rules="rules">
+      <wd-form ref="form" :model="formData">
         <view class="mb-40rpx space-y-32rpx">
           <wd-input
-            v-model="formData.username"
-            prop="username"
+            v-model="formData.name"
+            prop="name"
             placeholder="Username"
             no-border
             custom-class="bandhu-auth-input-field"
           />
           <wd-input
-            v-model="formData.mobile"
-            prop="mobile"
+            v-model="formData.phone"
+            prop="phone"
             placeholder="+88 Mobile number"
             no-border
             custom-class="bandhu-auth-input-field"
@@ -160,15 +219,15 @@ onUnmounted(() => {
             </wd-button>
           </view>
           <wd-input
-            v-model="formData.password"
-            prop="password"
-
+            v-model="formData.pwd"
+            prop="pwd"
             placeholder="Password 6-20 characters"
-            no-border show-password
+            no-border
+            show-password
             custom-class="bandhu-auth-input-field"
           />
           <wd-input
-            v-model="formData.referrerCode"
+            v-model="formData.code"
             placeholder="Referrer Code"
             no-border
             custom-class="bandhu-auth-input-field"

+ 8 - 72
src/store/user.ts

@@ -1,19 +1,11 @@
-import type { IUserInfoVo } from '@/api/types/login'
 import { defineStore } from 'pinia'
 import { ref } from 'vue'
-import {
-  getUserInfo as _getUserInfo,
-  login as _login,
-  logout as _logout,
-  wxLogin as _wxLogin,
-  getWxCode,
-} from '@/api/login'
-import { toast } from '@/utils/toast'
+import { getUserInfo as _getUserInfo } from '@/api/login'
 
 // 初始化状态
-const userInfoState: IUserInfoVo = {
+const userInfoState: any = {
   id: 0,
-  username: '',
+  name: '',
   avatar: '/static/images/default-avatar.png',
   token: '',
 }
@@ -22,23 +14,11 @@ export const useUserStore = defineStore(
   'user',
   () => {
     // 定义用户信息
-    const userInfo = ref<IUserInfoVo>({ ...userInfoState })
+    const userInfo = ref<any>({ ...userInfoState })
     // 设置用户信息
-    const setUserInfo = (val: IUserInfoVo) => {
+    const setUserInfo = (val: any) => {
       console.log('设置用户信息', val)
-      // 若头像为空 则使用默认头像
-      if (!val.avatar) {
-        val.avatar = userInfoState.avatar
-      }
-      else {
-        val.avatar = 'https://oss.laf.run/ukw0y1-site/avatar.jpg?feige'
-      }
-      userInfo.value = val
-    }
-    const setUserAvatar = (avatar: string) => {
-      userInfo.value.avatar = avatar
-      console.log('设置用户头像', avatar)
-      console.log('userInfo', userInfo.value)
+      userInfo.value = { ...userInfo, val }
     }
     // 删除用户信息
     const removeUserInfo = () => {
@@ -54,58 +34,14 @@ export const useUserStore = defineStore(
       const userInfo = res.data
       setUserInfo(userInfo)
       uni.setStorageSync('userInfo', userInfo)
-      uni.setStorageSync('token', userInfo.token)
-      // TODO 这里可以增加获取用户路由的方法 根据用户的角色动态生成路由
-      return res
-    }
-    /**
-     * 用户登录
-     * @param credentials 登录参数
-     * @returns R<IUserLogin>
-     */
-    const login = async (credentials: {
-      username: string
-      password: string
-      code: string
-      uuid: string
-    }) => {
-      const res = await _login(credentials)
-      console.log('登录信息', res)
-      toast.success('登录成功')
-      await getUserInfo()
-      return res
-    }
-
-    /**
-     * 退出登录 并 删除用户信息
-     */
-    const logout = async () => {
-      _logout()
-      removeUserInfo()
-    }
-    /**
-     * 微信登录
-     */
-    const wxLogin = async () => {
-      // 获取微信小程序登录的code
-      const data = await getWxCode()
-      console.log('微信登录code', data)
-
-      const res = await _wxLogin(data)
-      await getUserInfo()
       return res
     }
 
     return {
       userInfo,
-      login,
-      wxLogin,
       getUserInfo,
-      setUserAvatar,
-      logout,
+      setUserInfo,
+      removeUserInfo,
     }
   },
-  {
-    persist: true,
-  },
 )