@@ -65,6 +65,21 @@ const syncPageTitle = (title: string) => {
|
|||||||
if (typeof document !== 'undefined') document.title = title
|
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 loadPage = async (pageNo: number, replace: boolean) => {
|
||||||
const hallId = selectedExplainHallId.value
|
const hallId = selectedExplainHallId.value
|
||||||
if (!hallId || disposed || (!replace && (loadingMore.value || !hasMore.value))) return false
|
if (!hallId || disposed || (!replace && (loadingMore.value || !hasMore.value))) return false
|
||||||
@@ -115,8 +130,8 @@ const loadNextPage = () => void loadPage(nextPageNo.value, false)
|
|||||||
onLoad((options: Record<string, string | string[] | undefined> = {}) => {
|
onLoad((options: Record<string, string | string[] | undefined> = {}) => {
|
||||||
const first = (value: string | string[] | undefined) => Array.isArray(value) ? value[0] : value
|
const first = (value: string | string[] | undefined) => Array.isArray(value) ? value[0] : value
|
||||||
selectedExplainHallId.value = first(options.hallId) || ''
|
selectedExplainHallId.value = first(options.hallId) || ''
|
||||||
selectedExplainHallName.value = first(options.hallName) || '讲解对象'
|
selectedExplainHallName.value = decodeRouteParam(first(options.hallName) || '讲解对象')
|
||||||
syncPageTitle('讲解对象')
|
syncPageTitle(selectedExplainHallName.value)
|
||||||
if (!selectedExplainHallId.value) {
|
if (!selectedExplainHallId.value) {
|
||||||
explainError.value = '缺少展厅参数,请返回展厅列表后重试'
|
explainError.value = '缺少展厅参数,请返回展厅列表后重试'
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -98,18 +98,21 @@ describe('讲解对象列表返回', () => {
|
|||||||
wrapper.unmount()
|
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()
|
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()
|
await flushPromises()
|
||||||
|
|
||||||
|
expect(uni.setNavigationBarTitle).toHaveBeenCalledWith({ title: '演化厅' })
|
||||||
|
expect(document.title).toBe('演化厅')
|
||||||
|
|
||||||
await wrapper.get('[data-testid="detail-click"]').trigger('click')
|
await wrapper.get('[data-testid="detail-click"]').trigger('click')
|
||||||
|
|
||||||
const url = vi.mocked(uni.navigateTo).mock.calls[0]?.[0]?.url || ''
|
const url = vi.mocked(uni.navigateTo).mock.calls[0]?.[0]?.url || ''
|
||||||
const params = new URLSearchParams(url.split('?')[1])
|
const params = new URLSearchParams(url.split('?')[1])
|
||||||
expect(url.split('?')[0]).toBe('/pages/exhibit/detail')
|
expect(url.split('?')[0]).toBe('/pages/exhibit/detail')
|
||||||
expect(params.get('hallId')).toBe('hall-1')
|
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('targetType')).toBe('STOP')
|
||||||
expect(params.get('targetId')).toBe('target-1')
|
expect(params.get('targetId')).toBe('target-1')
|
||||||
wrapper.unmount()
|
wrapper.unmount()
|
||||||
|
|||||||
Reference in New Issue
Block a user