227 lines
5.2 KiB
Plaintext
227 lines
5.2 KiB
Plaintext
<template>
|
|
<scroll-view
|
|
class="files-container"
|
|
direction="horizontal"
|
|
:scroll-with-animation="true"
|
|
:show-scrollbar="false"
|
|
>
|
|
<template v-for="file in files" :key="file.uid">
|
|
<!-- 如果文件是图片,则显示图片,否则显示文档默认图片 -->
|
|
<view
|
|
class="files-box relative"
|
|
:class="[
|
|
!file?.type?.includes('image/')
|
|
? 'files-box-file'
|
|
: 'files-box-image',
|
|
file.status === UploadFileStatus.error ? 'files-box-error' : '',
|
|
]"
|
|
@click="onPreview(file)"
|
|
>
|
|
<view
|
|
class="files-box-loading"
|
|
v-if="file.status === UploadFileStatus.uploading"
|
|
>
|
|
<image
|
|
class="icon-loading-image"
|
|
src="@/static/assets/image_loading.svg"
|
|
alt=""
|
|
/>
|
|
</view>
|
|
<!-- 图片 -->
|
|
<image
|
|
class="image"
|
|
v-if="file?.type?.includes('image/')"
|
|
:src="file?.url"
|
|
mode="aspectFill"
|
|
:alt="file?.name || t('Mobile.Chat.uploadImageAlt')"
|
|
/>
|
|
<!-- 文件 -->
|
|
<template v-else>
|
|
<image
|
|
class="doc-image"
|
|
:src="docImage"
|
|
mode="aspectFill"
|
|
:alt="t('Mobile.Chat.uploadFileAlt')"
|
|
/>
|
|
<view class="doc-info-container">
|
|
<view class="doc-name text-ellipsis">{{ file?.name }}</view>
|
|
<text class="doc-size text-ellipsis">{{
|
|
formatBytes(file?.size)
|
|
}}</text>
|
|
</view>
|
|
</template>
|
|
<!-- 删除按钮 -->
|
|
<view
|
|
v-if="file.status !== UploadFileStatus.uploading"
|
|
class="del-container"
|
|
@click.stop="emit('onDel', file.uid)"
|
|
>
|
|
<image
|
|
src="@/static/assets/x-circle-fill.svg"
|
|
mode="aspectFit"
|
|
style="width: 40rpx; height: 40rpx"
|
|
:alt="t('Mobile.Common.deleteIconAlt')"
|
|
/>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
<!-- 添加按钮 -->
|
|
<view
|
|
class="files-box files-box-plus"
|
|
@click="emit('onAdd')"
|
|
v-if="props.showAddButton"
|
|
>
|
|
<text class="iconfont icon-Plus" />
|
|
</view>
|
|
</scroll-view>
|
|
</template>
|
|
|
|
<script lang="uts" setup>
|
|
import { UploadFileInfo } from "@/types/interfaces/common.uts";
|
|
import docImage from "@/static/assets/doc_image.png";
|
|
import { formatBytes } from "@/utils/byteConverter.uts";
|
|
import { UploadFileStatus } from "@/types/enums/common.uts";
|
|
import { useI18n } from "@/utils/i18n";
|
|
|
|
const props = defineProps<{
|
|
files: UploadFileInfo[];
|
|
showAddButton?: boolean;
|
|
}>();
|
|
|
|
const previewImages = computed(() => {
|
|
return (
|
|
props.files
|
|
?.filter((f) => f.type.includes("image/"))
|
|
?.map((file) => file.url) || []
|
|
);
|
|
});
|
|
|
|
const emit = defineEmits<{
|
|
onAdd: () => void;
|
|
onDel: (uid: string) => void;
|
|
}>();
|
|
const { t } = useI18n();
|
|
|
|
// 预览图片
|
|
const onPreview = (file: UploadFileInfo) => {
|
|
if (!file.type.includes("image/")) {
|
|
uni.showToast({
|
|
title: t("Mobile.Chat.previewTypeUnsupported"),
|
|
icon: "none",
|
|
duration: 1500,
|
|
});
|
|
return;
|
|
}
|
|
const urls = previewImages.value;
|
|
uni.previewImage({
|
|
urls,
|
|
current: file.url || "",
|
|
});
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.files-container {
|
|
display: flex;
|
|
flex-direction: row;
|
|
// padding: 0 32rpx;
|
|
|
|
.files-box {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 16rpx;
|
|
margin-right: 10rpx;
|
|
overflow: hidden;
|
|
border: 2rpx solid transparent;
|
|
|
|
&-loading {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 10;
|
|
display: flex;
|
|
justify-content: center;
|
|
background: rgba(64, 62, 62, 0.15);
|
|
|
|
.icon-loading-image {
|
|
margin-left: 40rpx;
|
|
width: 48rpx;
|
|
height: 48rpx;
|
|
border-radius: 50%;
|
|
}
|
|
}
|
|
|
|
&-plus {
|
|
width: 128rpx;
|
|
height: 128rpx;
|
|
background: #f6f6f6;
|
|
|
|
.iconfont {
|
|
font-size: 48rpx;
|
|
color: #888;
|
|
}
|
|
}
|
|
|
|
&-image {
|
|
width: 128rpx;
|
|
height: 128rpx;
|
|
background: #f6f6f6;
|
|
}
|
|
|
|
&-error {
|
|
border-color: #f93920;
|
|
}
|
|
|
|
&-file {
|
|
width: 400rpx;
|
|
padding: 16rpx;
|
|
background: rgba(12, 20, 102, 0.04);
|
|
gap: 8rpx;
|
|
overflow: hidden;
|
|
|
|
.doc-image {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 96rpx;
|
|
height: 96rpx;
|
|
}
|
|
|
|
.doc-info-container {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4rpx;
|
|
font-weight: 400;
|
|
|
|
.doc-name {
|
|
font-size: 28rpx;
|
|
color: #15171f;
|
|
}
|
|
|
|
.doc-size {
|
|
font-size: 24rpx;
|
|
color: #828894;
|
|
}
|
|
}
|
|
}
|
|
|
|
.image {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.del-container {
|
|
position: absolute;
|
|
top: 4rpx;
|
|
right: 4rpx;
|
|
z-index: 10;
|
|
}
|
|
}
|
|
}
|
|
</style>
|