diff --git a/pages.config.ts b/pages.config.ts index 9b1902e..9dbee5e 100644 --- a/pages.config.ts +++ b/pages.config.ts @@ -18,6 +18,37 @@ export default defineUniPages({ '^wd-(.*)': 'wot-design-uni/components/wd-$1/wd-$1.vue', }, }, - // tabbar 的配置统一在 “./src/tabbar/config.ts” 文件中 + // tabbar 配置 tabBar: tabBar as any, + + // 分包配置 + subPackages: [ + { + root: 'pagesMerchant', + pages: [ + { path: 'dashboard/index', style: { navigationBarTitleText: '商家工作台' } }, + { path: 'order/list', style: { navigationBarTitleText: '订单管理' } }, + { path: 'goods/list', style: { navigationBarTitleText: '商品管理' } }, + { path: 'finance/index', style: { navigationBarTitleText: '财务中心' } }, + { path: 'me/index', style: { navigationBarTitleText: '商家中心' } }, + ], + }, + { + root: 'pagesBank', + pages: [ + { path: 'dashboard/index', style: { navigationBarTitleText: '银行工作台' } }, + { path: 'audit/list', style: { navigationBarTitleText: '审核列表' } }, + { path: 'customer/list', style: { navigationBarTitleText: '客户管理' } }, + { path: 'me/index', style: { navigationBarTitleText: '银行中心' } }, + ], + }, + ], + + // 分包预下载配置 + preloadRule: { + 'pages/login/index': { + network: 'all', + packages: ['pagesMerchant', 'pagesBank'], + }, + }, }) diff --git a/src/App.vue b/src/App.vue index 0ea6924..f5660f2 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,10 +1,20 @@ + + + + diff --git a/src/pagesBank/customer/list.vue b/src/pagesBank/customer/list.vue new file mode 100644 index 0000000..fe85b6f --- /dev/null +++ b/src/pagesBank/customer/list.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/src/pagesBank/dashboard/index.vue b/src/pagesBank/dashboard/index.vue new file mode 100644 index 0000000..bba7763 --- /dev/null +++ b/src/pagesBank/dashboard/index.vue @@ -0,0 +1,192 @@ + + + + + diff --git a/src/pagesBank/me/index.vue b/src/pagesBank/me/index.vue new file mode 100644 index 0000000..4d98396 --- /dev/null +++ b/src/pagesBank/me/index.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/src/pagesMerchant/dashboard/index.vue b/src/pagesMerchant/dashboard/index.vue new file mode 100644 index 0000000..2cb737a --- /dev/null +++ b/src/pagesMerchant/dashboard/index.vue @@ -0,0 +1,192 @@ + + + + + diff --git a/src/pagesMerchant/finance/index.vue b/src/pagesMerchant/finance/index.vue new file mode 100644 index 0000000..9eb3100 --- /dev/null +++ b/src/pagesMerchant/finance/index.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/src/pagesMerchant/goods/list.vue b/src/pagesMerchant/goods/list.vue new file mode 100644 index 0000000..a1a1d81 --- /dev/null +++ b/src/pagesMerchant/goods/list.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/pagesMerchant/me/index.vue b/src/pagesMerchant/me/index.vue new file mode 100644 index 0000000..d0d9299 --- /dev/null +++ b/src/pagesMerchant/me/index.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/src/pagesMerchant/order/list.vue b/src/pagesMerchant/order/list.vue new file mode 100644 index 0000000..ce46b62 --- /dev/null +++ b/src/pagesMerchant/order/list.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/src/store/user.ts b/src/store/user.ts index cd91bbf..b4d694c 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -2,6 +2,43 @@ import { defineStore } from 'pinia' import type { User } from '@/typings/mall' import { mockMember } from '@/mock/member' +/** + * 客户端类型枚举 + * - user: 用户端(消费者) + * - merchant: 商家端 + * - bank: 银行端 + */ +export enum ClientType { + USER = 'user', + MERCHANT = 'merchant', + BANK = 'bank', +} + +/** 客户端类型配置 */ +export const CLIENT_TYPE_CONFIG = { + [ClientType.USER]: { + label: '用户端', + icon: 'i-carbon-user', + color: '#4d80f0', + description: '购物消费、查看订单', + homePage: '/pages/index/index', + }, + [ClientType.MERCHANT]: { + label: '商家端', + icon: 'i-carbon-store', + color: '#ff8f0d', + description: '商品管理、订单处理', + homePage: '/pagesMerchant/dashboard/index', + }, + [ClientType.BANK]: { + label: '银行端', + icon: 'i-carbon-bank', + color: '#00c05a', + description: '账款审核、金融服务', + homePage: '/pagesBank/dashboard/index', + }, +} + export const useUserStore = defineStore('user', { state: () => ({ userInfo: { @@ -10,23 +47,48 @@ export const useUserStore = defineStore('user', { nickname: '王明阳', avatar: '/static/images/avatar.jpg', phone: '13800138000', - creditLimits: [], // 实际应从 financeStore 获取或关联 + creditLimits: [], member: mockMember, } as User | null, - isLogin: true, // 默认已登录 + isLogin: true, + clientType: ClientType.USER as ClientType, }), + getters: { + // 获取当前客户端类型配置 + currentClientConfig(state) { + return CLIENT_TYPE_CONFIG[state.clientType] + }, + // 是否为用户端 + isUserClient(state) { + return state.clientType === ClientType.USER + }, + // 是否为商家端 + isMerchantClient(state) { + return state.clientType === ClientType.MERCHANT + }, + // 是否为银行端 + isBankClient(state) { + return state.clientType === ClientType.BANK + }, + }, + actions: { - // 登录(模拟) + // 设置客户端类型 + setClientType(type: ClientType) { + this.clientType = type + }, + + // 登录 login(data: any) { this.isLogin = true - // ... }, // 退出登录 logout() { this.isLogin = false this.userInfo = null + this.clientType = ClientType.USER }, }, @@ -38,3 +100,4 @@ export const useUserStore = defineStore('user', { }, }, }) + diff --git a/src/tabbar/config.ts b/src/tabbar/config.ts index 5a43a68..ddaca31 100644 --- a/src/tabbar/config.ts +++ b/src/tabbar/config.ts @@ -2,13 +2,11 @@ import type { TabBar } from '@uni-helper/vite-plugin-uni-pages' import type { CustomTabBarItem, NativeTabBarItem } from './types' /** - * tabbar 选择的策略,更详细的介绍见 tabbar.md 文件 - * 0: 'NO_TABBAR' `无 tabbar` - * 1: 'NATIVE_TABBAR' `完全原生 tabbar` - * 2: 'CUSTOM_TABBAR_WITH_CACHE' `有缓存自定义 tabbar` - * 3: 'CUSTOM_TABBAR_WITHOUT_CACHE' `无缓存自定义 tabbar` - * - * 温馨提示:本文件的任何代码更改了之后,都需要重新运行,否则 pages.json 不会更新导致配置不生效 + * tabbar 选择的策略 + * 0: 'NO_TABBAR' 无 tabbar + * 1: 'NATIVE_TABBAR' 完全原生 tabbar + * 2: 'CUSTOM_TABBAR_WITH_CACHE' 有缓存自定义 tabbar + * 3: 'CUSTOM_TABBAR_WITHOUT_CACHE' 无缓存自定义 tabbar */ export const TABBAR_STRATEGY_MAP = { NO_TABBAR: 0, @@ -17,113 +15,143 @@ export const TABBAR_STRATEGY_MAP = { CUSTOM_TABBAR_WITHOUT_CACHE: 3, } -// TODO: 1/3. 通过这里切换使用tabbar的策略 -// 如果是使用 NO_TABBAR(0),nativeTabbarList 和 customTabbarList 都不生效(里面的配置不用管) -// 如果是使用 NATIVE_TABBAR(1),只需要配置 nativeTabbarList,customTabbarList 不生效 -// 如果是使用 CUSTOM_TABBAR(2,3),只需要配置 不生效 export const selectedTabbarStrategy = TABBAR_STRATEGY_MAP.CUSTOM_TABBAR_WITH_CACHE -// TODO: 2/3. 使用 NATIVE_TABBAR 时,更新下面的 tabbar 配置 +// 原生 tabbar 配置(备用) export const nativeTabbarList: NativeTabBarItem[] = [ { iconPath: 'static/tabbar/home.png', selectedIconPath: 'static/tabbar/homeHL.png', pagePath: 'pages/index/index', - text: '数字广东', + text: '首页', }, { iconPath: 'static/tabbar/personal.png', selectedIconPath: 'static/tabbar/personalHL.png', pagePath: 'pages/me/me', - text: '个人', + text: '我的', }, ] -// TODO: 3/3. 使用 CUSTOM_TABBAR(2,3) 时,更新下面的 tabbar 配置 -// 如果需要配置鼓包,需要在 'tabbar/store.ts' 里面设置,最后在 `tabbar/index.vue` 里面更改鼓包的图片 -export const customTabbarList: CustomTabBarItem[] = [ +// ==================== 用户端 Tabbar 配置 ==================== +export const userTabbarList: CustomTabBarItem[] = [ { - text: '数字广东', + text: '首页', pagePath: 'pages/index/index', - // 注意 unocss 图标需要如下处理:(二选一) - // 1)在fg-tabbar.vue页面上引入一下并注释掉(见tabbar/index.vue代码第2行) - // 2)配置到 unocss.config.ts 的 safelist 中 iconType: 'image', icon: '/static/logo2.png', iconActive: '/static/logo1.png', - // badge: 'dot', }, { pagePath: 'pages/sort/index', text: '分类', - // 1)在fg-tabbar.vue页面上引入一下并注释掉(见tabbar/index.vue代码第2行) - // 2)配置到 unocss.config.ts 的 safelist 中 iconType: 'unocss', icon: 'i-carbon-view-mode-2', - // badge: 10, }, { pagePath: 'pages/goods/cart', text: '购物车', - // 1)在fg-tabbar.vue页面上引入一下并注释掉(见tabbar/index.vue代码第2行) - // 2)配置到 unocss.config.ts 的 safelist 中 iconType: 'unocss', icon: 'i-carbon-shopping-cart', - // badge: 10, }, { pagePath: 'pages/me/me', text: '我的', - // 1)在fg-tabbar.vue页面上引入一下并注释掉(见tabbar/index.vue代码第2行) - // 2)配置到 unocss.config.ts 的 safelist 中 iconType: 'unocss', icon: 'i-carbon-user', - // badge: 10, }, - // 其他类型演示 - // 1、uiLib - // { - // pagePath: 'pages/index/index', - // text: '首页', - // iconType: 'uiLib', - // icon: 'home', - // }, - // 2、iconfont - // { - // pagePath: 'pages/index/index', - // text: '首页', - // // 注意 iconfont 图标需要额外加上 'iconfont',如下 - // iconType: 'iconfont', - // icon: 'iconfont icon-my', - // }, - // 3、image - // { - // pagePath: 'pages/index/index', - // text: '首页', - // // 使用 ‘image’时,需要配置 icon + iconActive 2张图片 - // iconType: 'image', - // icon: '/static/tabbar/home.png', - // iconActive: '/static/tabbar/homeHL.png', - // }, ] +// ==================== 商家端 Tabbar 配置 ==================== +export const merchantTabbarList: CustomTabBarItem[] = [ + { + text: '工作台', + pagePath: 'pagesMerchant/dashboard/index', + iconType: 'unocss', + icon: 'i-carbon-dashboard', + }, + { + pagePath: 'pagesMerchant/order/list', + text: '订单', + iconType: 'unocss', + icon: 'i-carbon-document', + }, + { + pagePath: 'pagesMerchant/goods/list', + text: '商品', + iconType: 'unocss', + icon: 'i-carbon-product', + }, + { + pagePath: 'pagesMerchant/finance/index', + text: '财务', + iconType: 'unocss', + icon: 'i-carbon-wallet', + }, + { + pagePath: 'pagesMerchant/me/index', + text: '我的', + iconType: 'unocss', + icon: 'i-carbon-user', + }, +] + +// ==================== 银行端 Tabbar 配置 ==================== +export const bankTabbarList: CustomTabBarItem[] = [ + { + text: '工作台', + pagePath: 'pagesBank/dashboard/index', + iconType: 'unocss', + icon: 'i-carbon-analytics', + }, + { + pagePath: 'pagesBank/audit/list', + text: '审核', + iconType: 'unocss', + icon: 'i-carbon-task-approved', + }, + { + pagePath: 'pagesBank/customer/list', + text: '客户', + iconType: 'unocss', + icon: 'i-carbon-group', + }, + { + pagePath: 'pagesBank/me/index', + text: '我的', + iconType: 'unocss', + icon: 'i-carbon-user', + }, +] + +// 根据客户端类型获取对应的 tabbar 配置 +export type ClientTypeKey = 'user' | 'merchant' | 'bank' +export function getTabbarListByClientType(clientType: ClientTypeKey): CustomTabBarItem[] { + const tabbarMap: Record = { + user: userTabbarList, + merchant: merchantTabbarList, + bank: bankTabbarList, + } + return tabbarMap[clientType] || userTabbarList +} + +// 默认使用用户端配置 +export const customTabbarList: CustomTabBarItem[] = userTabbarList + /** * 是否启用 tabbar 缓存 - * NATIVE_TABBAR(1) 和 CUSTOM_TABBAR_WITH_CACHE(2) 时,需要tabbar缓存 */ export const tabbarCacheEnable = [TABBAR_STRATEGY_MAP.NATIVE_TABBAR, TABBAR_STRATEGY_MAP.CUSTOM_TABBAR_WITH_CACHE].includes(selectedTabbarStrategy) /** * 是否启用自定义 tabbar - * CUSTOM_TABBAR(2,3) 时,启用自定义tabbar */ export const customTabbarEnable = [TABBAR_STRATEGY_MAP.CUSTOM_TABBAR_WITH_CACHE, TABBAR_STRATEGY_MAP.CUSTOM_TABBAR_WITHOUT_CACHE].includes(selectedTabbarStrategy) /** * 是否需要隐藏原生 tabbar - * CUSTOM_TABBAR_WITH_CACHE(2) 时,需要隐藏原生tabbar */ export const needHideNativeTabbar = selectedTabbarStrategy === TABBAR_STRATEGY_MAP.CUSTOM_TABBAR_WITH_CACHE @@ -131,7 +159,6 @@ const _tabbarList = customTabbarEnable ? customTabbarList.map(item => ({ text: i export const tabbarList = customTabbarEnable ? customTabbarList : nativeTabbarList const _tabbar: TabBar = { - // 只有微信小程序支持 custom。App 和 H5 不生效 custom: selectedTabbarStrategy === TABBAR_STRATEGY_MAP.CUSTOM_TABBAR_WITH_CACHE, color: '#999999', selectedColor: '#018d71', @@ -145,3 +172,4 @@ const _tabbar: TabBar = { } export const tabBar = tabbarCacheEnable ? _tabbar : undefined + diff --git a/src/tabbar/store.ts b/src/tabbar/store.ts index c26b826..ad9eb21 100644 --- a/src/tabbar/store.ts +++ b/src/tabbar/store.ts @@ -1,25 +1,39 @@ import type { CustomTabBarItem, CustomTabBarItemBadge } from './types' import { reactive } from 'vue' -import { tabbarList as _tabbarList, customTabbarEnable, selectedTabbarStrategy, TABBAR_STRATEGY_MAP } from './config' +import { + tabbarList as _tabbarList, + customTabbarEnable, + selectedTabbarStrategy, + TABBAR_STRATEGY_MAP, + getTabbarListByClientType, + type ClientTypeKey, +} from './config' -// TODO 1/2: 中间的鼓包tabbarItem的开关 +// 中间的鼓包tabbarItem的开关 const BULGE_ENABLE = false -/** tabbarList 里面的 path 从 pages.config.ts 得到 */ +/** tabbarList 动态列表,根据客户端类型切换 */ const tabbarList = reactive(_tabbarList.map(item => ({ ...item, pagePath: item.pagePath.startsWith('/') ? item.pagePath : `/${item.pagePath}`, }))) -if (customTabbarEnable && BULGE_ENABLE) { - if (tabbarList.length % 2) { - console.error('有鼓包时 tabbar 数量必须是偶数,否则样式很奇怪!!') +// 初始化鼓包 +function initBulge() { + if (customTabbarEnable && BULGE_ENABLE) { + if (tabbarList.length % 2) { + console.error('有鼓包时 tabbar 数量必须是偶数') + } + const hasBulge = tabbarList.some(item => item.isBulge) + if (!hasBulge) { + tabbarList.splice(tabbarList.length / 2, 0, { + isBulge: true, + } as CustomTabBarItem) + } } - tabbarList.splice(tabbarList.length / 2, 0, { - isBulge: true, - } as CustomTabBarItem) } +initBulge() export function isPageTabbar(path: string) { if (selectedTabbarStrategy === TABBAR_STRATEGY_MAP.NO_TABBAR) { @@ -30,33 +44,55 @@ export function isPageTabbar(path: string) { } /** - * 自定义 tabbar 的状态管理,原生 tabbar 无需关注本文件 - * tabbar 状态,增加 storageSync 保证刷新浏览器时在正确的 tabbar 页面 - * 使用reactive简单状态,而不是 pinia 全局状态 + * 自定义 tabbar 的状态管理 */ const tabbarStore = reactive({ curIdx: uni.getStorageSync('app-tabbar-index') || 0, prevIdx: uni.getStorageSync('app-tabbar-index') || 0, + setCurIdx(idx: number) { this.curIdx = idx uni.setStorageSync('app-tabbar-index', idx) }, + setTabbarItemBadge(idx: number, badge: CustomTabBarItemBadge) { if (tabbarList[idx]) { tabbarList[idx].badge = badge } }, + + /** + * 根据客户端类型切换 tabbar 列表 + */ + setTabbarByClientType(clientType: ClientTypeKey) { + const newList = getTabbarListByClientType(clientType) + + // 清空现有列表 + tabbarList.length = 0 + + // 填充新列表 + newList.forEach(item => { + tabbarList.push({ + ...item, + pagePath: (item.pagePath.startsWith('/') ? item.pagePath : `/${item.pagePath}`) as any, + }) + }) + + // 重新初始化鼓包 + initBulge() + + // 重置当前索引 + this.setCurIdx(0) + }, + setAutoCurIdx(path: string) { - // '/' 当做首页 if (path === '/') { this.setCurIdx(0) return } const index = tabbarList.findIndex(item => item.pagePath === path) - // console.log('tabbarList:', tabbarList) if (index === -1) { const pagesPathList = getCurrentPages().map(item => item.route.startsWith('/') ? item.route : `/${item.route}`) - // console.log(pagesPathList) const flag = tabbarList.some(item => pagesPathList.includes(item.pagePath)) if (!flag) { this.setCurIdx(0) @@ -67,6 +103,7 @@ const tabbarStore = reactive({ this.setCurIdx(index) } }, + restorePrevIdx() { if (this.prevIdx === this.curIdx) return @@ -76,3 +113,4 @@ const tabbarStore = reactive({ }) export { tabbarList, tabbarStore } + diff --git a/uno.config.ts b/uno.config.ts index 9f58365..b69c351 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -70,10 +70,21 @@ export default defineConfig({ center: 'flex justify-center items-center', }, ], - // 动态图标需要在这里配置,或者写在vue页面中注释掉 - safelist: ['i-carbon-code', 'i-carbon-home', 'i-carbon-user','i-carbon-shopping-cart','i-carbon-view-mode-2','i-carbon-webhook', - 'i-carbon-restaurant','i-carbon-crop','i-carbon-ibm-deployable-architecture', - 'i-carbon-edge-device','i-carbon-ibm-cloud-direct-link-1-dedicated-hosting','i-carbon-face-satisfied','i-carbon-document-attachment'], + // 动态图标需要在这里配置 + safelist: [ + // 基础图标 + 'i-carbon-code', 'i-carbon-home', 'i-carbon-user', 'i-carbon-shopping-cart', 'i-carbon-view-mode-2', 'i-carbon-webhook', + 'i-carbon-restaurant', 'i-carbon-crop', 'i-carbon-ibm-deployable-architecture', + 'i-carbon-edge-device', 'i-carbon-ibm-cloud-direct-link-1-dedicated-hosting', 'i-carbon-face-satisfied', 'i-carbon-document-attachment', + // 商家端/银行端 tabbar 图标 + 'i-carbon-dashboard', 'i-carbon-document', 'i-carbon-product', 'i-carbon-wallet', + 'i-carbon-analytics', 'i-carbon-task-approved', 'i-carbon-group', 'i-carbon-report', + // 登录页端类型选择图标 + 'i-carbon-store', 'i-carbon-bank', 'i-carbon-checkmark-filled', + // 菜单图标 + 'i-carbon-settings', 'i-carbon-customer-service', 'i-carbon-help', 'i-carbon-information', + 'i-carbon-add', 'i-carbon-add-alt', 'i-carbon-document-add', 'i-carbon-chevron-right', + ], rules: [ [ 'p-safe',