图片预览
javascript
复制代码
<template>
<el-image class="avatar" :src="baseurl + img" :fit="fit" :style="'width: ' + wid + ';height: ' + hei">
<template #error>
<div class="image-slot">
<span class="iconfont icon-tupian" :style="'font-size: ' + siz + ';color:' + col"></span>
</div>
</template>
</el-image>
</template>
<script setup>
import { ref, defineProps } from "vue";
const props = defineProps({
img: { type: String, required: true, default: '' },
fit: { type: String, required: false, default: 'contain' }, // '' | 'fill 拉伸' | 'contain 等比例缩放完整留白' | 'cover 等比例缩放超出裁剪' | 'none 原始尺寸' | 'scale-down 取尺寸较小的显示方式'
wid: { type: String, required: false, default: '100%' },
hei: { type: String, required: false, default: '100%' },
col: { type: String, required: false, default: '' },
siz: { type: String, required: false, default: '3em' },
})
const baseurl = ref(process.env.VUE_APP_BASE_API)
</script>
附件预览
javascript
复制代码
<template>
<div>
<el-dialog class="wp80 hp80" :model-value="openDetail" :close-on-click-modal="false" :show-close="false" destroy-on-close>
<template #header>
<div class="header-left">
<el-icon class="header-icon">
<Document />
</el-icon>
<span class="header-title">查看附件</span>
</div>
<div class="header-right">
<el-button type="info" text @click="closeWindow('openDetail', emits, false)">
<el-icon>
<Close />
</el-icon>
</el-button>
</div>
</template>
<div class="video">
<div class="flexBox-common" style="align-items: flex-start;">
<div class="flexBox-common zywjBox" style="flex: 1 1 0%;" v-loading="loading" element-loading-background="rgba(122, 122, 122, 0.8)">
<embed v-if="dqwj.wjlx==='pdf'" class="teaplan_iframe" :src="baseurl + dqwj.fj" style="position:absolute; left: 0; top: 0;" width="100%" height="100%" type="application/pdf" />
<video v-else-if="dqwj.wjlx==='mp4'" controls="" autoplay="" name="media" style="width:100%;height:100%;"><source :src="baseurl + dqwj.fj" type="video/mp4"></video>
<video v-else-if="dqwj.wjlx==='3gp'" controls="" autoplay="" name="media" style="width:100%;height:100%;"><source :src="baseurl + dqwj.fj" type="video/3gpp"></video>
<img v-else-if="dqwj.wjlx==='gif' || dqwj.wjlx==='jpg' || dqwj.wjlx==='jpeg' || dqwj.wjlx==='png' || dqwj.wjlx==='svg'" :src="baseurl + dqwj.fj" style="width: 100%;height: 100%;object-fit: contain;display: block;-webkit-user-select: none;margin: auto;background-color: hsl(0, 0%, 90%);" :onload="officeJiaZai" />
<iframe v-else-if="dqwj.wjlx==='txt'" :src="baseurl + dqwj.fj" width='100%' height='100%' frameborder='1' ></iframe>
<vue-office-docx v-else-if="dqwj.wjlx==='docx'" :src="baseurl + dqwj.fj" style="width: 100%;height: 100%;" @rendered="officeJiaZai" />
<vue-office-excel v-else-if="dqwj.wjlx==='xlsx'" :src="baseurl + dqwj.fj" style="width: 100%;height: 100%;" @rendered="officeJiaZai" />
<div v-else style="width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;">当前文件不可预览</div>
</div>
<div v-if="listFj" class="zyListBox tree-overflow-x">
<div class="el-scrollbar" style="height: 100%;">
<div class="el-scrollbar__wrap">
<div class="el-scrollbar__view">
<div class="zyFileItem " :class="curFile===index?'curFile':''" v-for="(item, index) in listFj" :key="index" @click="wjClick(item, index)"><span class="fileOrder">文件{{ index+1 }}</span><span>{{ item.ymc }}</span></div>
</div>
</div>
<div class="el-scrollbar__bar is-horizontal">
<div class="el-scrollbar__thumb" style="transform: translateX(0%);"></div>
</div>
<div class="el-scrollbar__bar is-vertical">
<div class="el-scrollbar__thumb" style="transform: translateY(0%);"></div>
</div>
</div>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { defineEmits, ref, defineProps, watch } from 'vue'
import { closeWindow } from '@/api/common.js'
import VueOfficeDocx from '@vue-office/docx'
import '@vue-office/docx/lib/index.css'
import VueOfficeExcel from '@vue-office/excel'
import '@vue-office/excel/lib/index.css'
const props = defineProps({
openDetail: { type: Boolean, required: true },
row: { type: Object, required: false }
})
const emits = defineEmits(['update:openDetail'])
const listFj = ref([])
const dqwj = ref('')
// 文件点击
const baseurl = ref() // 根路径
const curFile = ref(0)
const loading = ref(false)
const wjClick = (item, index) => {
dqwj.value = { wjlx: '', fj: '' }
loading.value = false
if (item.wjlx === 'docx' || item.wjlx === 'xlsx') {
loading.value = true
}
curFile.value = index
dqwj.value = item
}
const officeJiaZai = () => {
loading.value = false
}
watch(
() => props.openDetail,
() => {
if (props.openDetail) {
baseurl.value = process.env.VUE_APP_BASE_API
listFj.value = props.row.listFj || []
if (listFj.value.length) {
listFj.value.forEach((element) => {
element.wjlx = element.fj.substring(element.fj.lastIndexOf('.') + 1)
element.ymc = element.fj.substr(element.fj.lastIndexOf('/') + 1)
})
dqwj.value = props.row.listFj[0]
}
}
},
{ deep: true, immediate: true }
)
</script>
<style lang="less" scoped>
.video {
width: 100%;
height: 100%;
border: 1px solid #ccc;
.flexBox-common {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
height: 100%;
.zywjBox {
height: 100% ;
width: calc(100% - 240px);
// background: #404040;
.teaplan_iframe {
height: 100%;
width: 100%;
}
}
.zyListBox {
width: 240px;
background: #f7f7f7;
height: 100%;
margin-left: 10px;
padding: 0 10px;
.tree-overflow-x .el-scrollbar__wrap {
overflow-x: hidden !important;
padding-right: 10px;
}
.curFile {
color: #1890ff;
font-weight: bold;
}
.zyFileItem {
word-wrap: break-word;
word-break: break-all;
line-height: 25px;
border-bottom: 1px solid #eee;
padding: 10px 0;
font-size: 15px;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
.fileOrder {
font-weight: bold;
margin-right: 10px;
}
}
}
}
}
</style>
富文本预览
javascript
复制代码
<template>
<div v-dompurify-html="msg" @click="handleClick"></div>
</template>
<script setup>
import { ref, defineProps, watch } from 'vue'
import { downloadImage } from '@/utils/requestDownload'
const props = defineProps({
msg: { type: String, required: true }
})
const handleClick = (event) => {
const clickedElement = event.target
// 检查点击的元素是否为你想处理的标签
if (clickedElement.className.toLowerCase() === 'fujian') {
// 处理按钮点击事件
const url = clickedElement.getAttribute('title')
const title = url.substr(url.lastIndexOf('/') + 1)
downloadImage(url, title)
}
}
</script>
<style lang="less" scoped>
img {
width: 100%;
}
</style>
分页
javascript
复制代码
<template>
<div class="paging">
<el-pagination
v-model:currentPage="currentPage"
v-model:page-size="pageSize"
:page-sizes="pageSizes"
:pager-count="pagerCount"
:background="background"
:layout="layout"
:total="totals"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
</el-pagination>
<el-link class="ml10" :underline="false" @click="shuaXinClick"><el-icon><RefreshRight /></el-icon></el-link>
</div>
</template>
<script setup>
import { ref, watch, defineEmits, defineProps } from 'vue'
const props = defineProps({
pagination: {
type: Object,
required: false
}
})
const emits = defineEmits(['ReturnData'])
const background = ref(true) // 按钮背景
const currentPage = ref(1) // 当前页
const pageSize = ref(100) // 每页显示条数
const pageSizes = ref([100, 200, 300, 400, 500]) // 每页显示个数选择器
const totals = ref(0) // 总条数
const pagerCount = ref(7) // 最大页码按钮数 数值范围:5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21
const layout = ref('sizes, prev, pager, next, jumper, total') // 组件布局: 每页显示 | 上一页 | 页码 | 下一页 | 跳页 | 总条数
// 每页条数
const handleSizeChange = (val) => {
emits('ReturnData', currentPage.value, val)
}
// 当前页
const handleCurrentChange = (val) => {
emits('ReturnData', val, pageSize.value)
}
// 刷新
const shuaXinClick = () => {
emits('ReturnData')
}
watch(() => props.pagination, () => {
if (props.pagination) {
background.value = props.pagination.background !== false // 按钮背景
currentPage.value = props.pagination.pageNo || 1 // 当前页
pageSize.value = props.pagination.pageSize || 100 // 每页显示条数
pageSizes.value = props.pagination.pageSizes || [100, 200, 300, 400, 500] // 每页显示个数选择器
totals.value = parseInt(props.pagination.total) || 0 // 总条数
pagerCount.value = props.pagination.pagerCount || 7 // 最大页码按钮数
layout.value = props.pagination.layout || 'sizes, prev, pager, next, jumper, total' // 组件布局
}
}, { deep: true, immediate: true })
</script>
<style lang="less" scoped>
.el-pagination {
padding-left: 0;
}
</style>