fix: harden performance survey xlsx downloads
This commit is contained in:
parent
2163ddb4f7
commit
52ad6aeb04
@ -2,7 +2,9 @@ import ExcelJS from 'exceljs'
|
||||
import {
|
||||
buildPerformanceSurveyDashboardWorkbook,
|
||||
buildPerformanceSurveyExportTable,
|
||||
choosePerformanceSurveyExportDestination,
|
||||
sanitizePerformanceSurveyExportFileName,
|
||||
savePerformanceSurveyDashboardWorkbook,
|
||||
type PerformanceSurveyDashboardExportData,
|
||||
} from '@/lib/performance-survey-dashboard-export'
|
||||
|
||||
@ -85,4 +87,44 @@ describe('performance survey dashboard xlsx export', () => {
|
||||
expect(sanitizePerformanceSurveyExportFileName('考核:品牌/设计*主管'))
|
||||
.toBe('考核_品牌_设计_主管.xlsx')
|
||||
})
|
||||
|
||||
test('keeps the browser context when opening the native save picker', async () => {
|
||||
const handle = { createWritable: jest.fn() }
|
||||
const picker = jest.fn(function (this: unknown) {
|
||||
expect(this).toBe(window)
|
||||
return Promise.resolve(handle)
|
||||
})
|
||||
Object.defineProperty(window, 'showSaveFilePicker', {
|
||||
configurable: true,
|
||||
value: picker,
|
||||
})
|
||||
|
||||
await expect(choosePerformanceSurveyExportDestination('考核调研.xlsx'))
|
||||
.resolves.toEqual({ kind: 'file-system', handle })
|
||||
expect(picker).toHaveBeenCalledWith(expect.objectContaining({
|
||||
suggestedName: '考核调研.xlsx',
|
||||
}))
|
||||
|
||||
delete (window as typeof window & { showSaveFilePicker?: unknown }).showSaveFilePicker
|
||||
})
|
||||
|
||||
test('uses a native blob download when the save picker is unavailable', async () => {
|
||||
const createObjectURL = jest.fn(() => 'blob:performance-survey-export')
|
||||
const revokeObjectURL = jest.fn()
|
||||
Object.defineProperty(URL, 'createObjectURL', { configurable: true, value: createObjectURL })
|
||||
Object.defineProperty(URL, 'revokeObjectURL', { configurable: true, value: revokeObjectURL })
|
||||
const click = jest.spyOn(HTMLAnchorElement.prototype, 'click').mockImplementation(() => {})
|
||||
|
||||
await savePerformanceSurveyDashboardWorkbook(
|
||||
exportData,
|
||||
'考核调研_品牌创意主管_2026-07.xlsx',
|
||||
{ kind: 'download' },
|
||||
)
|
||||
|
||||
expect(createObjectURL).toHaveBeenCalledWith(expect.any(Blob))
|
||||
expect(click).toHaveBeenCalledTimes(1)
|
||||
await new Promise((resolve) => window.setTimeout(resolve, 0))
|
||||
expect(revokeObjectURL).toHaveBeenCalledWith('blob:performance-survey-export')
|
||||
click.mockRestore()
|
||||
})
|
||||
})
|
||||
|
||||
@ -211,7 +211,7 @@ export async function choosePerformanceSurveyExportDestination(
|
||||
if (!picker) return { kind: 'download' }
|
||||
|
||||
try {
|
||||
const handle = await picker({
|
||||
const handle = await picker.call(window, {
|
||||
suggestedName,
|
||||
types: [{
|
||||
description: 'WPS/Excel 工作簿',
|
||||
@ -243,6 +243,26 @@ export async function savePerformanceSurveyDashboardWorkbook(
|
||||
return
|
||||
}
|
||||
|
||||
const { saveAs } = await import('file-saver')
|
||||
saveAs(blob, fileName)
|
||||
if (
|
||||
typeof document === 'undefined'
|
||||
|| typeof URL === 'undefined'
|
||||
|| typeof URL.createObjectURL !== 'function'
|
||||
) {
|
||||
throw new Error('当前浏览器无法创建下载文件,请更换 Chrome 或 Edge 后重试。')
|
||||
}
|
||||
|
||||
const objectUrl = URL.createObjectURL(blob)
|
||||
const anchor = document.createElement('a')
|
||||
anchor.href = objectUrl
|
||||
anchor.download = fileName
|
||||
anchor.rel = 'noopener'
|
||||
anchor.style.display = 'none'
|
||||
document.body.appendChild(anchor)
|
||||
|
||||
try {
|
||||
anchor.click()
|
||||
} finally {
|
||||
anchor.remove()
|
||||
window.setTimeout(() => URL.revokeObjectURL(objectUrl), 0)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user