Files
guoju0808/ry-vue3/src/views/portal/SupportLetter.vue
T
郭庆泰 cf5790229a refactor: 合并 biz_support_unit/biz_execution_unit/biz_service_org 为 biz_org, 删除 2 张孤儿表, 改 biz_person.work_unit → org_id FK
主要改动:
- SQL: biz_support_unit → biz_org, 加 org_type, 加 business_nature; 删 biz_execution_unit, biz_service_org
- SQL: biz_project.support_unit_id/name + service_org_id/name → org_id/name/type
- SQL: biz_meeting.support_unit_name → org_name
- SQL: biz_person.work_unit → org_id (FK)
- 后端: 新 BizOrg entity/mapper/service/controller
- 后端: BizProject/BizMeeting 字段重命名
- 后端: 删 12 个 BizSupportUnit/BizExecutionUnit/BizServiceOrg Java 文件
- 后端: BizPersonImportVO.workUnit → orgName (导入时查 biz_org 取 org_id)
- 后端: BizAuthController.registerExecutor 完整实现 (原 registerSupplier stub)
- 前端: 新 admin/Orgs.vue + manager/Orgs.vue (原 SupportUnits)
- 前端: RegisterExecutor.vue (原 RegisterSupplier, 单页 2 步)
- 前端: sponsor/executor/manager 多个文件 workUnit → orgId/orgName 重命名
- 前端: 统一 supplier → executor, 业务命名 sponsor(赞助方) / executor(执行方=供应商)
- 前端: 全工程 execution → executor (company type / role / person unit_type)
2026-08-15 12:41:10 +08:00

106 lines
4.4 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">
<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 }">
<el-button link type="primary" @click="openDetail(row)">详情</el-button>
<el-button link type="primary" :disabled="!row.fileUrl" @click="openPreview(row)">预览</el-button>
</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: 10, 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() }
function fmt(t) { return t ? new Date(t).toLocaleString('zh-CN') : '' }
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; }
</style>