diff --git a/miniprogram/scripts/verify-venue-tabbar.mjs b/miniprogram/scripts/verify-venue-tabbar.mjs index 4acfdb2..f8bd68f 100644 --- a/miniprogram/scripts/verify-venue-tabbar.mjs +++ b/miniprogram/scripts/verify-venue-tabbar.mjs @@ -6,57 +6,82 @@ const root = resolve(dirname(fileURLToPath(import.meta.url)), '..') const srcRoot = resolve(root, 'src') const tabPages = [ - { file: 'pages/ice/home/index.vue', venue: 'ice', active: 'home' }, - { file: 'pages/ice/courses/index.vue', venue: 'ice', active: 'courses' }, - { file: 'pages/ice/bookings/index.vue', venue: 'ice', active: 'bookings' }, - { file: 'pages/ice/profile/index.vue', venue: 'ice', active: 'profile' }, - { file: 'pages/comprehensive/home/index.vue', venue: 'comprehensive', active: 'home' }, - { file: 'pages/comprehensive/courses/index.vue', venue: 'comprehensive', active: 'courses' }, - { file: 'pages/comprehensive/bookings/index.vue', venue: 'comprehensive', active: 'bookings' }, - { file: 'pages/comprehensive/profile/index.vue', venue: 'comprehensive', active: 'profile' } + { file: 'pages/home/index.vue' }, + { file: 'pages/private/index.vue' }, + { file: 'pages/mall/index.vue' }, + { file: 'pages/courses/index.vue' }, + { file: 'pages/profile/index.vue' } ] -const icons = ['home', 'course', 'booking', 'mine'] -const venues = ['ice', 'comprehensive'] +const tabBarPages = [ + 'pages/home/index', + 'pages/private/index', + 'pages/mall/index', + 'pages/courses/index', + 'pages/profile/index' +] + +const icons = ['home', 'course', 'mine', 'mall', 'private'] const failures = [] -const assertFile = (path) => { - if (!existsSync(path)) failures.push(`Missing file: ${path}`) +const pagesJson = JSON.parse(readFileSync(resolve(srcRoot, 'pages.json'), 'utf8')) + +if (!pagesJson.tabBar) { + failures.push('pages.json missing tabBar configuration') +} else { + const tabPaths = pagesJson.tabBar.list.map(item => item.pagePath) + for (const page of tabBarPages) { + if (!tabPaths.includes(page)) { + failures.push(`tabBar missing page: ${page}`) + } + } } -assertFile(resolve(srcRoot, 'components/VenueTabBar.vue')) - -for (const { file, venue, active } of tabPages) { +for (const { file } of tabPages) { const path = resolve(srcRoot, file) - assertFile(path) - if (!existsSync(path)) continue - - const content = readFileSync(path, 'utf8') - if (!content.includes('`) - } - if (!content.includes(`venue="${venue}"`)) { - failures.push(`${file} does not pass venue="${venue}"`) - } - if (!content.includes(`active="${active}"`)) { - failures.push(`${file} does not pass active="${active}"`) - } - if (!content.includes("import VenueTabBar from '@/components/VenueTabBar.vue'")) { - failures.push(`${file} does not import VenueTabBar`) + if (!existsSync(path)) { + failures.push(`Missing tab page: ${file}`) } } -for (const venue of venues) { - for (const icon of icons) { - assertFile(resolve(srcRoot, `static/${venue}/tab/${icon}.png`)) - assertFile(resolve(srcRoot, `static/${venue}/tab/${icon}-active.png`)) +for (const icon of icons) { + const iconPath = resolve(srcRoot, `static/comprehensive/tab/${icon}.png`) + const activeIconPath = resolve(srcRoot, `static/comprehensive/tab/${icon}-active.png`) + if (!existsSync(iconPath)) failures.push(`Missing icon: static/comprehensive/tab/${icon}.png`) + if (!existsSync(activeIconPath)) failures.push(`Missing icon: static/comprehensive/tab/${icon}-active.png`) +} + +const venuePages = [ + 'pages/comprehensive/home/index.vue', + 'pages/comprehensive/courses/index.vue', + 'pages/comprehensive/profile/index.vue', + 'pages/ice/home/index.vue', + 'pages/ice/courses/index.vue', + 'pages/ice/profile/index.vue', + 'pages/ice/private/index.vue', + 'pages/ice/mall/index.vue' +] + +for (const file of venuePages) { + const path = resolve(srcRoot, file) + if (!existsSync(path)) { + failures.push(`Missing venue page: ${file}`) + continue } + const content = readFileSync(path, 'utf8') + if (content.includes('VenueTabBar')) { + failures.push(`${file} still references VenueTabBar`) + } +} + +if (existsSync(resolve(srcRoot, 'components/VenueTabBar.vue'))) { + failures.push('VenueTabBar.vue should be deleted') } if (failures.length) { - console.error(`Venue tabbar verification failed with ${failures.length} issue(s):`) + console.error(`TabBar verification failed with ${failures.length} issue(s):`) for (const failure of failures) console.error(`- ${failure}`) process.exit(1) } -console.log('Venue tabbar verification passed.') +console.log('TabBar verification passed.') diff --git a/miniprogram/src/App.vue b/miniprogram/src/App.vue index 5943dd9..4b92b52 100644 --- a/miniprogram/src/App.vue +++ b/miniprogram/src/App.vue @@ -21,6 +21,7 @@ page { line-height: 1.5; box-sizing: border-box; -webkit-text-size-adjust: 100%; + padding-top: var(--status-bar-height, 0px); } view, diff --git a/miniprogram/src/components/VenueTabBar.vue b/miniprogram/src/components/VenueTabBar.vue deleted file mode 100644 index 5261cbd..0000000 --- a/miniprogram/src/components/VenueTabBar.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - - - diff --git a/miniprogram/src/pages.json b/miniprogram/src/pages.json index ab88c88..c35d829 100644 --- a/miniprogram/src/pages.json +++ b/miniprogram/src/pages.json @@ -17,24 +17,54 @@ } }, { - "path": "pages/comprehensive/home/index", + "path": "pages/home/index", "style": { "navigationBarTitleText": "首页", "enablePullDownRefresh": true } }, + { + "path": "pages/private/index", + "style": { + "navigationBarTitleText": "订场" + } + }, + { + "path": "pages/mall/index", + "style": { + "navigationBarTitleText": "商城", + "enablePullDownRefresh": true + } + }, + { + "path": "pages/courses/index", + "style": { + "navigationBarTitleText": "约课", + "enablePullDownRefresh": true + } + }, + { + "path": "pages/profile/index", + "style": { + "navigationBarTitleText": "我的" + } + }, + { + "path": "pages/comprehensive/home/index", + "style": { + "navigationBarTitleText": "首页" + } + }, { "path": "pages/comprehensive/courses/index", "style": { - "navigationBarTitleText": "课程", - "enablePullDownRefresh": true + "navigationBarTitleText": "约课" } }, { "path": "pages/comprehensive/bookings/index", "style": { - "navigationBarTitleText": "我的预约", - "enablePullDownRefresh": true + "navigationBarTitleText": "我的预约" } }, { @@ -71,7 +101,7 @@ { "path": "pages/comprehensive/private/index", "style": { - "navigationBarTitleText": "包场预约" + "navigationBarTitleText": "订场" } }, { @@ -175,15 +205,25 @@ { "path": "pages/ice/home/index", "style": { - "navigationBarTitleText": "首页", - "enablePullDownRefresh": true + "navigationBarTitleText": "首页" + } + }, + { + "path": "pages/ice/private/index", + "style": { + "navigationBarTitleText": "订场" + } + }, + { + "path": "pages/ice/mall/index", + "style": { + "navigationBarTitleText": "商城" } }, { "path": "pages/ice/courses/index", "style": { - "navigationBarTitleText": "近期课程", - "enablePullDownRefresh": true + "navigationBarTitleText": "近期课程" } }, { @@ -238,7 +278,46 @@ } } ], + "tabBar": { + "color": "#6D7C84", + "selectedColor": "#0B8FB3", + "backgroundColor": "#FFFFFF", + "borderStyle": "white", + "list": [ + { + "pagePath": "pages/home/index", + "text": "首页", + "iconPath": "static/comprehensive/tab/home.png", + "selectedIconPath": "static/comprehensive/tab/home-active.png" + }, + { + "pagePath": "pages/private/index", + "text": "订场", + "iconPath": "static/comprehensive/tab/private.png", + "selectedIconPath": "static/comprehensive/tab/private-active.png" + }, + { + "pagePath": "pages/mall/index", + "text": "商城", + "iconPath": "static/comprehensive/tab/mall.png", + "selectedIconPath": "static/comprehensive/tab/mall-active.png" + }, + { + "pagePath": "pages/courses/index", + "text": "约课", + "iconPath": "static/comprehensive/tab/course.png", + "selectedIconPath": "static/comprehensive/tab/course-active.png" + }, + { + "pagePath": "pages/profile/index", + "text": "我的", + "iconPath": "static/comprehensive/tab/mine.png", + "selectedIconPath": "static/comprehensive/tab/mine-active.png" + } + ] + }, "globalStyle": { + "navigationStyle": "custom", "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF", "backgroundColor": "#F8FAFC", diff --git a/miniprogram/src/pages/comprehensive/bookings/index.vue b/miniprogram/src/pages/comprehensive/bookings/index.vue index b60d37e..0f5e58f 100644 --- a/miniprogram/src/pages/comprehensive/bookings/index.vue +++ b/miniprogram/src/pages/comprehensive/bookings/index.vue @@ -36,7 +36,6 @@ 加载中... - @@ -47,7 +46,6 @@ import { ticketApi } from '@/modules/comprehensive/api/ticket' import { membershipApi } from '@/modules/comprehensive/api/membership' import { useComprehensiveSessionStore } from '@/modules/comprehensive/stores/session' import { formatDateTime, formatTimeRange } from '@/modules/comprehensive/utils/date' -import VenueTabBar from '@/components/VenueTabBar.vue' import UnauthLoginPanel from '@/components/UnauthLoginPanel.vue' const session = useComprehensiveSessionStore() @@ -124,6 +122,8 @@ const loadItems = async () => { } } +defineExpose({ refresh: loadItems }) + const getItemTitle = (item) => { if (businessType.value === 'course') return item.session?.title || '课程预约' if (businessType.value === 'private') return item.courts?.map((court) => court.name).join('、') || '包场预约' diff --git a/miniprogram/src/pages/comprehensive/courses/index.vue b/miniprogram/src/pages/comprehensive/courses/index.vue index f2a548e..2a93d7a 100644 --- a/miniprogram/src/pages/comprehensive/courses/index.vue +++ b/miniprogram/src/pages/comprehensive/courses/index.vue @@ -41,17 +41,14 @@ 当前筛选条件下暂无课程 已加载全部 - diff --git a/miniprogram/src/pages/comprehensive/profile/index.vue b/miniprogram/src/pages/comprehensive/profile/index.vue index 36d0ca4..2655899 100644 --- a/miniprogram/src/pages/comprehensive/profile/index.vue +++ b/miniprogram/src/pages/comprehensive/profile/index.vue @@ -67,7 +67,6 @@ - @@ -76,7 +75,6 @@ import { computed, onMounted, ref } from 'vue' import { useComprehensiveSessionStore } from '@/modules/comprehensive/stores/session' import { memberApi } from '@/modules/comprehensive/api/member' import { formatAmount } from '@/modules/comprehensive/utils/money' -import VenueTabBar from '@/components/VenueTabBar.vue' import AgreementLinks from '@/components/AgreementLinks.vue' import UnauthLoginPanel from '@/components/UnauthLoginPanel.vue' @@ -86,14 +84,12 @@ const balance = ref('0.00') const balanceText = computed(() => formatAmount(balance.value)) const menuItems = [ - { title: '包场预约', url: '/pages/comprehensive/private/index', theme: 'private-theme', icon: 'private' }, { title: '篮球门票', url: '/pages/comprehensive/tickets/index', theme: 'ticket-theme', icon: 'ticket' }, - { title: '商城', url: '/pages/comprehensive/mall/index', theme: 'order-theme', icon: 'order' }, { title: '充值', url: '/pages/comprehensive/mall/index', theme: 'order-theme', icon: 'order' }, { title: '我的次卡', url: '/pages/comprehensive/membership/cards', theme: 'profile-theme', icon: 'profile' }, { title: '我的订单', url: '/pages/comprehensive/profile/orders', theme: 'order-theme', icon: 'order' }, + { title: '我的预约', url: '/pages/comprehensive/bookings/index', theme: 'order-theme', icon: 'order' }, { title: '余额流水', url: '/pages/comprehensive/profile/balance', theme: 'order-theme', icon: 'order' }, - { title: '消费记录', url: '/pages/comprehensive/profile/orders', theme: 'order-theme', icon: 'order' }, { title: '个人信息', url: '/pages/comprehensive/profile/detail', theme: 'profile-theme', icon: 'profile' }, { title: '切换场馆', url: '/pages/venue-select/index?mode=switch', theme: 'profile-theme', icon: 'profile' } ] @@ -120,6 +116,8 @@ const logout = () => { const go = (url) => { uni.navigateTo({ url }) } + +defineExpose({ onPageShow: () => {} }) diff --git a/miniprogram/src/pages/home/index.vue b/miniprogram/src/pages/home/index.vue new file mode 100644 index 0000000..8249cbe --- /dev/null +++ b/miniprogram/src/pages/home/index.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/miniprogram/src/pages/ice/bookings/index.vue b/miniprogram/src/pages/ice/bookings/index.vue index 324c08e..707d313 100644 --- a/miniprogram/src/pages/ice/bookings/index.vue +++ b/miniprogram/src/pages/ice/bookings/index.vue @@ -107,7 +107,6 @@ /> - @@ -117,7 +116,6 @@ import { onPullDownRefresh, onReachBottom, onShow } from '@dcloudio/uni-app' import { bookingApi } from '@/modules/ice/api/booking' import { authStorage } from '@/modules/ice/api/member' import { errorMessage, getMemberSession, loginAndStoreToken, sessionStatusFromError, SESSION_STATUS } from '@/modules/ice/api/session' -import VenueTabBar from '@/components/VenueTabBar.vue' import StatePanel from '@/components/ice/StatePanel.vue' import UnauthLoginPanel from '@/components/UnauthLoginPanel.vue' @@ -297,7 +295,7 @@ const applySessionError = (err) => { } const goProfile = () => { - uni.reLaunch({ url: '/pages/ice/profile/index' }) + uni.switchTab({ url: '/pages/profile/index' }) } diff --git a/miniprogram/src/pages/ice/courses/index.vue b/miniprogram/src/pages/ice/courses/index.vue index 024b785..0d271d5 100644 --- a/miniprogram/src/pages/ice/courses/index.vue +++ b/miniprogram/src/pages/ice/courses/index.vue @@ -90,16 +90,13 @@ compact /> - diff --git a/miniprogram/src/pages/ice/private/index.vue b/miniprogram/src/pages/ice/private/index.vue new file mode 100644 index 0000000..605aadc --- /dev/null +++ b/miniprogram/src/pages/ice/private/index.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/miniprogram/src/pages/ice/profile/index.vue b/miniprogram/src/pages/ice/profile/index.vue index 6df3d25..af7b2c1 100644 --- a/miniprogram/src/pages/ice/profile/index.vue +++ b/miniprogram/src/pages/ice/profile/index.vue @@ -176,6 +176,21 @@ + + + + + + + + + 我的预约 + + + + + + @@ -209,16 +224,13 @@ - diff --git a/miniprogram/src/pages/private/index.vue b/miniprogram/src/pages/private/index.vue new file mode 100644 index 0000000..c57a5f2 --- /dev/null +++ b/miniprogram/src/pages/private/index.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/miniprogram/src/pages/profile/index.vue b/miniprogram/src/pages/profile/index.vue new file mode 100644 index 0000000..83764ba --- /dev/null +++ b/miniprogram/src/pages/profile/index.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/miniprogram/src/static/comprehensive/tab/mall-active.png b/miniprogram/src/static/comprehensive/tab/mall-active.png new file mode 100644 index 0000000..532109d Binary files /dev/null and b/miniprogram/src/static/comprehensive/tab/mall-active.png differ diff --git a/miniprogram/src/static/comprehensive/tab/mall.png b/miniprogram/src/static/comprehensive/tab/mall.png new file mode 100644 index 0000000..f0c28ef Binary files /dev/null and b/miniprogram/src/static/comprehensive/tab/mall.png differ diff --git a/miniprogram/src/static/comprehensive/tab/private-active.png b/miniprogram/src/static/comprehensive/tab/private-active.png new file mode 100644 index 0000000..677f5ef Binary files /dev/null and b/miniprogram/src/static/comprehensive/tab/private-active.png differ diff --git a/miniprogram/src/static/comprehensive/tab/private.png b/miniprogram/src/static/comprehensive/tab/private.png new file mode 100644 index 0000000..f13f87f Binary files /dev/null and b/miniprogram/src/static/comprehensive/tab/private.png differ diff --git a/miniprogram/src/static/ice/tab/mall-active.png b/miniprogram/src/static/ice/tab/mall-active.png new file mode 100644 index 0000000..532109d Binary files /dev/null and b/miniprogram/src/static/ice/tab/mall-active.png differ diff --git a/miniprogram/src/static/ice/tab/mall.png b/miniprogram/src/static/ice/tab/mall.png new file mode 100644 index 0000000..f0c28ef Binary files /dev/null and b/miniprogram/src/static/ice/tab/mall.png differ diff --git a/miniprogram/src/static/ice/tab/private-active.png b/miniprogram/src/static/ice/tab/private-active.png new file mode 100644 index 0000000..677f5ef Binary files /dev/null and b/miniprogram/src/static/ice/tab/private-active.png differ diff --git a/miniprogram/src/static/ice/tab/private.png b/miniprogram/src/static/ice/tab/private.png new file mode 100644 index 0000000..f13f87f Binary files /dev/null and b/miniprogram/src/static/ice/tab/private.png differ diff --git a/miniprogram/src/utils/venue.js b/miniprogram/src/utils/venue.js index 6727b65..e0428e5 100644 --- a/miniprogram/src/utils/venue.js +++ b/miniprogram/src/utils/venue.js @@ -6,27 +6,13 @@ export const VENUE_KEYS = Object.freeze({ }) export const VENUE_OPTIONS = Object.freeze([ - { - key: VENUE_KEYS.ICE, - name: '冰场馆', - description: '课程预约、会员卡与滑冰服务', - homePath: '/pages/ice/home/index' - }, - { - key: VENUE_KEYS.COMPREHENSIVE, - name: '综合场馆', - description: '课程、包场、门票、订单与余额', - homePath: '/pages/comprehensive/home/index' - } + { key: VENUE_KEYS.ICE, name: '冰场馆', description: '课程预约、会员卡与滑冰服务' }, + { key: VENUE_KEYS.COMPREHENSIVE, name: '综合场馆', description: '课程、包场、门票、订单与余额' } ]) -export const isVenueKey = (value) => { - return value === VENUE_KEYS.ICE || value === VENUE_KEYS.COMPREHENSIVE -} +export const isVenueKey = (value) => value === VENUE_KEYS.ICE || value === VENUE_KEYS.COMPREHENSIVE -export const getVenueOption = (venueKey) => { - return VENUE_OPTIONS.find((item) => item.key === venueKey) || null -} +export const getVenueOption = (venueKey) => VENUE_OPTIONS.find((item) => item.key === venueKey) || null export const getStoredVenue = () => { const venue = uni.getStorageSync(CURRENT_VENUE_KEY) @@ -38,18 +24,14 @@ export const setStoredVenue = (venueKey) => { uni.removeStorageSync(CURRENT_VENUE_KEY) return '' } - uni.setStorageSync(CURRENT_VENUE_KEY, venueKey) return venueKey } -export const navigateToVenueHome = (venueKey, options = {}) => { - const venue = getVenueOption(venueKey) - if (!venue) { +export const navigateToVenueHome = (venueKey) => { + if (!isVenueKey(venueKey)) { uni.reLaunch({ url: '/pages/venue-select/index' }) return } - - const navigate = options.redirect === true ? uni.redirectTo : uni.reLaunch - navigate({ url: venue.homePath }) + uni.reLaunch({ url: '/pages/home/index' }) }