diff --git a/src/common/apis/ab98/index.ts b/src/common/apis/ab98/index.ts
new file mode 100644
index 0000000..999be28
--- /dev/null
+++ b/src/common/apis/ab98/index.ts
@@ -0,0 +1,55 @@
+import { request } from '@/http/axios'
+import {
+  GetTokenParams,
+  LoginData,
+  LogoutResponse,
+  SmsSendResponse,
+  TokenResponse,
+  VerifySmsParams,
+  WechatQrCodeParams
+} from './type'
+
+/** 获取临时令牌 */
+export function getTokenApi(appName: string) {
+  return request<ApiResponseData<TokenResponse>>({
+    url: '/api/wx/login/getToken',
+    method: 'get',
+    params: { appName }
+  })
+}
+
+/** 获取微信登录二维码 */
+export function getWechatQrCodeApi(token: string) {
+  return request<ApiResponseData<string>>({
+    url: '/api/wx/login/wechat/qrcode',
+    method: 'get',
+    params: { token }
+  })
+}
+
+/** 发送短信验证码 */
+export function sendSmsApi(token: string, tel: string) {
+  return request<ApiResponseData<SmsSendResponse>>({
+    url: '/api/wx/login/sendSms',
+    method: 'post',
+    params: { token, tel }
+  })
+}
+
+/** 验证短信验证码 */
+export function verifySmsApi(params: VerifySmsParams) {
+  return request<ApiResponseData<LoginData>>({
+    url: '/api/wx/login/verifySms',
+    method: 'post',
+    params
+  })
+}
+
+/** 用户退出登录 */
+export function logoutApi(token: string) {
+  return request<ApiResponseData<LogoutResponse>>({
+    url: '/api/wx/login/logout',
+    method: 'post',
+    params: { token }
+  })
+}
\ No newline at end of file
diff --git a/src/common/apis/ab98/type.ts b/src/common/apis/ab98/type.ts
new file mode 100644
index 0000000..44d9025
--- /dev/null
+++ b/src/common/apis/ab98/type.ts
@@ -0,0 +1,59 @@
+/** 令牌响应 */
+export interface TokenResponse {
+  /** 认证令牌 */
+  token: string
+}
+
+/** 退出登录响应 */
+export interface LogoutResponse {
+  /** 是否成功 */
+  success: boolean
+}
+
+/** 短信发送响应 */
+export interface SmsSendResponse {
+  /** 发送状态 */
+  success: boolean
+  /** 错误信息 */
+  message?: string
+}
+
+/** 登录数据 */
+export interface LoginData {
+  /** 用户头像 */
+  face_img: string
+  /** 登录状态 */
+  success: boolean
+  /** 用户性别 */
+  sex: string
+  /** 用户姓名 */
+  name: string
+  /** 用户ID */
+  userid: string
+  /** 是否已注册 */
+  registered: boolean
+  /** 联系电话 */
+  tel: string
+}
+
+/** 获取令牌参数 */
+export type GetTokenParams = {
+  /** 应用名称 */
+  appName: string
+}
+
+/** 微信二维码参数 */
+export type WechatQrCodeParams = {
+  /** 认证令牌 */
+  token: string
+}
+
+/** 短信验证参数 */
+export type VerifySmsParams = {
+  /** 认证令牌 */
+  token: string
+  /** 手机号码 */
+  tel: string
+  /** 验证码 */
+  vcode: string
+}
\ No newline at end of file
diff --git a/src/layout/components/Tabbar.vue b/src/layout/components/Tabbar.vue
index 9a4b34f..310439a 100644
--- a/src/layout/components/Tabbar.vue
+++ b/src/layout/components/Tabbar.vue
@@ -3,7 +3,7 @@ const router = useRouter()
 
 const tabbarItemList = computed(() => {
   const routes = router.getRoutes()
-  return routes.filter(route => route.meta.layout?.tabbar?.showTabbar)
+  return routes.filter(route => route.meta.layout?.tabbar?.showTabbar && route.path !== '/cabinet')
   .map(route => ({
     title: route.meta.title,
     icon: route.meta.layout?.tabbar?.icon,
diff --git a/src/pages/login/Ab98Login.vue b/src/pages/login/Ab98Login.vue
new file mode 100644
index 0000000..ed12a61
--- /dev/null
+++ b/src/pages/login/Ab98Login.vue
@@ -0,0 +1,168 @@
+<script setup>
+import { ref } from 'vue'
+import { useRouter } from 'vue-router'
+import { verifySmsApi, sendSmsApi, getTokenApi } from '@/common/apis/ab98'
+import { useAb98UserStore } from '@/pinia/stores/ab98-user'
+import { showSuccessToast, showFailToast } from 'vant'
+
+const userStore = useAb98UserStore()
+const router = useRouter()
+
+// 表单数据
+const form = ref({
+  tel: '',
+  vcode: ''
+})
+
+// 验证规则
+const rules = {
+  tel: [
+    { required: true, message: '请输入手机号码', trigger: 'blur' },
+    { pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
+  ],
+  vcode: [
+    { required: true, message: '请输入验证码', trigger: 'blur' }
+  ]
+}
+
+// 倒计时状态
+const countdown = ref(0)
+const canSend = ref(true)
+
+// 发送验证码
+const handleSendSms = async () => {
+  if (!form.value.tel) {
+    showFailToast('请先输入手机号码')
+    return
+  }
+
+  try {
+    const { data: tokenData } = await getTokenApi('shop-web')
+    if (!tokenData?.success) {
+        showFailToast('获取token失败')
+      return
+    }
+    userStore.setToken(tokenData.data.token);
+
+    const { data } = await sendSmsApi(tokenData.data.token, form.value.tel)
+    if (data.success) {
+      showSuccessToast('验证码已发送')
+      startCountdown()
+    } else {
+        showFailToast(data.message || '发送失败')
+    }
+  } catch (error) {
+    showFailToast('发送验证码失败')
+  }
+}
+
+// 开始倒计时
+const startCountdown = () => {
+  canSend.value = false
+  countdown.value = 60
+  const timer = setInterval(() => {
+    if (countdown.value <= 0) {
+      clearInterval(timer)
+      canSend.value = true
+      return
+    }
+    countdown.value--
+  }, 1000)
+}
+
+// 提交登录
+const handleSubmit = async () => {
+  try {
+    const params = {
+      token: userStore.token,
+      tel: form.value.tel,
+      vcode: form.value.vcode
+    }
+
+    const { data } = await verifySmsApi(params)
+    if (data.success) {
+      userStore.setUserInfo(data)
+      ElMessage.success('登录成功')
+      router.push('/')
+    } else {
+      ElMessage.error('验证码错误或已过期')
+    }
+  } catch (error) {
+    ElMessage.error('登录失败')
+  }
+}
+</script>
+
+<template>
+  <div class="login-container">
+    <el-card class="login-box">
+      <h2 class="title">手机验证码登录</h2>
+      
+      <el-form 
+        :model="form"
+        :rules="rules"
+        label-width="80px"
+        label-position="top"
+      >
+        <el-form-item label="手机号码" prop="tel">
+          <el-input v-model="form.tel" placeholder="请输入手机号码" />
+        </el-form-item>
+
+        <el-form-item label="验证码" prop="vcode">
+          <div class="vcode-input">
+            <el-input 
+              v-model="form.vcode" 
+              placeholder="请输入验证码"
+              style="width: 60%"
+            />
+            <el-button 
+              :disabled="!canSend"
+              @click="handleSendSms"
+              style="margin-left: 10px; width: 35%"
+            >
+              {{ countdown > 0 ? `${countdown}秒后重试` : '获取验证码' }}
+            </el-button>
+          </div>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button 
+            type="primary"
+            @click="handleSubmit"
+            style="width: 100%"
+          >
+            立即登录
+          </el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<style scoped>
+.login-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  min-height: 100vh;
+  background-color: #f5f7fa;
+}
+
+.login-box {
+  width: 400px;
+  padding: 30px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+}
+
+.title {
+  text-align: center;
+  margin-bottom: 30px;
+  color: #303133;
+}
+
+.vcode-input {
+  display: flex;
+  align-items: center;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/me/index.vue b/src/pages/me/index.vue
index 61ece3a..c1e55da 100644
--- a/src/pages/me/index.vue
+++ b/src/pages/me/index.vue
@@ -1,17 +1,22 @@
 <script setup lang="ts">
 import { useRouter } from 'vue-router'
 import { useWxStore } from '@/pinia/stores/wx'
-import { computed } from 'vue'
+import { useAb98UserStore } from '@/pinia/stores/ab98-user'
+import { storeToRefs } from 'pinia'
 import { publicPath } from "@/common/utils/path"
 
 const router = useRouter()
 const wxStore = useWxStore()
-const balance = computed(() => wxStore.balance)
+const ab98UserStore = useAb98UserStore()
+
+const { balance } = storeToRefs(wxStore)
+const { name: userName, sex: userSex, face_img } = storeToRefs(ab98UserStore)
+
+const userAvatar = face_img.value ? face_img.value : `${publicPath}img/1.jpg`
 </script>
 
 <template>
   <div un-py-16px>
-    <!-- 用户信息区域 -->
     <van-cell-group class="user-card">
       <van-cell :border="false">
         <template #title>
@@ -20,13 +25,12 @@ const balance = computed(() => wxStore.balance)
               round
               width="80"
               height="80"
-              :src="`${publicPath}img/1.jpg`"
+              :src="userAvatar"
               class="mr-4"
             />
             <div>
-              <div class="text-lg font-bold mb-2">{{ '' }}</div>
-              <van-tag type="primary" class="mr-2">{{ 20 }}岁</van-tag>
-              <van-tag type="success">{{ '男' }}</van-tag>
+              <div class="text-lg font-bold mb-2">{{ userName }}</div>
+              <van-tag type="primary" class="mr-2">{{ userSex }}</van-tag>
             </div>
           </div>
         </template>
diff --git a/src/pages/product/components/checkout.vue b/src/pages/product/components/checkout.vue
index bc45ae4..b393938 100644
--- a/src/pages/product/components/checkout.vue
+++ b/src/pages/product/components/checkout.vue
@@ -155,7 +155,7 @@ async function handleSubmit() {
         <van-field label="支付方式" :model-value="selectedPayment" readonly>
           <template #input>
             <van-radio-group v-model="selectedPayment" direction="horizontal">
-              <van-radio name="wechat">
+              <van-radio name="wechat" v-if="!wxStore.corpid">
                 <van-icon name="wechat" class="method-icon" />
                 微信支付
               </van-radio>
diff --git a/src/pinia/stores/ab98-user.ts b/src/pinia/stores/ab98-user.ts
new file mode 100644
index 0000000..96a622b
--- /dev/null
+++ b/src/pinia/stores/ab98-user.ts
@@ -0,0 +1,123 @@
+import { pinia } from "@/pinia"
+import { LoginData } from "@/common/apis/ab98/type"
+
+// 本地存储键名常量
+const STORAGE_KEYS = {
+    FACE: 'ab98_face',
+    SEX: 'ab98_sex',
+    NAME: 'ab98_name',
+    USERID: 'ab98_userid',
+    REGISTERED: 'ab98_registered',
+    TEL: 'ab98_tel',
+    TOKEN: 'ab98_token'
+}
+
+/**
+ * AB98用户信息存储
+ * @description 管理AB98系统用户相关状态信息
+ */
+export const useAb98UserStore = defineStore("ab98User", () => {
+  // 用户面部图像URL
+  const storedFace = localStorage.getItem(STORAGE_KEYS.FACE)
+  const face_img = ref<string>(storedFace ? atob(storedFace) : '')
+  // 用户性别(男/女)
+  const storedSex = localStorage.getItem(STORAGE_KEYS.SEX)
+  const sex = ref<string>(storedSex ? atob(storedSex) : '')
+  // 用户真实姓名
+  const storedName = localStorage.getItem(STORAGE_KEYS.NAME)
+  const name = ref<string>(storedName ? atob(storedName) : '')
+  // AB98系统用户唯一标识
+  const storedUserId = localStorage.getItem(STORAGE_KEYS.USERID)
+  const userid = ref<string>(storedUserId ? atob(storedUserId) : "")
+  // 是否已完成注册流程
+  const registered = ref<boolean>(JSON.parse(localStorage.getItem(STORAGE_KEYS.REGISTERED) || "false"))
+  // 用户绑定手机号
+  const storedTel = localStorage.getItem(STORAGE_KEYS.TEL)
+  const tel = ref<string>(storedTel ? atob(storedTel) : "")
+  // 用户认证令牌
+  const storedToken = localStorage.getItem(STORAGE_KEYS.TOKEN)
+  const token = ref<string>(storedToken ? atob(storedToken) : "")
+  // 用户登录状态
+  const isLogin = ref<boolean>(false);
+  isLogin.value = tel.value ? true : false;
+
+  /**
+   * 更新用户基本信息
+   * @param data - 登录接口返回的用户数据
+   */
+  const setUserInfo = (data: LoginData) => {
+    face_img.value = data.face_img
+    localStorage.setItem(STORAGE_KEYS.FACE, btoa(data.face_img))
+    sex.value = data.sex
+    localStorage.setItem(STORAGE_KEYS.SEX, btoa(data.sex))
+    name.value = data.name
+    localStorage.setItem(STORAGE_KEYS.NAME, btoa(data.name))
+    userid.value = data.userid
+    localStorage.setItem(STORAGE_KEYS.USERID, btoa(data.userid))
+    registered.value = data.registered
+    localStorage.setItem(STORAGE_KEYS.REGISTERED, JSON.stringify(data.registered))
+    tel.value = data.tel
+    localStorage.setItem(STORAGE_KEYS.TEL, btoa(data.tel))
+  }
+
+  /**
+   * 清空用户敏感信息
+   * @description 用于用户登出或会话过期时
+   */
+  const clearUserInfo = () => {
+    face_img.value = ""
+    localStorage.removeItem(STORAGE_KEYS.FACE)
+    sex.value = ""
+    localStorage.removeItem(STORAGE_KEYS.SEX)
+    name.value = ""
+    localStorage.removeItem(STORAGE_KEYS.NAME)
+    userid.value = ""
+    localStorage.removeItem(STORAGE_KEYS.USERID)
+    registered.value = false
+    localStorage.removeItem(STORAGE_KEYS.REGISTERED)
+    tel.value = ""
+    localStorage.removeItem(STORAGE_KEYS.TEL)
+    localStorage.removeItem(STORAGE_KEYS.TOKEN)
+  }
+
+  /**
+   * 设置认证令牌
+   * @param value - JWT格式的认证令牌
+   */
+  const setToken = (value: string) => {
+    localStorage.setItem(STORAGE_KEYS.TOKEN, btoa(value))
+    token.value = value
+  }
+
+  const setTel = (value: string) => {
+    localStorage.setItem(STORAGE_KEYS.TEL, btoa(value))
+    tel.value = value
+  }
+
+  const setIsLogin = (value: boolean) => {
+    isLogin.value = value;
+  }
+
+  return { 
+    face_img,
+    sex,
+    name,
+    userid,
+    registered,
+    tel,
+    token,
+    isLogin,
+    setUserInfo,
+    setToken,
+    setTel,
+    setIsLogin,
+    clearUserInfo
+  }
+})
+
+/**
+ * @description 在非setup上下文或SSR场景中使用store
+ */
+export function useAb98UserStoreOutside() {
+  return useAb98UserStore(pinia)
+}
\ No newline at end of file
diff --git a/src/router/guard.ts b/src/router/guard.ts
index 01a3ca1..4ca96fd 100644
--- a/src/router/guard.ts
+++ b/src/router/guard.ts
@@ -5,18 +5,26 @@ import { isWhiteList } from "@/router/whitelist"
 import { useTitle } from "@@/composables/useTitle"
 import { getToken } from "@@/utils/cache/cookies"
 import NProgress from "nprogress"
+import { useAb98UserStore } from '@/pinia/stores/ab98-user'
 
 
 NProgress.configure({ showSpinner: false })
 
 const { setTitle } = useTitle()
 
-const LOGIN_PATH = "/login"
+const LOGIN_PATH = "/ab98"
 
 export function registerNavigationGuard(router: Router) {
   // 全局前置守卫
   router.beforeEach((to, _from) => {
     NProgress.start()
+    const userStore = useAb98UserStore()
+    if (!userStore.isLogin) {
+        // 如果在免登录的白名单中,则直接进入
+        if (isWhiteList(to)) return true
+        // 其他没有访问权限的页面将被重定向到登录页面
+        return LOGIN_PATH
+    }
     return true;
     // const userStore = useUserStore()
     // // 如果没有登录
diff --git a/src/router/index.ts b/src/router/index.ts
index 62b9a4e..1acf8f1 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -86,7 +86,7 @@ export const routes: RouteRecordRaw[] = [
           showLeftArrow: false
         },
         tabbar: {
-          showTabbar: false,
+          showTabbar: true,
           icon: "home-o"
         }
       }
@@ -147,6 +147,14 @@ export const routes: RouteRecordRaw[] = [
         }
       }
     }
+  },
+  {
+    path: "/ab98",
+    component: () => import("@/pages/login/Ab98Login.vue"),
+    name: "Ab98Login",
+    meta: {
+      title: "登录"
+    }
   }
 ]
 
diff --git a/src/router/whitelist.ts b/src/router/whitelist.ts
index 7811e19..5c7cf86 100644
--- a/src/router/whitelist.ts
+++ b/src/router/whitelist.ts
@@ -1,7 +1,7 @@
 import type { RouteLocationNormalizedGeneric, RouteRecordNameGeneric } from "vue-router"
 
 /** 免登录白名单(匹配路由 path) */
-const whiteListByPath: string[] = ["/login"]
+const whiteListByPath: string[] = ["/login", "/ab98"]
 
 /** 免登录白名单(匹配路由 name) */
 const whiteListByName: RouteRecordNameGeneric[] = []