Skip to content

Commit 119c22b

Browse files
pythonHuangclaude
andcommitted
fix: 报表管理列表页预览空白/PDF与Excel操作失败/打印空白-预览打开自动查询+查询按钮常驻;request拦截器放行blob下载;导出改取response.data;打印改为取预览HTML写新窗口触发print
Co-Authored-By: Claude Code <noreply@anthropic.com>
1 parent f653d73 commit 119c22b

2 files changed

Lines changed: 33 additions & 16 deletions

File tree

‎JuggleNet6.Frontend/src/utils/request.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ request.interceptors.request.use((config) => {
2020
request.interceptors.response.use(
2121
(response) => {
2222
const data = response.data
23+
// blob 下载(文件导出)直接放行
24+
if (data instanceof Blob) return response
2325
if (data.code === 200) {
2426
return data
2527
} else if (data.code === 401) {

‎JuggleNet6.Frontend/src/views/report/ReportList.vue‎

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,17 @@
3434
</el-card>
3535

3636
<el-dialog v-model="previewVisible" title="预览报表" width="90%" top="5vh">
37-
<div v-if="previewParams.length>0" style="display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap">
37+
<div style="display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap;align-items:center">
3838
<div v-for="p in previewParams" :key="p.name" style="display:flex;align-items:center;gap:4px">
3939
<span style="font-size:12px">{{ p.label||p.name }}:</span>
4040
<el-input v-model="previewValues[p.name]" size="small" style="width:140px" />
4141
</div>
42-
<el-button size="small" type="primary" @click="doPreview">查询</el-button>
42+
<el-button size="small" type="primary" :loading="previewLoading" @click="doPreview">查询</el-button>
43+
<span style="font-size:12px;color:#888;margin-left:auto">第 {{ previewPage }} 页 · 每页 {{ previewPageSize }} 行</span>
44+
<el-pagination small layout="prev,next" :total="previewTotal" v-model:current-page="previewPage" :page-size="previewPageSize" @change="doPreview" />
4345
</div>
44-
<div style="display:flex;gap:8px;align-items:center;margin-bottom:12px">
45-
<span style="font-size:12px;color:#888">第 {{ previewPage }} 页 · 每页 {{ previewPageSize }} 行</span>
46-
<el-pagination small layout="prev,next" :total="previewTotal" v-model:current-page="previewPage" :page-size="previewPageSize" @change="doPreview" style="margin-left:auto" />
47-
</div>
48-
<div v-if="previewHtml" v-html="previewHtml" style="border:1px solid #eee;padding:16px;overflow:auto;max-height:65vh"></div>
46+
<div v-loading="previewLoading" v-if="previewHtml" v-html="previewHtml" style="border:1px solid #eee;padding:16px;overflow:auto;max-height:65vh"></div>
47+
<el-empty v-else-if="!previewLoading" description="暂无数据" :image-size="60" />
4948
</el-dialog>
5049
</div>
5150
</template>
@@ -63,6 +62,7 @@ const page = ref(1)
6362
const total = ref(0)
6463
const previewVisible = ref(false)
6564
const previewHtml = ref('')
65+
const previewLoading = ref(false)
6666
const previewParams = ref<any[]>([])
6767
const previewValues = ref<Record<string,any>>({})
6868
const previewId = ref(0)
@@ -97,27 +97,42 @@ function openPreview(row: any) {
9797
previewValues.value = {}
9898
for (const p of previewParams.value) previewValues.value[p.name] = p.default || ''
9999
previewHtml.value = ''
100+
previewPage.value = 1
100101
previewVisible.value = true
102+
doPreview() // 打开即自动查询(无参数报表也能出数据)
101103
}
102104
103105
async function doPreview() {
104-
const res = await request.post('/report/preview', { id: previewId.value, params: previewValues.value, page: previewPage.value, pageSize: previewPageSize.value })
105-
previewHtml.value = res.data?.html || ''
106-
previewTotal.value = res.data?.total || 0
106+
previewLoading.value = true
107+
try {
108+
const res = await request.post('/report/preview', { id: previewId.value, params: previewValues.value, page: previewPage.value, pageSize: previewPageSize.value })
109+
previewHtml.value = res.data?.html || ''
110+
previewTotal.value = res.data?.total || 0
111+
} finally { previewLoading.value = false }
107112
}
108113
109114
async function doExportPdf(row: any) {
110-
const res = await request.post('/report/export-pdf', { id: row.id, params: {} }, { responseType: 'blob' })
111-
downloadBlob(res, `${row.name}.html`)
115+
const res: any = await request.post('/report/export-pdf', { id: row.id, params: {} }, { responseType: 'blob' })
116+
downloadBlob(res.data, `${row.name}.html`)
112117
}
113118
114119
async function doExportExcel(row: any) {
115-
const res = await request.post('/report/export-excel', { id: row.id, params: {} }, { responseType: 'blob' })
116-
downloadBlob(res, `${row.name}.xls`)
120+
const res: any = await request.post('/report/export-excel', { id: row.id, params: {} }, { responseType: 'blob' })
121+
downloadBlob(res.data, `${row.name}.xls`)
117122
}
118123
119-
function doPrint(_row: any) {
120-
window.open(`${location.origin}/api/report/export-pdf`, '_blank')
124+
/** 打印:取预览 HTML 写入新窗口并触发浏览器打印 */
125+
async function doPrint(row: any) {
126+
try {
127+
const res = await request.post('/report/preview', { id: row.id, params: {} })
128+
const html = res.data?.html || ''
129+
const w = window.open('', '_blank')
130+
if (!w) { ElMessage.warning('浏览器拦截了弹出窗口,请允许后重试'); return }
131+
w.document.write(`<html><head><title>${row.name}</title><meta charset="utf-8"><style>@media print{@page{size:A4;margin:15mm}}body{font-family:'Microsoft YaHei',sans-serif}</style></head><body>${html}</body></html>`)
132+
w.document.close()
133+
w.focus()
134+
setTimeout(() => { w.print() }, 300)
135+
} catch { /* 拦截器已提示 */ }
121136
}
122137
123138
function downloadBlob(data: any, filename: string) {

0 commit comments

Comments
 (0)