Files
guoju0808/ry-vue3/src/components/Preview.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

72 lines
2.6 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>
<el-dialog v-model="open" :title="title" width="780" top="6vh" :close-on-click-modal="false" destroy-on-close>
<div v-if="fileUrl" class="preview-box">
<!-- 图片 -->
<img v-if="kind === 'image'" :src="fileUrl" class="preview-img" :alt="title" />
<!-- PDFiframe 预览浏览器内置 viewer -->
<iframe v-else-if="kind === 'pdf'" :src="fileUrl" class="preview-iframe" />
<!-- 其它doc/xls/zip ):给下载链接 -->
<div v-else class="preview-fallback">
<el-icon class="fallback-icon"><Document /></el-icon>
<p>该文件类型暂不支持页内预览,请点击下方按钮下载/在新窗口打开查看</p>
<el-button type="primary" @click="openNew">在新窗口打开</el-button>
<el-button @click="copyUrl">复制链接</el-button>
</div>
</div>
<el-empty v-else description="暂无附件" />
<template #footer>
<el-button @click="open = false">关闭</el-button>
<el-button v-if="fileUrl" type="primary" @click="openNew">在新窗口打开</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import { Document } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
const props = defineProps({
modelValue: Boolean,
url: { type: String, default: '' },
title: { type: String, default: '附件预览' }
})
const emit = defineEmits(['update:modelValue'])
const open = computed({
get: () => props.modelValue,
set: v => emit('update:modelValue', v)
})
const fileUrl = computed(() => props.url || '')
const kind = computed(() => {
const u = fileUrl.value.split('?')[0].toLowerCase()
if (/\.(png|jpe?g|gif|webp|bmp|svg)(\?.*)?$/.test(u)) return 'image'
if (/\.pdf(\?.*)?$/.test(u)) return 'pdf'
return 'other'
})
function openNew() {
if (!fileUrl.value) return
window.open(fileUrl.value, '_blank', 'noopener')
}
async function copyUrl() {
if (!fileUrl.value) return
try {
await navigator.clipboard.writeText(fileUrl.value)
ElMessage.success('链接已复制')
} catch {
ElMessage.error('复制失败,请手动复制')
}
}
</script>
<style scoped>
.preview-box { display: flex; justify-content: center; align-items: flex-start; min-height: 480px; }
.preview-img { max-width: 100%; max-height: 70vh; object-fit: contain; }
.preview-iframe { width: 100%; height: 70vh; border: 1px solid #ebeef5; border-radius: 4px; }
.preview-fallback { text-align: center; padding: 48px 24px; color: #606266; }
.fallback-icon { font-size: 48px; color: #909399; margin-bottom: 12px; }
.preview-fallback p { margin: 12px 0 24px; }
</style>