Files
guoju0808/ry-vue3/src/views/portal/SupportLetter.vue
T
2026-10-08 14:07:27 +00:00

195 lines
7.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="portal-support-letter">
<h1 class="page-title">支持函</h1>
<p class="page-sub">查看项目支持函(含 PDF 文件下载/预览)</p>
<el-form inline :model="q" class="filter-bar" @keyup.enter="onSearch">
<el-form-item label="项目编号:">
<el-input v-model="q.projectNo" placeholder="输入项目编号" clearable />
</el-form-item>
<el-form-item label="标题:">
<el-input v-model="q.title" placeholder="输入标题" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSearch">查询</el-button>
<el-button @click="onReset">重置</el-button>
</el-form-item>
</el-form>
<div class="page-card">
<el-table :data="rows" v-loading="loading" stripe border>
<el-table-column prop="title" label="支持函标题" min-width="260" show-overflow-tooltip />
<el-table-column prop="projectNo" label="项目编号" width="160" />
<el-table-column prop="publishTime" label="发布时间" width="180">
<template #default="{ row }">{{ fmt(row.publishTime) }}</template>
</el-table-column>
<el-table-column prop="supportCount" label="支持单位数" width="120" align="center" />
<el-table-column label="操作" width="220" fixed="right">
<template #default="{ row }"><div class="table-actions">
<el-link :underline="false" type="primary" @click="openDetail(row)">详情</el-link>
<el-link :underline="false" type="primary" :disabled="!row.fileUrl" @click="openPreview(row)">预览</el-link>
</div></template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="page.pageNum" v-model:page-size="page.pageSize"
:total="page.total" :page-sizes="[10,20,50]"
layout="total, sizes, prev, pager, next, jumper"
@current-change="load" @size-change="load"
style="margin-top: 12px; text-align: right;" />
</div>
<!-- 详情 dialog -->
<el-dialog v-model="detailOpen" title="支持函详情" width="640" top="6vh">
<el-descriptions v-if="current" :column="1" border>
<el-descriptions-item label="标题">{{ current.title }}</el-descriptions-item>
<el-descriptions-item label="项目编号">{{ current.projectNo }}</el-descriptions-item>
<el-descriptions-item label="发布时间">{{ fmt(current.publishTime) }}</el-descriptions-item>
<el-descriptions-item label="支持单位数">{{ current.supportCount }}</el-descriptions-item>
<el-descriptions-item label="文件">
<el-link v-if="current.fileUrl" type="primary" @click="openPreview(current)">点击预览</el-link>
<span v-else>-</span>
</el-descriptions-item>
</el-descriptions>
</el-dialog>
<!-- 预览组件 -->
<Preview v-model="previewOpen" :url="previewUrl" :title="previewTitle" />
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { bizList } from '@/api/public'
import Preview from '@/components/Preview.vue'
const q = ref({ projectNo: '', title: '' })
const rows = ref([])
const loading = ref(false)
const page = reactive({ pageNum: 1, pageSize: 20, total: 0 })
async function load() {
loading.value = true
try {
const { data } = await bizList('supportLetter', { ...q.value, pageNum: page.pageNum, pageSize: page.pageSize })
rows.value = data?.rows || []
page.total = data?.total || 0
} catch (e) { rows.value = []; page.total = 0 }
finally { loading.value = false }
}
function onSearch() { page.pageNum = 1; load() }
function onReset() { q.value = { projectNo: '', title: '' }; onSearch() }
// 只显示年月日, 不显示时分秒 (与 portal/Publicity.vue fmtDate 口径一致)
function fmt(t) {
if (!t) return ''
const d = new Date(t)
const p = n => String(n).padStart(2, '0')
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`
}
const detailOpen = ref(false)
const current = ref(null)
function openDetail(row) { current.value = row; detailOpen.value = true }
const previewOpen = ref(false)
const previewUrl = ref('')
const previewTitle = ref('支持函预览')
function openPreview(row) {
previewUrl.value = row.fileUrl
previewTitle.value = `支持函预览 - ${row.title || ''}`
previewOpen.value = true
}
load()
</script>
<style scoped>
.portal-support-letter { padding: 16px; }
.page-title { font-size: 20px; font-weight: 600; margin: 0 0 8px; }
.page-sub { color: #909399; font-size: 13px; margin: 0 0 16px; }
.filter-bar { background: #fff; padding: 16px 20px; border-radius: 6px; border: 1px solid #f0f0f0; margin-bottom: 12px; }
.page-card { background: #fff; padding: 16px; border-radius: 6px; border: 1px solid #f0f0f0; }
/* ========================================
移动端适配 (≤768px)
- 卡片 padding 收窄
- 工具栏横向滚动
- filter-form: label 与输入框横向
- 表格字号收紧
======================================== */
@media (max-width: 768px) {
/* 卡片 padding */
.page-card { padding: 12px !important; border-radius: 4px !important; }
.breadcrumb { font-size: 12px !important; margin-bottom: 8px !important; }
/* 工具栏: 横向滚动 */
.toolbar {
flex-wrap: nowrap !important;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
padding-bottom: 6px;
margin-bottom: 8px !important;
scrollbar-width: thin;
}
.toolbar::-webkit-scrollbar { height: 4px; }
.toolbar::-webkit-scrollbar-thumb { background: var(--brand-slate-200); border-radius: 2px; }
.toolbar :deep(.action-btn),
.toolbar :deep(.el-button) {
flex-shrink: 0;
font-size: 12px !important;
padding: 0 10px !important;
height: 30px !important;
}
/* filter-form: 横向 (label 左 + input 右) */
.filter-form {
display: flex !important;
flex-direction: column !important;
align-items: stretch !important;
gap: 10px !important;
}
.filter-form :deep(.el-form-item) {
display: flex !important;
align-items: center !important;
margin-right: 0 !important;
margin-bottom: 0 !important;
}
.filter-form :deep(.el-form-item__label) {
float: none !important;
width: auto !important;
min-width: 80px !important;
text-align: right !important;
padding: 0 8px 0 0 !important;
font-size: 13px !important;
color: var(--el-text-color-regular) !important;
line-height: 32px !important;
height: 32px !important;
}
.filter-form :deep(.el-form-item__content) {
margin-left: 0 !important;
line-height: 32px !important;
flex: 1 !important;
min-width: 0 !important;
}
/* 强制所有控件全宽 */
.filter-form :deep(.el-select),
.filter-form :deep(.el-input),
.filter-form :deep(.el-date-editor),
.filter-form :deep(.el-button),
.filter-form :deep(.el-cascader) {
width: 100% !important;
min-width: 0 !important;
margin-left: 0 !important;
margin-right: 0 !important;
display: block !important;
}
.filter-form :deep(.el-button + .el-button) {
margin-top: 8px !important;
}
/* 表格字号收紧 */
:deep(.el-table) { font-size: 12px !important; }
}
</style>