From a9b00871315e15a8c67545c13f79b4f46d640ef9 Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Mon, 18 Aug 2025 19:53:57 +0800 Subject: [PATCH 01/17] =?UTF-8?q?feat(login):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=9A=E5=B9=B3=E5=8F=B0=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加H5、微信小程序和通用登录页面组件,通过条件编译实现多平台适配 --- src/pages/login/login.h5.vue | 26 ++++++++++++++++++++++++++ src/pages/login/login.vue | 26 ++++++++++++++++++++++++++ src/pages/login/login.weixin.vue | 26 ++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 src/pages/login/login.h5.vue create mode 100644 src/pages/login/login.vue create mode 100644 src/pages/login/login.weixin.vue diff --git a/src/pages/login/login.h5.vue b/src/pages/login/login.h5.vue new file mode 100644 index 0000000..9966cdf --- /dev/null +++ b/src/pages/login/login.h5.vue @@ -0,0 +1,26 @@ + +{ + "layout": "default", + "style": { + "navigationBarTitleText": "登录" + } +} + + + + + + + diff --git a/src/pages/login/login.vue b/src/pages/login/login.vue new file mode 100644 index 0000000..2b7cbf7 --- /dev/null +++ b/src/pages/login/login.vue @@ -0,0 +1,26 @@ + +{ + "layout": "default", + "style": { + "navigationBarTitleText": "登录" + } +} + + + + + + + diff --git a/src/pages/login/login.weixin.vue b/src/pages/login/login.weixin.vue new file mode 100644 index 0000000..345f382 --- /dev/null +++ b/src/pages/login/login.weixin.vue @@ -0,0 +1,26 @@ + +{ + "layout": "default", + "style": { + "navigationBarTitleText": "登录" + } +} + + + + + + + From 168a19fbca1ac02c16e699d942c25909a5bda6e1 Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Mon, 18 Aug 2025 21:24:05 +0800 Subject: [PATCH 02/17] =?UTF-8?q?feat(=E7=99=BB=E5=BD=95):=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=99=BB=E5=BD=95=E7=AD=96=E7=95=A5=E5=92=8C=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E6=8B=A6=E6=88=AA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加登录相关配置文件和页面,包括登录策略配置、注册页面和路由拦截逻辑 移除旧的登录相关代码和配置,使用新的登录策略实现 在用户store中添加hasLogin计算属性用于检查登录状态 优化路由拦截器逻辑,支持白名单和黑名单策略 --- env/.env | 3 --- src/App.vue | 15 +++++------ src/login/README.md | 15 +++++++++++ src/login/config.ts | 13 +++++++++ src/pages.json | 16 +++++++++++ src/pages/login/register.vue | 19 ++++++++++++++ src/router/interceptor.ts | 51 ++++++++++++++---------------------- src/store/user.ts | 1 + src/utils/index.ts | 12 --------- 9 files changed, 91 insertions(+), 54 deletions(-) create mode 100644 src/login/README.md create mode 100644 src/login/config.ts create mode 100644 src/pages/login/register.vue diff --git a/env/.env b/env/.env index 8aa561c..61c2a09 100644 --- a/env/.env +++ b/env/.env @@ -8,9 +8,6 @@ VITE_WX_APPID = 'wxa2abb91f64032a2b' # https://uniapp.dcloud.net.cn/collocation/manifest.html#h5-router VITE_APP_PUBLIC_BASE=/ -# 登录页面 -VITE_LOGIN_URL = '/pages/login/index' - # 后台请求地址 VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run' # 后台上传地址 diff --git a/src/App.vue b/src/App.vue index b0d9043..275a071 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,21 +1,20 @@ + + + + diff --git a/src/router/interceptor.ts b/src/router/interceptor.ts index 14c5535..fe73004 100644 --- a/src/router/interceptor.ts +++ b/src/router/interceptor.ts @@ -6,54 +6,43 @@ */ import { useUserStore } from '@/store' import { tabbarStore } from '@/tabbar/store' -import { needLoginPages as _needLoginPages, getLastPage, getNeedLoginPages } from '@/utils' - -// TODO Check -const loginRoute = import.meta.env.VITE_LOGIN_URL - -function isLogined() { - const userStore = useUserStore() - return !!userStore.userInfo.username -} - -const isDev = import.meta.env.DEV +import { getLastPage } from '@/utils' +import { EXCLUDE_LIST, LOGIN_PAGE_LIST } from '../login/config' // 黑名单登录拦截器 - (适用于大部分页面不需要登录,少部分页面需要登录) export const navigateToInterceptor = { // 注意,这里的url是 '/' 开头的,如 '/pages/index/index',跟 'pages.json' 里面的 path 不同 // 增加对相对路径的处理,BY 网友 @ideal invoke({ url }: { url: string }) { - // console.log(url) // /pages/route-interceptor/index?name=feige&age=30 + console.log(url) // /pages/route-interceptor/index?name=feige&age=30 let path = url.split('?')[0] // 处理相对路径 if (!path.startsWith('/')) { - const currentPath = getLastPage().route + const currentPath = getLastPage()?.route || '' const normalizedCurrentPath = currentPath.startsWith('/') ? currentPath : `/${currentPath}` const baseDir = normalizedCurrentPath.substring(0, normalizedCurrentPath.lastIndexOf('/')) path = `${baseDir}/${path}` } - let needLoginPages: string[] = [] - // 为了防止开发时出现BUG,这里每次都获取一下。生产环境可以移到函数外,性能更好 - if (isDev) { - needLoginPages = getNeedLoginPages() - } - else { - needLoginPages = _needLoginPages - } - const isNeedLogin = needLoginPages.includes(path) - if (!isNeedLogin) { - return true - } - const hasLogin = isLogined() - if (hasLogin) { - return true + if (LOGIN_PAGE_LIST.includes(path)) { + console.log('000') + return } + tabbarStore.restorePrevIdx() - const redirectRoute = `${loginRoute}?redirect=${encodeURIComponent(url)}` - uni.navigateTo({ url: redirectRoute }) - return false + + console.log('拦截器中得到的 path:', path) + const userStore = useUserStore() + + if (userStore.hasLogin || [...EXCLUDE_LIST, ...LOGIN_PAGE_LIST].includes(path)) { + console.log('111') + uni.navigateTo({ url: path }) + return + } + console.log('222') + const redirectUrl = `/login/login?redirect=${encodeURIComponent(path)}` + uni.navigateTo({ url: redirectUrl }) }, } diff --git a/src/store/user.ts b/src/store/user.ts index cec931a..2616a62 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -103,6 +103,7 @@ export const useUserStore = defineStore( getUserInfo, setUserAvatar, logout, + hasLogin: computed(() => !!userInfo.value.token), } }, { diff --git a/src/utils/index.ts b/src/utils/index.ts index 3aa8e52..00224ae 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -110,18 +110,6 @@ export function getCurrentPageI18nKey() { return currPage.style.navigationBarTitleText } -/** - * 得到所有的需要登录的 pages,包括主包和分包的 - * 只得到 path 数组 - */ -export const getNeedLoginPages = (): string[] => getAllPages('needLogin').map(page => page.path) - -/** - * 得到所有的需要登录的 pages,包括主包和分包的 - * 只得到 path 数组 - */ -export const needLoginPages: string[] = getAllPages('needLogin').map(page => page.path) - /** * 根据微信小程序当前环境,判断应该获取的 baseUrl */ From 7a89d913ec0b8d16d03825b041f36cd56b1bb1c2 Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Mon, 18 Aug 2025 21:27:59 +0800 Subject: [PATCH 03/17] =?UTF-8?q?refactor:=20=E7=BB=9F=E4=B8=80=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E7=9B=B8=E5=85=B3=E9=A1=B5=E9=9D=A2=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E4=B8=BA/pages/login=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将登录页面、注册页面及相关跳转路径统一修改为/pages/login前缀 在首页添加跳转登录页的按钮 --- src/login/config.ts | 4 ++-- src/pages/index/index.vue | 9 +++++++++ src/router/interceptor.ts | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/login/config.ts b/src/login/config.ts index ae94969..c8694cc 100644 --- a/src/login/config.ts +++ b/src/login/config.ts @@ -5,9 +5,9 @@ export const LOGIN_STRATEGY_MAP = { // 登录策略,默认使用黑名单策略,即默认不需要登录就可以访问 export const LOGIN_STRATEGY = LOGIN_STRATEGY_MAP.WHITELIST -export const LOGIN_PAGE_LIST = ['/login/login', '/login/register'] +export const LOGIN_PAGE_LIST = ['/pages/login/login', '/pages/login/register'] // 排除在外的列表,白名单策略指白名单列表,黑名单策略指黑名单列表 export const EXCLUDE_LIST = [ - '/xxx/index', + '/pages/xxx/index', ] diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index dd24520..4353702 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -46,6 +46,12 @@ onLoad(() => { console.log('项目作者:', author.value) }) +function toLogin() { + uni.navigateTo({ + url: '/pages/login/login', + }) +} + console.log('index') @@ -118,6 +124,9 @@ console.log('index') https://wot-design-uni.cn + diff --git a/src/router/interceptor.ts b/src/router/interceptor.ts index fe73004..87dd783 100644 --- a/src/router/interceptor.ts +++ b/src/router/interceptor.ts @@ -41,7 +41,7 @@ export const navigateToInterceptor = { return } console.log('222') - const redirectUrl = `/login/login?redirect=${encodeURIComponent(path)}` + const redirectUrl = `/pages/login/login?redirect=${encodeURIComponent(path)}` uni.navigateTo({ url: redirectUrl }) }, } From e8478c9d437e1e14201c3edc1fa1eaa40fb3ea72 Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Mon, 18 Aug 2025 21:52:32 +0800 Subject: [PATCH 04/17] =?UTF-8?q?feat(=E7=99=BB=E5=BD=95):=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0H5=E6=A8=A1=E6=8B=9F=E7=99=BB=E5=BD=95=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=B9=B6=E4=BC=98=E5=8C=96=E8=B7=AF=E7=94=B1=E6=8B=A6?= =?UTF-8?q?=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在user store中添加setUserInfo方法 - 新增tabbar页面判断工具函数isPageTabbar - 重构路由拦截逻辑,简化登录判断 - 实现H5模拟登录页面及跳转逻辑 - 移除不再使用的usePageAuth钩子 --- src/hooks/usePageAuth.ts | 50 ------------------------------------ src/pages/login/login.h5.vue | 33 +++++++++++++++++++++++- src/router/interceptor.ts | 13 ++++++---- src/store/user.ts | 1 + src/tabbar/store.ts | 4 +++ 5 files changed, 45 insertions(+), 56 deletions(-) delete mode 100644 src/hooks/usePageAuth.ts diff --git a/src/hooks/usePageAuth.ts b/src/hooks/usePageAuth.ts deleted file mode 100644 index fd006c8..0000000 --- a/src/hooks/usePageAuth.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { onLoad } from '@dcloudio/uni-app' -import { useUserStore } from '@/store' -import { needLoginPages as _needLoginPages, getNeedLoginPages } from '@/utils' - -const loginRoute = import.meta.env.VITE_LOGIN_URL -const isDev = import.meta.env.DEV -function isLogined() { - const userStore = useUserStore() - return !!userStore.userInfo.username -} -// 检查当前页面是否需要登录 -export function usePageAuth() { - onLoad((options) => { - // 获取当前页面路径 - const pages = getCurrentPages() - const currentPage = pages[pages.length - 1] - const currentPath = `/${currentPage.route}` - - // 获取需要登录的页面列表 - let needLoginPages: string[] = [] - if (isDev) { - needLoginPages = getNeedLoginPages() - } - else { - needLoginPages = _needLoginPages - } - - // 检查当前页面是否需要登录 - const isNeedLogin = needLoginPages.includes(currentPath) - if (!isNeedLogin) { - return - } - - const hasLogin = isLogined() - if (hasLogin) { - return true - } - - // 构建重定向URL - const queryString = Object.entries(options || {}) - .map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`) - .join('&') - - const currentFullPath = queryString ? `${currentPath}?${queryString}` : currentPath - const redirectRoute = `${loginRoute}?redirect=${encodeURIComponent(currentFullPath)}` - - // 重定向到登录页 - uni.redirectTo({ url: redirectRoute }) - }) -} diff --git a/src/pages/login/login.h5.vue b/src/pages/login/login.h5.vue index 9966cdf..83d5c1d 100644 --- a/src/pages/login/login.h5.vue +++ b/src/pages/login/login.h5.vue @@ -8,7 +8,35 @@ diff --git a/src/router/interceptor.ts b/src/router/interceptor.ts index 87dd783..3291fde 100644 --- a/src/router/interceptor.ts +++ b/src/router/interceptor.ts @@ -5,7 +5,6 @@ * 我这里应为大部分都可以随便进入,所以使用黑名单 */ import { useUserStore } from '@/store' -import { tabbarStore } from '@/tabbar/store' import { getLastPage } from '@/utils' import { EXCLUDE_LIST, LOGIN_PAGE_LIST } from '../login/config' @@ -30,12 +29,16 @@ export const navigateToInterceptor = { return } - tabbarStore.restorePrevIdx() - - console.log('拦截器中得到的 path:', path) const userStore = useUserStore() + if (userStore.hasLogin) { + return + } - if (userStore.hasLogin || [...EXCLUDE_LIST, ...LOGIN_PAGE_LIST].includes(path)) { + // tabbarStore.restorePrevIdx() + + console.log('拦截器中得到的 path:', path, userStore.hasLogin) + + if ([...EXCLUDE_LIST, ...LOGIN_PAGE_LIST].includes(path)) { console.log('111') uni.navigateTo({ url: path }) return diff --git a/src/store/user.ts b/src/store/user.ts index 2616a62..16a9d8b 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -100,6 +100,7 @@ export const useUserStore = defineStore( userInfo, login, wxLogin, + setUserInfo, getUserInfo, setUserAvatar, logout, diff --git a/src/tabbar/store.ts b/src/tabbar/store.ts index 2feeea7..7225118 100644 --- a/src/tabbar/store.ts +++ b/src/tabbar/store.ts @@ -16,6 +16,10 @@ if (BULGE_ENABLE) { export { tabbarList } +export function isPageTabbar(path: string) { + return tabbarList.some(item => item.pagePath === path) +} + /** * 自定义 tabbar 的状态管理,原生 tabbar 无需关注本文件 * tabbar 状态,增加 storageSync 保证刷新浏览器时在正确的 tabbar 页面 From 6aa4bc347288a35681e9b8ab50c844d32b02b70a Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Mon, 18 Aug 2025 22:01:55 +0800 Subject: [PATCH 05/17] =?UTF-8?q?feat(login):=20wip=20=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 5 ----- src/pages/about/about.vue | 9 +++++++++ src/router/interceptor.ts | 9 +++++++-- src/tabbar/config.ts | 2 +- src/tabbar/store.ts | 4 ++-- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/App.vue b/src/App.vue index 275a071..becd39f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,8 +1,6 @@ - - - - diff --git a/src/pages/login/login.vue b/src/pages/login/login.vue index 2b7cbf7..bf16e7e 100644 --- a/src/pages/login/login.vue +++ b/src/pages/login/login.vue @@ -8,17 +8,46 @@ diff --git a/src/pages/login/register.vue b/src/pages/login/register.vue index f0d5db9..b28cfab 100644 --- a/src/pages/login/register.vue +++ b/src/pages/login/register.vue @@ -8,10 +8,26 @@ diff --git a/src/tabbar/config.ts b/src/tabbar/config.ts index 8a28010..9fde129 100644 --- a/src/tabbar/config.ts +++ b/src/tabbar/config.ts @@ -38,6 +38,12 @@ export const nativeTabbarList: NativeTabBarItem[] = [ pagePath: 'pages/about/about', text: '关于', }, + { + iconPath: 'static/tabbar/personal.png', + selectedIconPath: 'static/tabbar/personalHL.png', + pagePath: 'pages/me/me', + text: '个人', + }, ] export interface CustomTabBarItem { @@ -71,17 +77,18 @@ export const customTabbarList: CustomTabBarItem[] = [ icon: 'i-carbon-code', // badge: 10, }, - - // { - // pagePath: 'pages/mine/index', - // text: '我的', - // // 注意 iconfont 图标需要额外加上 'iconfont',如下 - // iconType: 'iconfont', - // icon: 'iconfont icon-my', - // }, + { + pagePath: 'pages/me/me', + text: '我的', + iconType: 'uniUi', + icon: 'contact', + }, // { // pagePath: 'pages/index/index', // text: '首页', + // 注意 iconfont 图标需要额外加上 'iconfont',如下 + // iconType: 'iconfont', + // icon: 'iconfont icon-my', // // 使用 ‘image’时,需要配置 icon + iconActive 2张图片(不推荐) // // 既然已经用了自定义tabbar了,就不建议用图片了,所以不推荐 // iconType: 'image', diff --git a/src/utils/index.ts b/src/utils/index.ts index e0d28c5..9ef3987 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -12,7 +12,7 @@ export function getLastPage() { /** * 获取当前页面路由的 path 路径和 redirectPath 路径 - * path 如 '/pages/login/index' + * path 如 '/pages/login/login' * redirectPath 如 '/pages/demo/base/route-interceptor' */ export function currRoute() { @@ -25,8 +25,8 @@ export function currRoute() { // 经过多端测试,只有 fullPath 靠谱,其他都不靠谱 const { fullPath } = currRoute as { fullPath: string } // console.log(fullPath) - // eg: /pages/login/index?redirect=%2Fpages%2Fdemo%2Fbase%2Froute-interceptor (小程序) - // eg: /pages/login/index?redirect=%2Fpages%2Froute-interceptor%2Findex%3Fname%3Dfeige%26age%3D30(h5) + // eg: /pages/login/login?redirect=%2Fpages%2Fdemo%2Fbase%2Froute-interceptor (小程序) + // eg: /pages/login/login?redirect=%2Fpages%2Froute-interceptor%2Findex%3Fname%3Dfeige%26age%3D30(h5) return getUrlObj(fullPath) } @@ -38,8 +38,8 @@ export function ensureDecodeURIComponent(url: string) { } /** * 解析 url 得到 path 和 query - * 比如输入url: /pages/login/index?redirect=%2Fpages%2Fdemo%2Fbase%2Froute-interceptor - * 输出: {path: /pages/login/index, query: {redirect: /pages/demo/base/route-interceptor}} + * 比如输入url: /pages/login/login?redirect=%2Fpages%2Fdemo%2Fbase%2Froute-interceptor + * 输出: {path: /pages/login/login, query: {redirect: /pages/demo/base/route-interceptor}} */ export function getUrlObj(url: string) { const [path, queryStr] = url.split('?') diff --git a/tsconfig.json b/tsconfig.json index c95ea2f..0a76bae 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,6 +29,7 @@ "plugins": ["@uni-helper/uni-types/volar-plugin"] }, "include": [ + "package.json", "src/**/*.ts", "src/**/*.js", "src/**/*.d.ts", From d77ed8ac29309f02f7cb1a1f27aba7d44b78d060 Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Thu, 21 Aug 2025 16:28:45 +0800 Subject: [PATCH 17/17] =?UTF-8?q?fix(tabbar):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89tabbar=E5=90=AF=E7=94=A8=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加customTabbarEnable条件检查,确保仅在启用自定义tabbar时处理鼓包样式 --- src/tabbar/store.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tabbar/store.ts b/src/tabbar/store.ts index 4c48d67..b3600af 100644 --- a/src/tabbar/store.ts +++ b/src/tabbar/store.ts @@ -1,5 +1,5 @@ import type { CustomTabBarItem } from './config' -import { tabbarList as _tabbarList } from './config' +import { tabbarList as _tabbarList, customTabbarEnable } from './config' // TODO 1/2: 中间的鼓包tabbarItem的开关 const BULGE_ENABLE = true @@ -10,9 +10,9 @@ const tabbarList: CustomTabBarItem[] = _tabbarList.map(item => ({ pagePath: item.pagePath.startsWith('/') ? item.pagePath : `/${item.pagePath}`, })) -if (BULGE_ENABLE) { - if (tabbarList.length % 2 === 1) { - console.error('tabbar 数量必须是偶数,否则样式很奇怪!!') +if (customTabbarEnable && BULGE_ENABLE) { + if (tabbarList.length % 2) { + console.error('有鼓包时 tabbar 数量必须是偶数,否则样式很奇怪!!') } tabbarList.splice(tabbarList.length / 2, 0, { isBulge: true,