diff --git a/src/pages/explain/guide-stop-list.vue b/src/pages/explain/guide-stop-list.vue index 089602a..2abde0c 100644 --- a/src/pages/explain/guide-stop-list.vue +++ b/src/pages/explain/guide-stop-list.vue @@ -65,6 +65,21 @@ const syncPageTitle = (title: string) => { if (typeof document !== 'undefined') document.title = title } +const decodeRouteParam = (value: string) => { + let decoded = value + // H5 hash routes embedded in web-view can add multiple URL-encoding layers. + for (let index = 0; index < 8; index += 1) { + try { + const next = decodeURIComponent(decoded) + if (next === decoded) break + decoded = next + } catch { + break + } + } + return decoded +} + const loadPage = async (pageNo: number, replace: boolean) => { const hallId = selectedExplainHallId.value if (!hallId || disposed || (!replace && (loadingMore.value || !hasMore.value))) return false @@ -115,8 +130,8 @@ const loadNextPage = () => void loadPage(nextPageNo.value, false) onLoad((options: Record = {}) => { const first = (value: string | string[] | undefined) => Array.isArray(value) ? value[0] : value selectedExplainHallId.value = first(options.hallId) || '' - selectedExplainHallName.value = first(options.hallName) || '讲解对象' - syncPageTitle('讲解对象') + selectedExplainHallName.value = decodeRouteParam(first(options.hallName) || '讲解对象') + syncPageTitle(selectedExplainHallName.value) if (!selectedExplainHallId.value) { explainError.value = '缺少展厅参数,请返回展厅列表后重试' return diff --git a/tests/unit/ExplainGuideStopListNavigation.spec.ts b/tests/unit/ExplainGuideStopListNavigation.spec.ts index c375dc8..d2178df 100644 --- a/tests/unit/ExplainGuideStopListNavigation.spec.ts +++ b/tests/unit/ExplainGuideStopListNavigation.spec.ts @@ -98,18 +98,21 @@ describe('讲解对象列表返回', () => { wrapper.unmount() }) - it('keeps the selected hall context when an object payload omits hall fields', async () => { + it('uses the decoded hall name as the page title and detail context', async () => { const wrapper = mountGuideStopList() - testState.onLoadHandler?.({ hallId: 'hall-1', hallName: '恐龙厅' }) + testState.onLoadHandler?.({ hallId: 'hall-1', hallName: '%25E6%25BC%2594%25E5%258C%2596%25E5%258E%2585' }) await flushPromises() + expect(uni.setNavigationBarTitle).toHaveBeenCalledWith({ title: '演化厅' }) + expect(document.title).toBe('演化厅') + await wrapper.get('[data-testid="detail-click"]').trigger('click') const url = vi.mocked(uni.navigateTo).mock.calls[0]?.[0]?.url || '' const params = new URLSearchParams(url.split('?')[1]) expect(url.split('?')[0]).toBe('/pages/exhibit/detail') expect(params.get('hallId')).toBe('hall-1') - expect(params.get('hallName')).toBe('恐龙厅') + expect(params.get('hallName')).toBe('演化厅') expect(params.get('targetType')).toBe('STOP') expect(params.get('targetId')).toBe('target-1') wrapper.unmount()