Commit 5f8ce1c2 by yuzhenWang

Merge branch 'wyz' into 'test'

优化2

See merge request !145
parents b60297ec 3a0841e3
<!-- filePreview -->
<template>
<el-dialog
v-model="dialogVisible"
:title="fileTitle"
width="90%"
:close-on-click-modal="false"
destroy-on-close
@close="handleClose"
>
<div class="preview-container">
<!-- 图片预览(增加 loading 和错误处理) -->
<div
v-if="fileType === 'image'"
class="preview-image-wrapper"
v-loading="imageLoading"
element-loading-text="图片加载中..."
>
<div v-if="imageError" class="image-error">
<el-icon :size="48"><Picture /></el-icon>
<p>图片加载失败</p>
<el-button size="small" type="primary" @click="retryImage">重试</el-button>
</div>
<img
v-else
:src="fileUrl"
:key="imageKey"
class="preview-image"
alt="预览图片"
@load="onImageLoad"
@error="onImageError"
/>
</div>
<!-- PDF 预览(滚动多页) -->
<div v-else-if="fileType === 'pdf'" class="pdf-viewer">
<div class="pdf-toolbar">
<el-button-group>
<el-button size="small" @click="zoomOut">
<el-icon><ZoomOut /></el-icon> 缩小
</el-button>
<el-button size="small" @click="zoomIn">
<el-icon><ZoomIn /></el-icon> 放大
</el-button>
</el-button-group>
<span class="page-info">{{ pdfTotalPages }}</span>
</div>
<div
class="pdf-scroll-wrapper"
v-loading="pdfLoading"
element-loading-text="正在渲染页面..."
>
<div ref="pdfScrollContainer" class="pdf-scroll-container"></div>
</div>
</div>
<!-- 不支持预览的文件类型 -->
<div v-else class="preview-unsupported">
<el-icon :size="48" color="#909399"><Document /></el-icon>
<p>暂不支持预览此类型文件</p>
<el-button type="primary" @click="dialogVisible = false">关闭</el-button>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { ref, computed, watch, nextTick, onBeforeUnmount, shallowRef } from 'vue'
import { ElMessage } from 'element-plus'
import { ZoomIn, ZoomOut, Document, Picture } from '@element-plus/icons-vue'
import * as PDFJS from 'pdfjs-dist'
// 配置 PDF.js worker
PDFJS.GlobalWorkerOptions.workerSrc = '/js/pdf.worker.min.mjs'
// ---------- 内部状态 ----------
const dialogVisible = ref(false) // 弹窗显示状态
const fileUrl = ref('') // 当前预览的文件 URL
const fileName = ref('') // 当前预览的文件名
// 图片预览相关状态
const imageLoading = ref(false) // 图片加载中
const imageError = ref(false) // 图片加载失败
const imageKey = ref(0) // 强制重新加载图片的 key
// PDF 相关
const pdfDoc = shallowRef(null) // pdf 文档实例
const pdfScrollContainer = ref(null) // 滚动容器
const pdfTotalPages = ref(0) // 总页数
const pdfScale = ref(1.2) // 缩放比例
const pdfLoading = ref(false) // 加载状态
let pdfLoadingCanceled = false // 取消标志
let isRendering = false // 防止重复渲染
// ---------- 辅助函数 ----------
// 根据文件名获取文件类型(image / pdf / unsupported)
const getFileType = name => {
if (!name) return 'unsupported'
const ext = name.split('.').pop().toLowerCase()
if (['jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp', 'svg'].includes(ext)) {
return 'image'
} else if (ext === 'pdf') {
return 'pdf'
}
return 'unsupported'
}
const fileType = computed(() => getFileType(fileName.value))
const fileTitle = computed(() => fileName.value || '文件预览')
// ---------- 图片预览事件处理 ----------
const onImageLoad = () => {
imageLoading.value = false
imageError.value = false
}
const onImageError = () => {
imageLoading.value = false
imageError.value = true
ElMessage.error('图片加载失败,请检查文件链接')
}
const retryImage = () => {
imageError.value = false
imageLoading.value = true
imageKey.value++ // 改变 key 强制重新加载图片
}
// ---------- 清理 PDF 资源 ----------
const clearPdf = async () => {
pdfLoadingCanceled = true // 取消任何进行中的渲染
pdfLoading.value = false
isRendering = false
if (pdfDoc.value) {
try {
await pdfDoc.value.destroy()
} catch (e) {
// 忽略销毁错误
}
pdfDoc.value = null
}
pdfTotalPages.value = 0
pdfScale.value = 1.2
if (pdfScrollContainer.value) {
pdfScrollContainer.value.innerHTML = ''
}
}
// ---------- 渲染 PDF 所有页面(滚动多页)----------
const renderAllPages = async scale => {
if (!pdfDoc.value || pdfLoadingCanceled || isRendering) return
isRendering = true
pdfLoading.value = true
const container = pdfScrollContainer.value
if (!container) {
isRendering = false
pdfLoading.value = false
return
}
// 清空之前的 canvas
container.innerHTML = ''
try {
const promises = []
for (let pageNum = 1; pageNum <= pdfTotalPages.value; pageNum++) {
if (pdfLoadingCanceled) break
const page = await pdfDoc.value.getPage(pageNum)
const viewport = page.getViewport({ scale })
// 创建 canvas 元素
const canvas = document.createElement('canvas')
canvas.className = 'pdf-page-canvas'
const context = canvas.getContext('2d')
canvas.height = viewport.height
canvas.width = viewport.width
canvas.style.marginBottom = '16px'
canvas.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)'
container.appendChild(canvas)
// 渲染当前页
const renderTask = page.render({
canvasContext: context,
viewport: viewport
})
promises.push(renderTask.promise)
}
await Promise.all(promises)
} catch (err) {
if (!pdfLoadingCanceled) {
console.error('渲染 PDF 失败', err)
ElMessage.error('渲染 PDF 页面失败')
}
} finally {
isRendering = false
pdfLoading.value = false
}
}
// 加载 PDF 文档
const loadPdf = async url => {
pdfLoadingCanceled = false
pdfLoading.value = true
try {
// 清理旧文档
if (pdfDoc.value) {
await pdfDoc.value.destroy().catch(() => {})
pdfDoc.value = null
}
if (pdfScrollContainer.value) {
pdfScrollContainer.value.innerHTML = ''
}
const loadingTask = PDFJS.getDocument(url)
pdfDoc.value = await loadingTask.promise
if (pdfLoadingCanceled) {
if (pdfDoc.value) pdfDoc.value.destroy()
pdfLoading.value = false
return
}
pdfTotalPages.value = pdfDoc.value.numPages
await renderAllPages(pdfScale.value)
pdfLoading.value = false
} catch (err) {
if (!pdfLoadingCanceled) {
console.error('PDF 加载失败', err)
ElMessage.error('PDF 文件加载失败,请检查文件链接')
dialogVisible.value = false
}
pdfLoading.value = false
}
}
// ---------- 缩放控制 ----------
const zoomIn = () => {
if (fileType.value !== 'pdf') return
pdfScale.value = Math.min(pdfScale.value + 0.2, 3.0)
renderAllPages(pdfScale.value)
}
const zoomOut = () => {
if (fileType.value !== 'pdf') return
pdfScale.value = Math.max(pdfScale.value - 0.2, 0.5)
renderAllPages(pdfScale.value)
}
// ---------- 关闭弹窗 ----------
const handleClose = async () => {
// 重置图片相关状态
imageLoading.value = false
imageError.value = false
await clearPdf()
dialogVisible.value = false
}
// ---------- 对外暴露的方法 ----------
/**
* 打开预览弹窗
* @param {Object} file - 文件对象,需包含 url 和 name 属性(或 originalName)
* @example
* open({ url: 'https://example.com/file.pdf', name: '文档.pdf' })
*/
const open = file => {
if (!file || !file.url) {
ElMessage.warning('无法预览:文件地址不存在')
return
}
// 重置状态
fileUrl.value = file.url
fileName.value = file.name || file.originalName || '文件'
// 根据文件类型重置对应的加载状态
const type = getFileType(fileName.value)
if (type === 'image') {
// 重置图片状态并强制重新加载
imageLoading.value = true
imageError.value = false
imageKey.value++ // 改变 key 确保重新加载图片
} else if (type === 'pdf') {
// PDF 相关状态重置已在 loadPdf 中处理
pdfLoadingCanceled = false
}
dialogVisible.value = true
// 根据文件类型处理
nextTick(() => {
if (fileType.value === 'pdf') {
loadPdf(fileUrl.value)
}
// 图片无需额外处理,通过 imageKey 变化自动重新加载
})
}
// 组件卸载时清理 PDF 资源
onBeforeUnmount(() => {
if (pdfDoc.value) {
pdfDoc.value.destroy().catch(() => {})
pdfDoc.value = null
}
pdfLoadingCanceled = true
})
defineExpose({ open })
</script>
<style lang="scss" scoped>
.preview-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 400px;
}
.preview-image-wrapper {
width: 100%;
position: relative;
min-height: 200px;
text-align: center;
}
.preview-image {
max-width: 100%;
max-height: 70vh;
object-fit: contain;
}
.image-error {
text-align: center;
padding: 40px;
color: #909399;
p {
margin: 16px 0;
}
}
.preview-unsupported {
text-align: center;
padding: 40px;
p {
margin: 16px 0;
color: #909399;
}
}
.pdf-viewer {
display: flex;
flex-direction: column;
height: 70vh;
}
.pdf-toolbar {
display: flex;
justify-content: center;
align-items: center;
gap: 16px;
padding: 8px 0;
border-bottom: 1px solid #e4e7ed;
margin-bottom: 12px;
.page-info {
font-size: 14px;
color: #606266;
}
}
.pdf-scroll-wrapper {
width: 100%;
flex: 1;
overflow-y: auto;
border: 1px solid #ebeef5;
border-radius: 4px;
background: #f9fafc;
}
.pdf-scroll-container {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px;
}
.pdf-page-canvas {
display: block;
max-width: 100%;
height: auto;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-bottom: 16px;
}
</style>
...@@ -62,7 +62,9 @@ ...@@ -62,7 +62,9 @@
</el-row> </el-row>
</div> </div>
<el-table <el-table
ref="multipleTableRef"
:data="tableData" :data="tableData"
row-key="fortuneBizId"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
height="400" height="400"
border border
...@@ -70,7 +72,7 @@ ...@@ -70,7 +72,7 @@
style="width: 100%" style="width: 100%"
v-loading="loading" v-loading="loading"
> >
<el-table-column type="selection" width="40" fixed="left" /> <el-table-column type="selection" width="40" fixed="left" :selectable="isSelectable" />
<el-table-column prop="payableNo" label="业务编号" width="150" fixed="left" /> <el-table-column prop="payableNo" label="业务编号" width="150" fixed="left" />
<el-table-column prop="status" label="出账状态" width="160" sortable> <el-table-column prop="status" label="出账状态" width="160" sortable>
<template #default="{ row }"> <template #default="{ row }">
...@@ -340,7 +342,7 @@ const installmentsBillFlag = ref(false) ...@@ -340,7 +342,7 @@ const installmentsBillFlag = ref(false)
const settingBillYearMonthFlag = ref(false) const settingBillYearMonthFlag = ref(false)
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const { csf_fortune_status, sys_no_yes } = proxy.useDict('csf_fortune_status', 'sys_no_yes') const { csf_fortune_status, sys_no_yes } = proxy.useDict('csf_fortune_status', 'sys_no_yes')
const multipleTableRef = ref(null)
const userStore = useUserStore() const userStore = useUserStore()
// 分页相关 // 分页相关
const currentPage = ref(1) const currentPage = ref(1)
...@@ -671,6 +673,11 @@ const fortuneBizTypeOptions = [ ...@@ -671,6 +673,11 @@ const fortuneBizTypeOptions = [
{ value: 'R', label: '关联保单应付单' }, { value: 'R', label: '关联保单应付单' },
{ value: 'U', label: '非关联保单应付单' } { value: 'U', label: '非关联保单应付单' }
] ]
// 可选性校验
const isSelectable = row => {
// status 为 6 的行禁止勾选
return row.status !== '6'
}
const confirmRateExchange = async () => { const confirmRateExchange = async () => {
let formData = await rateExchangeFormRef.value.validate() let formData = await rateExchangeFormRef.value.validate()
formData.fortuneBizId = selectedRow.value.fortuneBizId formData.fortuneBizId = selectedRow.value.fortuneBizId
...@@ -1011,7 +1018,8 @@ const addSpiltRecord = () => { ...@@ -1011,7 +1018,8 @@ const addSpiltRecord = () => {
payoutCurrency: 'HKD', payoutCurrency: 'HKD',
ruleCurrency: selectedRow.value.ruleCurrency, ruleCurrency: selectedRow.value.ruleCurrency,
originalCurrency: selectedRow.value.originalCurrency, originalCurrency: selectedRow.value.originalCurrency,
hkdToPayoutRate: '1' hkdToPayoutRate: '1',
exchangeRate: selectedRow.value.exchangeRate
} }
if (selectedRow.value.originalCurrency && selectedRow.value.originalCurrency == 'HKD') { if (selectedRow.value.originalCurrency && selectedRow.value.originalCurrency == 'HKD') {
newRow.originalToHkdRate = '1' newRow.originalToHkdRate = '1'
...@@ -1445,7 +1453,6 @@ const updatePayoutAmountapi = async data => { ...@@ -1445,7 +1453,6 @@ const updatePayoutAmountapi = async data => {
const updatePayRollStatusDisable = ref(true) const updatePayRollStatusDisable = ref(true)
const multipleSelection = ref([]) const multipleSelection = ref([])
const handleSelectionChange = val => { const handleSelectionChange = val => {
multipleSelection.value = val multipleSelection.value = val
console.log('全选:', val) console.log('全选:', val)
// 完成检核按钮是否禁用 // 完成检核按钮是否禁用
...@@ -1462,7 +1469,7 @@ const submitSettingBillYearMonth = async () => { ...@@ -1462,7 +1469,7 @@ const submitSettingBillYearMonth = async () => {
if (res.code === 200) { if (res.code === 200) {
settingBillYearMonthFlag.value = false settingBillYearMonthFlag.value = false
ElMessage.success('完成检核,等待关账') ElMessage.success('完成检核,等待关账')
const params = searchFormRef.value.getFormData() const params = await searchFormRef.value.getFormData()
loadTableData(params) loadTableData(params)
} }
} catch (error) { } catch (error) {
...@@ -1479,7 +1486,8 @@ const submitSettingBillYearMonth = async () => { ...@@ -1479,7 +1486,8 @@ const submitSettingBillYearMonth = async () => {
const singleRes = await actualPayoutDateApi(params) const singleRes = await actualPayoutDateApi(params)
ElMessage.success('设置出账年月成功') ElMessage.success('设置出账年月成功')
settingBillYearMonthFlag.value = false settingBillYearMonthFlag.value = false
loadTableData() const searchParams = await searchFormRef.value.getFormData()
loadTableData(searchParams)
} catch (error) { } catch (error) {
ElMessage.error('设置出账年月失败') ElMessage.error('设置出账年月失败')
settingBillYearMonthFlag.value = true settingBillYearMonthFlag.value = true
...@@ -1522,6 +1530,17 @@ const onSubmit = data => { ...@@ -1522,6 +1530,17 @@ const onSubmit = data => {
} }
onMounted(async () => {}) onMounted(async () => {})
// 数据变化时清空选中
watch(
() => tableData,
() => {
nextTick(() => {
multipleTableRef.value?.clearSelection()
multipleSelection.value = []
})
},
{ deep: true }
)
</script> </script>
<style scoped> <style scoped>
......
...@@ -173,7 +173,7 @@ ...@@ -173,7 +173,7 @@
<el-table-column prop="policyHolderEn" label="投保人(英文)" width="120" /> <el-table-column prop="policyHolderEn" label="投保人(英文)" width="120" />
<el-table-column prop="broker" label="转介人" width="120" /> <el-table-column prop="broker" label="转介人" width="120" />
<el-table-column prop="insuranceCompany" label="保险公司" width="120" /> <el-table-column prop="insuranceCompany" label="保险公司" width="120" />
<el-table-column prop="remark" label="备注" width="120" sortable /> <el-table-column prop="manualRemark" label="备注" width="120" sortable />
<el-table-column prop="isDeleted" label="记录状态" width="120" sortable> <el-table-column prop="isDeleted" label="记录状态" width="120" sortable>
<template #default="{ row }"> <template #default="{ row }">
{{ row.isDeleted === 1 ? '无效' : '有效' }} {{ row.isDeleted === 1 ? '无效' : '有效' }}
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
/> --> /> -->
<el-table-column <el-table-column
prop="fortuneAccountMonth" prop="fortuneAccountMonth"
label="出账月" label="出账月"
min-width="150" min-width="150"
show-overflow-tooltip show-overflow-tooltip
/> />
...@@ -442,8 +442,8 @@ const debounceChangeRateMap = new WeakMap() ...@@ -442,8 +442,8 @@ const debounceChangeRateMap = new WeakMap()
const debounceChangeToAmountMap = new WeakMap() const debounceChangeToAmountMap = new WeakMap()
// 表格操作菜单 // 表格操作菜单
const dropdownItems = [ const dropdownItems = [
{ label: '拆分出账', value: 'splitBilling' }, { label: '拆分出账', value: 'splitBilling' }
{ label: '设置出账日', value: 'settingSalaryDate' } // { label: '设置出账日', value: 'settingSalaryDate' }
// { label: '查看记录', value: 'viewRecord' } // { label: '查看记录', value: 'viewRecord' }
] ]
//=============拆分出账开始================ //=============拆分出账开始================
...@@ -816,7 +816,7 @@ const getList = async (searchParams = {}) => { ...@@ -816,7 +816,7 @@ const getList = async (searchParams = {}) => {
payoutDate: undefined, payoutDate: undefined,
pageNo: currentPage.value, pageNo: currentPage.value,
pageSize: pageSize.value, pageSize: pageSize.value,
statusList:searchParams.statusList || ['6'] statusList: searchParams.statusList || ['6']
} }
const response = await getReferrerFortuneList(params) const response = await getReferrerFortuneList(params)
......
...@@ -413,13 +413,13 @@ const payableReportListTableColumns = ref([ ...@@ -413,13 +413,13 @@ const payableReportListTableColumns = ref([
width: '130', width: '130',
formatter: row => row.payableNo || '-' formatter: row => row.payableNo || '-'
}, },
{ // {
prop: 'policyNo', // prop: 'policyNo',
label: '关联业务编号', // label: '关联业务编号',
sortable: true, // sortable: true,
width: '130', // width: '130',
formatter: row => row.policyNo || '-' // formatter: row => row.policyNo || '-'
}, // },
{ {
prop: 'policyNo', prop: 'policyNo',
label: '保单号', label: '保单号',
......
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
</el-table> </el-table>
</template> </template>
</CommonPage> </CommonPage>
<!-- 应收明细 -->
<CommonDialog <CommonDialog
dialogTitle="应收明细" dialogTitle="应收明细"
dialogWidth="80%" dialogWidth="80%"
...@@ -901,6 +901,7 @@ const handleSelect = async (e, row) => { ...@@ -901,6 +901,7 @@ const handleSelect = async (e, row) => {
// 3. 此时 addRecordRef.value 一定存在了 // 3. 此时 addRecordRef.value 一定存在了
if (addRecordRef.value && selectedRow.value) { if (addRecordRef.value && selectedRow.value) {
addReceivablesFormModel.value = { ...selectedRow.value } addReceivablesFormModel.value = { ...selectedRow.value }
addReceivablesFormModel.value.commissionDate = selectedRow.value.commissionDateMonth
console.log('赋值成功:', addReceivablesFormModel.value) console.log('赋值成功:', addReceivablesFormModel.value)
} }
}) })
......
<!-- 预约附件代码 -->
<template> <template>
<div class="uploadContainer"> <div class="uploadContainer">
<CardOne title="材料信息"> <CardOne title="材料信息">
...@@ -129,7 +130,7 @@ ...@@ -129,7 +130,7 @@
:key="file.fileBizId" :key="file.fileBizId"
class="uploaded-file-item" class="uploaded-file-item"
> >
<div class="fileName">{{ file.originalName }}</div> <div class="fileNameBox">{{ file.originalName }}</div>
<div> <div>
<el-button type="primary" size="small" link @click="previewFile(file)"> <el-button type="primary" size="small" link @click="previewFile(file)">
查看 查看
...@@ -148,37 +149,9 @@ ...@@ -148,37 +149,9 @@
</div> </div>
</CommonDialog> </CommonDialog>
<!-- 文件预览弹窗(页面内查看,不打开新窗口) -->
<!-- <el-dialog
v-model="previewDialogVisible"
:title="previewFileName"
width="70%"
:close-on-click-modal="false"
destroy-on-close
@close="previewUrl = ''"
>
<div class="preview-container">
<div v-if="previewFileType === 'image'" class="preview-image-wrapper">
<img :src="previewUrl" class="preview-image" alt="预览图片" />
</div>
<iframe
v-else-if="previewFileType === 'pdf'"
:src="previewUrl"
class="preview-pdf"
frameborder="0"
></iframe>
<div v-else-if="previewFileType === 'unsupported'" class="preview-unsupported">
<el-icon :size="48" color="#909399"><Document /></el-icon>
<p>暂不支持预览此类型文件</p>
<el-button type="primary" @click="previewDialogVisible = false"> 关闭 </el-button>
</div>
</div>
</el-dialog> -->
<!-- 文件预览弹窗 --> <!-- 文件预览弹窗 -->
<el-dialog <FilePreview ref="filePreviewRef" />
<!-- <el-dialog
v-model="previewDialogVisible" v-model="previewDialogVisible"
:title="previewFileName" :title="previewFileName"
width="90%" width="90%"
...@@ -187,14 +160,14 @@ ...@@ -187,14 +160,14 @@
@close="closePreview" @close="closePreview"
> >
<div class="preview-container"> <div class="preview-container">
<!-- 图片预览 -->
<div v-if="previewFileType === 'image'" class="preview-image-wrapper"> <div v-if="previewFileType === 'image'" class="preview-image-wrapper">
<img :src="previewUrl" class="preview-image" alt="预览图片" /> <img :src="previewUrl" class="preview-image" alt="预览图片" />
</div> </div>
<!-- PDF 预览区域(滚动多页) -->
<div v-else-if="previewFileType === 'pdf'" class="pdf-viewer"> <div v-else-if="previewFileType === 'pdf'" class="pdf-viewer">
<div class="pdf-toolbar"> <div class="pdf-toolbar">
<!-- 只保留缩放按钮 -->
<el-button-group> <el-button-group>
<el-button size="small" @click="zoomOut"> <el-button size="small" @click="zoomOut">
<el-icon><ZoomOut /></el-icon> 缩小 <el-icon><ZoomOut /></el-icon> 缩小
...@@ -213,14 +186,14 @@ ...@@ -213,14 +186,14 @@
<div ref="pdfScrollContainer" class="pdf-scroll-container"></div> <div ref="pdfScrollContainer" class="pdf-scroll-container"></div>
</div> </div>
</div> </div>
<!-- 不支持预览的文件类型 -->
<div v-else-if="previewFileType === 'unsupported'" class="preview-unsupported"> <div v-else-if="previewFileType === 'unsupported'" class="preview-unsupported">
<el-icon :size="48" color="#909399"><Document /></el-icon> <el-icon :size="48" color="#909399"><Document /></el-icon>
<p>暂不支持预览此类型文件</p> <p>暂不支持预览此类型文件</p>
<el-button type="primary" @click="previewDialogVisible = false"> 关闭 </el-button> <el-button type="primary" @click="previewDialogVisible = false"> 关闭 </el-button>
</div> </div>
</div> </div>
</el-dialog> </el-dialog> -->
<el-dialog v-model="imageViewerVisible" title="图片预览" width="60%"> <el-dialog v-model="imageViewerVisible" title="图片预览" width="60%">
<div style="text-align: center"> <div style="text-align: center">
<el-image :src="imageUrl" fit="contain" /> <el-image :src="imageUrl" fit="contain" />
...@@ -234,6 +207,7 @@ import { ref, nextTick, shallowRef } from 'vue' ...@@ -234,6 +207,7 @@ import { ref, nextTick, shallowRef } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { downloadFilesAsZip } from '@/utils/zipDownload' // 引入刚才封装的工具 import { downloadFilesAsZip } from '@/utils/zipDownload' // 引入刚才封装的工具
import CommonDialog from '@/components/commonDialog' import CommonDialog from '@/components/commonDialog'
import FilePreview from '@/components/Preview/filePreview.vue'
import CardOne from '@/components/formCard/cardOne' import CardOne from '@/components/formCard/cardOne'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { addFile, getAppointmentFile, delFile, editAppointmentFile } from '@/api/sign/appointment' import { addFile, getAppointmentFile, delFile, editAppointmentFile } from '@/api/sign/appointment'
...@@ -258,6 +232,7 @@ const props = defineProps({ ...@@ -258,6 +232,7 @@ const props = defineProps({
idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象 idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象
pageSource: { type: String, default: '' } //页面来源 pageSource: { type: String, default: '' } //页面来源
}) })
const filePreviewRef = ref(null)
// 在定义其他响应式变量的附近添加 // 在定义其他响应式变量的附近添加
const pdfLoading = ref(false) // PDF 加载状态 const pdfLoading = ref(false) // PDF 加载状态
const acceptUploadType = ref('.pdf,.jpg,.jpeg,.png,.bmp,.gif,.svg') const acceptUploadType = ref('.pdf,.jpg,.jpeg,.png,.bmp,.gif,.svg')
...@@ -397,34 +372,42 @@ const renderAllPages = async scale => { ...@@ -397,34 +372,42 @@ const renderAllPages = async scale => {
} }
// 修改 previewFile 中的 PDF 分支 // 修改 previewFile 中的 PDF 分支
function previewFile(file) { // function previewFile(file) {
console.log('====================================') // console.log('====================================')
console.log('file', file) // console.log('file', file)
console.log('====================================') // console.log('====================================')
const url = file.url || file.fileUrl // const url = file.url || file.fileUrl
if (!url) { // if (!url) {
ElMessage.warning('文件地址不存在') // ElMessage.warning('文件地址不存在')
return // return
} // }
const ext = (file.originalName || '').split('.').pop().toLowerCase() // const ext = (file.originalName || '').split('.').pop().toLowerCase()
previewUrl.value = url // previewUrl.value = url
previewFileName.value = file.originalName || '文件' // previewFileName.value = file.originalName || '文件'
if (['jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp', 'svg'].includes(ext)) { // if (['jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp', 'svg'].includes(ext)) {
previewFileType.value = 'image' // previewFileType.value = 'image'
previewDialogVisible.value = true // previewDialogVisible.value = true
} else if (ext === 'pdf') { // } else if (ext === 'pdf') {
previewFileType.value = 'pdf' // previewFileType.value = 'pdf'
previewDialogVisible.value = true // previewDialogVisible.value = true
// 先清理旧的资源 // // 先清理旧的资源
closePreview() // closePreview()
nextTick(() => { // nextTick(() => {
loadPdf(previewUrl.value) // loadPdf(previewUrl.value)
// })
// } else {
// previewFileType.value = 'unsupported'
// previewDialogVisible.value = true
// }
// }
// 在需要预览文件的地方调用(例如原来的 previewFile 函数)
function previewFile(file) {
// 确保传入对象包含 url 和 name 属性
filePreviewRef.value?.open({
url: file.url || file.fileUrl,
name: file.originalName || file.name
}) })
} else {
previewFileType.value = 'unsupported'
previewDialogVisible.value = true
}
} }
const closePreview = () => { const closePreview = () => {
pdfLoadingCanceled = true // 取消任何进行中的渲染 pdfLoadingCanceled = true // 取消任何进行中的渲染
...@@ -875,6 +858,13 @@ defineExpose({ ...@@ -875,6 +858,13 @@ defineExpose({
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.fileNameBox {
width: 70%;
/* 核心三件套: 强制单行 + 溢出隐藏 + 省略号 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.pdf-viewer { .pdf-viewer {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment