From cdec6ef299c234e88a21f36c8dbb53384bfced2e Mon Sep 17 00:00:00 2001 From: jacobxu666 Date: Sun, 14 Jun 2026 17:24:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=B9=E9=80=A0=20user=20store?= =?UTF-8?q?=EF=BC=88=E5=BE=AE=E4=BF=A1=E7=99=BB=E5=BD=95=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20card=20store?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - user store 增加 refreshToken 状态、wxLogin 微信登录(条件编译)、降级登录 - card store 封装年卡列表/详情/我的年卡/激活/绑定/入园码等状态和操作 Co-Authored-By: Claude Opus 4.8 (1M context) --- src/store/card.ts | 64 +++++++++++++++++++++++++++++++++++++++++++++++ src/store/user.ts | 41 +++++++++++++++++++++++++++--- 2 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 src/store/card.ts diff --git a/src/store/card.ts b/src/store/card.ts new file mode 100644 index 0000000..fa89e13 --- /dev/null +++ b/src/store/card.ts @@ -0,0 +1,64 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import * as cardApi from '../api/card' +import type { CardInfo, CardDetail, MyCard, ActivateParams, QrCodeInfo } from '../api/types' + +export const useCardStore = defineStore('card', () => { + const cardList = ref([]) + const currentCard = ref(null) + const myCards = ref([]) + const loading = ref(false) + + /** 获取年卡列表 */ + async function fetchCardList(params?: { keyword?: string; category?: string }) { + loading.value = true + try { + cardList.value = await cardApi.getCardList(params) + } finally { + loading.value = false + } + } + + /** 获取年卡详情 */ + async function fetchCardDetail(id: string) { + loading.value = true + try { + currentCard.value = await cardApi.getCardDetail(id) + } finally { + loading.value = false + } + } + + /** 获取我的年卡 */ + async function fetchMyCards() { + myCards.value = await cardApi.getMyCards() + } + + /** 激活年卡 */ + async function activateCard(cardId: string, data: ActivateParams) { + return await cardApi.activateCard(cardId, data) + } + + /** 绑定年卡 */ + async function bindCard(cardNo: string) { + return await cardApi.bindCard(cardNo) + } + + /** 获取入园码 */ + async function getEntryQrCode(cardId: string): Promise { + return await cardApi.getEntryQrCode(cardId) + } + + return { + cardList, + currentCard, + myCards, + loading, + fetchCardList, + fetchCardDetail, + fetchMyCards, + activateCard, + bindCard, + getEntryQrCode + } +}) diff --git a/src/store/user.ts b/src/store/user.ts index ad2f7a5..eac476b 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -1,40 +1,73 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { getToken, setToken, removeToken } from '../api/request' -import { getUserInfo, login as apiLogin, type UserInfo, type LoginParams } from '../api/user' +import { wxLogin as apiWxLogin, login as apiLogin, getUserInfo as apiGetUserInfo } from '../api/user' +import type { UserInfo, LoginParams } from '../api/types' +import { TOKEN_KEY, REFRESH_TOKEN_KEY } from '../config' export const useUserStore = defineStore('user', () => { const token = ref(getToken()) + const refreshToken = ref(uni.getStorageSync(REFRESH_TOKEN_KEY) || '') const userInfo = ref(null) const isLogin = computed(() => !!token.value) + /** 微信授权登录 */ + async function wxLogin() { + // #ifdef MP-WEIXIN + const loginRes = await new Promise((resolve, reject) => { + uni.login({ + provider: 'weixin', + success: resolve, + fail: reject + }) + }) + const result = await apiWxLogin(loginRes.code) + token.value = result.accessToken + refreshToken.value = result.refreshToken + setToken(result.accessToken) + uni.setStorageSync(REFRESH_TOKEN_KEY, result.refreshToken) + return result + // #endif + + // #ifdef H5 + throw new Error('H5 登录暂未开放,请在微信小程序中使用') + // #endif + } + + /** 账号密码登录(降级方案) */ async function login(params: LoginParams) { const result = await apiLogin(params) token.value = result.accessToken + refreshToken.value = result.refreshToken setToken(result.accessToken) - // 登录成功后获取用户信息 - await fetchUserInfo() + uni.setStorageSync(REFRESH_TOKEN_KEY, result.refreshToken) return result } + /** 获取用户信息 */ async function fetchUserInfo() { if (!token.value) return - const info = await getUserInfo() + const info = await apiGetUserInfo() userInfo.value = info return info } + /** 退出登录 */ function logout() { token.value = '' + refreshToken.value = '' userInfo.value = null removeToken() + uni.removeStorageSync(REFRESH_TOKEN_KEY) } return { token, + refreshToken, userInfo, isLogin, + wxLogin, login, fetchUserInfo, logout