Some checks are pending
Check / lint (push) Waiting to run
Check / typecheck (push) Waiting to run
Check / build (build, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build, 18.x, windows-latest) (push) Waiting to run
Check / build (build:app, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:app, 18.x, windows-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Waiting to run
311 lines
7.5 KiB
Vue
311 lines
7.5 KiB
Vue
<script lang="ts" setup>
|
|
import { fileFormatSize } from '@/utils/strings'
|
|
import { computed } from 'vue'
|
|
import { download, getFileNameSuffix } from '@/utils/functions'
|
|
import { ITalkRecordExtraFile, ITalkRecord } from '@/types/chat'
|
|
import filePaperPDF from '@/static/image/chat/file-paper-pdf.png'
|
|
import filePaperPPT from '@/static/image/chat/file-paper-ppt.png'
|
|
import filePaperWord from '@/static/image/chat/file-paper-word.png'
|
|
import filePaperExcel from '@/static/image/chat/file-paper-excel.png'
|
|
import filePaperOther from '@/static/image/chat/file-paper-other.png'
|
|
import filePaperPDFBlank from '@/static/image/chat/file-paper-pdf-blank.png'
|
|
import filePaperPPTBlank from '@/static/image/chat/file-paper-ppt-blank.png'
|
|
import filePaperWordBlank from '@/static/image/chat/file-paper-word-blank.png'
|
|
import filePaperExcelBlank from '@/static/image/chat/file-paper-excel-blank.png'
|
|
import filePaperOtherBlank from '@/static/image/chat/file-paper-other-blank.png'
|
|
|
|
const props = defineProps<{
|
|
extra: ITalkRecordExtraFile
|
|
data: ITalkRecord
|
|
maxWidth?: Boolean
|
|
}>()
|
|
|
|
const getFileTypeIMG = computed(() => {
|
|
const suffix = props.extra.name.split('.').pop()?.toLowerCase() || ''
|
|
let objT = {
|
|
finishedImg: '',
|
|
blankImg: '',
|
|
progressColor: '',
|
|
}
|
|
|
|
switch (suffix) {
|
|
case 'pdf':
|
|
objT.finishedImg = filePaperPDF
|
|
objT.blankImg = filePaperPDFBlank
|
|
objT.progressColor = '#DE4E4E'
|
|
break
|
|
case 'doc':
|
|
case 'docx':
|
|
objT.finishedImg = filePaperWord
|
|
objT.blankImg = filePaperWordBlank
|
|
objT.progressColor = '#2750B2'
|
|
break
|
|
case 'xls':
|
|
case 'xlsx':
|
|
objT.finishedImg = filePaperExcel
|
|
objT.blankImg = filePaperExcelBlank
|
|
objT.progressColor = '#3C7F4B'
|
|
break
|
|
case 'ppt':
|
|
case 'pptx':
|
|
objT.finishedImg = filePaperPPT
|
|
objT.blankImg = filePaperPPTBlank
|
|
objT.progressColor = '#B74B2B'
|
|
break
|
|
default:
|
|
objT.finishedImg = filePaperOther
|
|
objT.blankImg = filePaperOtherBlank
|
|
objT.progressColor = '#46299d'
|
|
}
|
|
return objT
|
|
})
|
|
|
|
const previewPDF = () => {
|
|
if (typeof plus !== 'undefined') {
|
|
downloadAndOpenFile()
|
|
} else {
|
|
document.addEventListener('plusready', () => {
|
|
downloadAndOpenFile()
|
|
})
|
|
}
|
|
}
|
|
|
|
const downloadAndOpenFile = () => {
|
|
uni.showLoading({ title: '加载中...', mask: true })
|
|
const downloadUrl = props?.extra?.path
|
|
if (!downloadUrl) {
|
|
uni.hideLoading()
|
|
uni.showToast({ title: '文件路径无效', icon: 'none' })
|
|
return
|
|
}
|
|
const options = {
|
|
filename: '_doc/downloads/', // 保存路径
|
|
}
|
|
const dtask = plus.downloader.createDownload(downloadUrl, options, function (
|
|
d,
|
|
status,
|
|
) {
|
|
if (status === 200) {
|
|
uni.hideLoading()
|
|
const filePath = d.filename
|
|
if (filePath) {
|
|
plus.runtime.openFile(filePath, {}, function () {})
|
|
} else {
|
|
uni.showToast({ title: '文件路径无效', icon: 'none' })
|
|
}
|
|
} else {
|
|
uni.hideLoading()
|
|
}
|
|
})
|
|
dtask.start()
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<section
|
|
class="file-message"
|
|
@click="previewPDF"
|
|
:class="{ left: data.float === 'left', right: data.float === 'right' }"
|
|
>
|
|
<div class="flex justify-between">
|
|
<div
|
|
class="w-[228rpx] text-[32rpx] text-[#1A1A1A] h-[88rpx] leading-[44rpx] textEllipsis file_name"
|
|
>
|
|
{{ extra.name }}
|
|
</div>
|
|
<div
|
|
v-if="data.uploadStatus === 2 || !data.uploadStatus"
|
|
class="w-[95rpx]"
|
|
>
|
|
<tm-image
|
|
:width="95"
|
|
:height="95"
|
|
:src="getFileTypeIMG.finishedImg"
|
|
></tm-image>
|
|
</div>
|
|
<div
|
|
v-if="data.uploadStatus === 1 || data.uploadStatus === 3"
|
|
class="w-[95rpx]"
|
|
>
|
|
<tm-image
|
|
:width="95"
|
|
:height="95"
|
|
:src="getFileTypeIMG.blankImg"
|
|
></tm-image>
|
|
<wd-circle v-if="data.uploadStatus === 1"
|
|
customClass="circleProgress"
|
|
:modelValue="data.uploadCurrent"
|
|
layerColor="#E3E3E3"
|
|
:color="getFileTypeIMG.progressColor"
|
|
:strokeWidth="3"
|
|
:size="20"
|
|
></wd-circle>
|
|
<div class="upload-failed" v-if="data.uploadStatus === 3">
|
|
<tm-icon :font-size="20" name="tmicon-times" color="#fff"></tm-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="divider mt-[28rpx]"></div>
|
|
<div class="text-[24rpx] text-[#747474] mt-[10rpx]">
|
|
{{ fileFormatSize(extra.size) }}
|
|
</div>
|
|
<!-- <div class="main">
|
|
<div class="ext">{{ getFileNameSuffix(extra.name) }}</div>
|
|
<div class="file-box">
|
|
<p class="info">
|
|
<span class="name">{{ extra.name }}</span>
|
|
<span class="size">({{ fileFormatSize(extra.size) }})</span>
|
|
</p>
|
|
<p class="notice">文件已成功发送, 文件助手永久保存</p>
|
|
</div>
|
|
</div>
|
|
<div class="footer">
|
|
<a @click="download(data.msg_id)">下载</a>
|
|
<a>在线预览</a>
|
|
</div> -->
|
|
</section>
|
|
</template>
|
|
|
|
<style lang="less" scoped>
|
|
.file-message {
|
|
width: 486rpx;
|
|
min-height: 220rpx;
|
|
padding: 28rpx 30rpx 22rpx 30rpx;
|
|
border-radius: 10px;
|
|
background-color: #fff;
|
|
border-radius: 0;
|
|
|
|
&.left {
|
|
background-color: #fff;
|
|
border-radius: 0 16rpx 16rpx 16rpx;
|
|
}
|
|
|
|
&.right {
|
|
background-color: #fff;
|
|
border-radius: 16rpx 0 16rpx 16rpx;
|
|
}
|
|
|
|
.file_name {
|
|
word-break: break-all; /* 在任意字符间断行 */
|
|
word-wrap: break-word; /* 允许长单词换行到下一行 */
|
|
}
|
|
|
|
.main {
|
|
height: 45px;
|
|
display: flex;
|
|
flex-direction: row;
|
|
margin-top: 5px;
|
|
|
|
.ext {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
width: 45px;
|
|
height: 45px;
|
|
color: #ffffff;
|
|
background: #49a4ff;
|
|
border-radius: 5px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.file-box {
|
|
flex: 1 1;
|
|
height: 45px;
|
|
margin-left: 10px;
|
|
overflow: hidden;
|
|
|
|
.info {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
overflow: hidden;
|
|
height: 24px;
|
|
font-size: 14px;
|
|
|
|
.name {
|
|
flex: 1 auto;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.size {
|
|
font-size: 12px;
|
|
color: #cac6c6;
|
|
flex-shrink: 0;
|
|
}
|
|
}
|
|
|
|
.notice {
|
|
height: 25px;
|
|
line-height: 25px;
|
|
font-size: 12px;
|
|
color: #929191;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
}
|
|
}
|
|
|
|
.footer {
|
|
height: 30px;
|
|
line-height: 37px;
|
|
text-align: right;
|
|
font-size: 12px;
|
|
border-top: 1px solid var(--border-color);
|
|
margin-top: 10px;
|
|
|
|
a {
|
|
margin: 0 3px;
|
|
user-select: none;
|
|
cursor: pointer;
|
|
color: var(--im-text-color);
|
|
|
|
&:hover {
|
|
color: royalblue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.textEllipsis {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
|
|
.divider {
|
|
background-color: #e7e7e7;
|
|
height: 1rpx;
|
|
}
|
|
|
|
.circleProgress {
|
|
position: absolute;
|
|
top: 120rpx;
|
|
right: 52rpx;
|
|
transform: translate(-50%, -50%);
|
|
z-index: 1;
|
|
width: 40rpx !important;
|
|
height: 40rpx !important;
|
|
}
|
|
|
|
.upload-failed {
|
|
position: absolute;
|
|
top: 120rpx;
|
|
right: 52rpx;
|
|
transform: translate(-50%, -50%);
|
|
z-index: 1;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #ff4d4f;
|
|
background: #ff4d4f;
|
|
border-radius: 50%;
|
|
}
|
|
</style>
|