ow
This commit is contained in:
1 parent
599211b895
commit
9bbb8dfd67
9 files changed
+2889
-803
No files matched your search
@@ -0,0 +1,488 @@
|
||||
<template>
|
||||
<div class="my-computer" ref="containerRef">
|
||||
<div class="my-computer-header">
|
||||
<div class="view-toggles">
|
||||
<a-tooltip title="列表视图">
|
||||
<a-button
|
||||
size="small"
|
||||
:type="viewMode === 'list' ? 'primary' : 'default'"
|
||||
@click="viewMode = 'list'"
|
||||
>
|
||||
<UnorderedListOutlined />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="图标视图">
|
||||
<a-button
|
||||
size="small"
|
||||
:type="viewMode === 'icon' ? 'primary' : 'default'"
|
||||
@click="viewMode = 'icon'"
|
||||
>
|
||||
<AppstoreOutlined />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-computer-body" v-if="viewMode === 'icon'">
|
||||
<div
|
||||
v-for="record in datas"
|
||||
:key="record.FileId + '-' + record.FileName"
|
||||
class="file-card-wrapper"
|
||||
@click="onCardClick(record)"
|
||||
@dblclick="onCardDblClick(record)"
|
||||
>
|
||||
<!-- checkbox -->
|
||||
<div class="file-checkbox-wrapper">
|
||||
<a-checkbox
|
||||
:checked="isSelected(record)"
|
||||
@click.stop="toggleSelect(record)"
|
||||
/>
|
||||
</div>
|
||||
<!-- 状态角标:右上角 -->
|
||||
<div class="file-status-badge">
|
||||
<LockOutlined
|
||||
v-if="record.PermissionIndc === 'N'"
|
||||
class="badge-lock"
|
||||
/>
|
||||
<template v-if="record.PermissionIndc === 'Y'">
|
||||
<UnlockOutlined class="badge-unlock" />
|
||||
<ShareAltOutlined
|
||||
v-if="record.FavoriteIndc === 'Y'"
|
||||
class="badge-share"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<div class="file-content">
|
||||
<template v-if="record.IsDirectoryIndc == 'Y'">
|
||||
<div class="folder-icon">
|
||||
<FolderOutlined />
|
||||
</div>
|
||||
<div class="file-name" :title="record.OrgFileName">
|
||||
{{ record.OrgFileName }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isImage(record.OrderKey)">
|
||||
<div class="image-thumb">
|
||||
<img
|
||||
:src="record.Url"
|
||||
:title="record.OrgFileName"
|
||||
@click.stop="$emit('preview-image', record)"
|
||||
/>
|
||||
</div>
|
||||
<div class="file-name" :title="record.OrgFileName">
|
||||
{{ record.OrgFileName }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isVideo(record.OrderKey)">
|
||||
<div class="video-thumb">
|
||||
<img
|
||||
:src="record.FormattedPic.replace('.m3u8', '.png')"
|
||||
:title="record.OrgFileName"
|
||||
/>
|
||||
<div class="play-overlay">
|
||||
<PlayCircleOutlined />
|
||||
</div>
|
||||
</div>
|
||||
<div class="file-name" :title="record.OrgFileName">
|
||||
{{ record.OrgFileName }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isAudio(record.OrderKey)">
|
||||
<div
|
||||
class="audio-icon"
|
||||
:class="{
|
||||
playing: record.IsPlay == 'Y' && record.IsPause != 'Y',
|
||||
}"
|
||||
>
|
||||
<cust-icon-font
|
||||
size="54"
|
||||
type="icon-playmp3"
|
||||
style="color: #ff7878"
|
||||
/>
|
||||
</div>
|
||||
<div class="file-name" :title="record.OrgFileName">
|
||||
{{ record.OrgFileName }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="file-icon">
|
||||
<FileOutlined />
|
||||
</div>
|
||||
<div class="file-name" :title="record.OrgFileName">
|
||||
{{ record.OrgFileName }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<a-empty v-if="!datas || datas.length === 0" description="暂无文件" />
|
||||
</div>
|
||||
<div class="my-computer-body list-body" v-else>
|
||||
<div
|
||||
v-for="record in datas"
|
||||
:key="record.FileId + '-' + record.FileName"
|
||||
class="list-item"
|
||||
:class="{ selected: isSelected(record) }"
|
||||
@click="onCardClick(record)"
|
||||
@dblclick="onCardDblClick(record)"
|
||||
>
|
||||
<a-checkbox
|
||||
:checked="isSelected(record)"
|
||||
@click.stop="toggleSelect(record)"
|
||||
/>
|
||||
<div class="list-icon">
|
||||
<template v-if="record.IsDirectoryIndc == 'Y'">
|
||||
<FolderOutlined style="color: #faad14" />
|
||||
</template>
|
||||
<template v-else-if="isImage(record.OrderKey)">
|
||||
<FileImageOutlined style="color: #52c41a" />
|
||||
</template>
|
||||
<template v-else-if="isVideo(record.OrderKey)">
|
||||
<VideoCameraOutlined style="color: #1890ff" />
|
||||
</template>
|
||||
<template v-else-if="isAudio(record.OrderKey)">
|
||||
<PlayCircleOutlined style="color: #eb2f96" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<FileOutlined style="color: #8c8c8c" />
|
||||
</template>
|
||||
</div>
|
||||
<div class="list-name-wrap">
|
||||
<span class="list-name" :title="record.OrgFileName">{{
|
||||
record.OrgFileName
|
||||
}}</span>
|
||||
<span class="list-status-icon">
|
||||
<LockOutlined
|
||||
v-if="record.PermissionIndc === 'N'"
|
||||
class="icon-lock"
|
||||
/>
|
||||
<template v-if="record.PermissionIndc === 'Y'">
|
||||
<UnlockOutlined class="icon-unlock" />
|
||||
<ShareAltOutlined
|
||||
v-if="record.FavoriteIndc === 'Y'"
|
||||
class="icon-share"
|
||||
/>
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
<div class="list-size">{{ formatSize(record.FileSize) }}</div>
|
||||
<div class="list-date">{{ formatDate(record.CreatedDatetime) }}</div>
|
||||
</div>
|
||||
<a-empty v-if="!datas || datas.length === 0" description="暂无文件" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import {
|
||||
FolderOutlined,
|
||||
FileOutlined,
|
||||
FileImageOutlined,
|
||||
VideoCameraOutlined,
|
||||
PlayCircleOutlined,
|
||||
UnorderedListOutlined,
|
||||
AppstoreOutlined,
|
||||
LockOutlined,
|
||||
UnlockOutlined,
|
||||
ShareAltOutlined,
|
||||
} from "@ant-design/icons-vue";
|
||||
import { FamilyDmsFileViewDisplayData } from "@/data/auto/familyDmsFileViewDisplayData";
|
||||
import { notification } from "ant-design-vue";
|
||||
const props = defineProps<{
|
||||
datas: FamilyDmsFileViewDisplayData[];
|
||||
selectedKeys: FamilyDmsFileViewDisplayData[];
|
||||
}>();
|
||||
const emit = defineEmits([
|
||||
"update:selectedKeys",
|
||||
"select-change",
|
||||
"open-folder",
|
||||
"open-file",
|
||||
"preview-image",
|
||||
]);
|
||||
const viewMode = ref<"icon" | "list">("icon");
|
||||
const isSelected = (record: FamilyDmsFileViewDisplayData) => {
|
||||
return props.selectedKeys.some((s) => s.FileId === record.FileId);
|
||||
};
|
||||
/**
|
||||
* 单选逻辑:
|
||||
* 如果当前已经选中,则清空;否则选中当前这一项
|
||||
*/
|
||||
const toggleSelect = (record: FamilyDmsFileViewDisplayData) => {
|
||||
let newKeys: FamilyDmsFileViewDisplayData[];
|
||||
if (isSelected(record)) {
|
||||
// 点击已选中项 → 取消选择
|
||||
newKeys = [];
|
||||
} else {
|
||||
// 点击未选中项 → 只选中当前一个
|
||||
newKeys = [record];
|
||||
}
|
||||
emit("update:selectedKeys", newKeys);
|
||||
emit("select-change", newKeys);
|
||||
};
|
||||
const onCardClick = (record: FamilyDmsFileViewDisplayData) => {
|
||||
toggleSelect(record);
|
||||
};
|
||||
const onCardDblClick = (record: FamilyDmsFileViewDisplayData) => {
|
||||
if (record.IsDirectoryIndc == "Y") {
|
||||
if (record.PermissionIndc == "Y") emit("open-folder", record);
|
||||
else {
|
||||
notification.info({
|
||||
message: "系统提示:",
|
||||
description: "你还没有权限访问该文件夹",
|
||||
placement: "topRight",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
emit("open-file", record);
|
||||
}
|
||||
};
|
||||
const isImage = (key: string) => {
|
||||
if (!key) return false;
|
||||
return /\.(png|jpe?g|gif|bmp|webp)$/i.test(key);
|
||||
};
|
||||
const isVideo = (key: string) => {
|
||||
if (!key) return false;
|
||||
return /\.(mp4|m3u8|rm|mpeg|mov|wmv|avi)$/i.test(key);
|
||||
};
|
||||
const isAudio = (key: string) => {
|
||||
if (!key) return false;
|
||||
return /\.(mp3|wav|flac|aac|ogg|wma)$/i.test(key);
|
||||
};
|
||||
const formatSize = (size: number) => {
|
||||
size = size * 1024;
|
||||
if (!size) return "-";
|
||||
if (size < 1024) return size + " B";
|
||||
if (size < 1024 * 1024) return (size / 1024).toFixed(1) + " KB";
|
||||
if (size < 1024 * 1024 * 1024) return (size / 1024 / 1024).toFixed(1) + " MB";
|
||||
return (size / 1024 / 1024 / 1024).toFixed(2) + " GB";
|
||||
};
|
||||
const formatDate = (date: any) => {
|
||||
if (!date) return "-";
|
||||
const d = new Date(date);
|
||||
if (isNaN(d.getTime())) return "-";
|
||||
return (
|
||||
d.getFullYear() +
|
||||
"-" +
|
||||
String(d.getMonth() + 1).padStart(2, "0") +
|
||||
"-" +
|
||||
String(d.getDate()).padStart(2, "0") +
|
||||
" " +
|
||||
String(d.getHours()).padStart(2, "0") +
|
||||
":" +
|
||||
String(d.getMinutes()).padStart(2, "0")
|
||||
);
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.my-computer {
|
||||
padding: 8px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.my-computer-header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 8px 4px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.view-toggles {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
.my-computer-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 4px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
gap: 16px;
|
||||
}
|
||||
.my-computer-body.list-body {
|
||||
flex-wrap: nowrap;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
.file-card-wrapper {
|
||||
width: 120px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s;
|
||||
position: relative;
|
||||
}
|
||||
.file-card-wrapper:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.file-checkbox-wrapper {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 4px;
|
||||
z-index: 1;
|
||||
}
|
||||
/* =========图标视图状态角标 右上角========= */
|
||||
.file-status-badge {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 4px;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
.badge-lock {
|
||||
font-size: 16px;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
.badge-unlock {
|
||||
font-size: 16px;
|
||||
color: #52c41a;
|
||||
}
|
||||
.badge-share {
|
||||
font-size: 16px;
|
||||
color: #1890ff;
|
||||
}
|
||||
.file-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
.folder-icon,
|
||||
.file-icon,
|
||||
.audio-icon {
|
||||
font-size: 56px;
|
||||
color: #faad14;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.file-icon {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
.audio-icon {
|
||||
color: #eb2f96;
|
||||
}
|
||||
.audio-icon.playing {
|
||||
animation: rotate 2s linear infinite;
|
||||
}
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.image-thumb,
|
||||
.video-thumb {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.image-thumb img,
|
||||
.video-thumb img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.video-thumb .play-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
font-size: 36px;
|
||||
color: #fff;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.video-thumb:hover .play-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
.file-name {
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
text-align: center;
|
||||
max-width: 110px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: background 0.15s;
|
||||
gap: 12px;
|
||||
}
|
||||
.list-item:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.list-item.selected {
|
||||
background: #e6f4ff;
|
||||
}
|
||||
.list-icon {
|
||||
font-size: 20px;
|
||||
width: 28px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
/* =========列表视图文件名+状态图标容器========= */
|
||||
.list-name-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.list-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.list-status-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.icon-lock {
|
||||
font-size: 14px;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
.icon-unlock {
|
||||
font-size: 14px;
|
||||
color: #52c41a;
|
||||
}
|
||||
.icon-share {
|
||||
font-size: 14px;
|
||||
color: #1890ff;
|
||||
}
|
||||
.list-size,
|
||||
.list-date {
|
||||
color: #8c8c8c;
|
||||
font-size: 13px;
|
||||
width: 120px;
|
||||
text-align: right;
|
||||
}
|
||||
.list-date {
|
||||
width: 160px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,287 @@
|
||||
<template>
|
||||
<div class="operator-station" v-if="!isDirectoryTop">
|
||||
<div class="operator-group main-actions">
|
||||
<a-tooltip title="新增文件夹">
|
||||
<a-button
|
||||
type="primary"
|
||||
v-if="canCreate"
|
||||
:icon="h(FolderAddOutlined)"
|
||||
@click="$emit('create-folder')"
|
||||
>新增文件夹</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
|
||||
<a-divider type="vertical" v-if="hasSelection" />
|
||||
|
||||
<div class="operator-group selection-actions" v-if="hasSelection">
|
||||
<template v-if="!isDirectorySelected && isSingleItem">
|
||||
<a-tooltip title="下载">
|
||||
<a-button
|
||||
type="text"
|
||||
:icon="h(DownloadOutlined)"
|
||||
:disabled="!canAmend"
|
||||
@click="onDownload"
|
||||
>下载</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
|
||||
<template v-if="isSingleVideo">
|
||||
<a-tooltip title="播放">
|
||||
<a-button
|
||||
type="text"
|
||||
:icon="h(PlayCircleOutlined, { style: { color: 'red' } })"
|
||||
@click="onPlayVideo"
|
||||
>播放</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="isSingleAudio">
|
||||
<a-tooltip v-if="selectedItem.IsPlay != 'Y'" title="播放">
|
||||
<a-button
|
||||
type="text"
|
||||
:icon="h(PlayCircleOutlined, { style: { color: 'red' } })"
|
||||
@click="onPlayAudio"
|
||||
>播放</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-else-if="selectedItem.IsPause != 'Y'" title="暂停">
|
||||
<a-button
|
||||
type="text"
|
||||
:icon="h(PauseCircleOutlined)"
|
||||
@click="onPauseAudio"
|
||||
>暂停</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-else title="继续">
|
||||
<a-button
|
||||
type="text"
|
||||
:icon="h(PlayCircleOutlined, { style: { color: 'red' } })"
|
||||
@click="onContinueAudio"
|
||||
>继续</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="isDirectorySelected">
|
||||
<a-tooltip :title="favorite">
|
||||
<a-button type="text" :icon="h(ShareAltOutlined)" @click="$emit('set-share-folder')"
|
||||
>{{favorite}}</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<a-divider type="vertical" v-if="hasSelection" />
|
||||
|
||||
<div style="display: none">
|
||||
<a-upload
|
||||
v-if="canCreate"
|
||||
v-model:file-list="fileList"
|
||||
name="file"
|
||||
:before-upload="onBeforeUpload"
|
||||
:headers="headers"
|
||||
:show-upload-list="false"
|
||||
:action="uploadUrl"
|
||||
ref="uploadRef"
|
||||
>
|
||||
</a-upload>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, h } from "vue";
|
||||
import {
|
||||
UploadOutlined,
|
||||
FolderAddOutlined,
|
||||
DownloadOutlined,
|
||||
ShareAltOutlined,
|
||||
NotificationOutlined,
|
||||
UnorderedListOutlined,
|
||||
PlayCircleOutlined,
|
||||
PauseCircleOutlined,
|
||||
EyeOutlined,
|
||||
EditOutlined,
|
||||
ScissorOutlined,
|
||||
DeleteOutlined,
|
||||
DownOutlined,
|
||||
} from "@ant-design/icons-vue";
|
||||
import { FamilyDmsFileViewDisplayData } from "@/data/auto/familyDmsFileViewDisplayData";
|
||||
import type { UploadProps } from "ant-design-vue";
|
||||
interface BreadcrumbItem {
|
||||
value: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
selectedItems: FamilyDmsFileViewDisplayData[];
|
||||
pathStack: BreadcrumbItem[];
|
||||
uploadUrl: string;
|
||||
headers: any;
|
||||
canCreate: boolean;
|
||||
canAmend: boolean;
|
||||
canDelete: boolean;
|
||||
canView: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits([
|
||||
"create-folder",
|
||||
"set-share-folder",
|
||||
"before-upload",
|
||||
"download",
|
||||
"share",
|
||||
"publish",
|
||||
"view-preview",
|
||||
"play-video",
|
||||
"play-audio",
|
||||
"pause-audio",
|
||||
"continue-audio",
|
||||
"preview",
|
||||
"rename",
|
||||
"move",
|
||||
"delete",
|
||||
]);
|
||||
|
||||
const fileList = ref<UploadProps["fileList"]>([]);
|
||||
const uploadRef = ref<any>(null);
|
||||
|
||||
const hasSelection = computed(() => props.selectedItems.length > 0);
|
||||
const isDirectorySelected = computed(() =>
|
||||
props.selectedItems.some((s) => s.IsDirectoryIndc == "Y"),
|
||||
);
|
||||
|
||||
const favorite = computed(() => {
|
||||
// 单选模式,取第一条选中
|
||||
const record = props.selectedItems[0];
|
||||
if (!record) return "";
|
||||
// 无权限,不支持分享
|
||||
if (record.PermissionIndc !== "Y") return "";
|
||||
|
||||
if (record.FavoriteIndc === "N") {
|
||||
return "设置分享";
|
||||
} else if (record.FavoriteIndc === "Y") {
|
||||
return "取消分享";
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
|
||||
const isDirectoryTop = computed(() => props.pathStack.length < 2);
|
||||
|
||||
const isSingleItem = computed(() => props.selectedItems.length === 1);
|
||||
|
||||
const selectedItem = computed(() => {
|
||||
return props.selectedItems[0] || ({} as FamilyDmsFileViewDisplayData);
|
||||
});
|
||||
|
||||
const selectedOrderKey = computed(() => {
|
||||
return selectedItem.value?.OrderKey || selectedItem.value?.OrgFileName || "";
|
||||
});
|
||||
|
||||
const isImage = (key: string) => {
|
||||
if (!key) return false;
|
||||
return /\.(png|jpe?g|gif|bmp|webp)$/i.test(key);
|
||||
};
|
||||
|
||||
const isVideo = (key: string) => {
|
||||
if (!key) return false;
|
||||
return /\.(mp4|m3u8|rm|mpeg|mov|wmv|avi)$/i.test(key);
|
||||
};
|
||||
|
||||
const isAudio = (key: string) => {
|
||||
if (!key) return false;
|
||||
return /\.(mp3|wav|flac|aac|ogg|wma)$/i.test(key);
|
||||
};
|
||||
|
||||
const isSingleVideo = computed(() => {
|
||||
return isSingleItem.value && isVideo(selectedOrderKey.value);
|
||||
});
|
||||
|
||||
const isSingleAudio = computed(() => {
|
||||
return isSingleItem.value && isAudio(selectedOrderKey.value);
|
||||
});
|
||||
|
||||
const publishTooltip = computed(() => {
|
||||
if (isImage(selectedOrderKey.value)) return "发布相册";
|
||||
if (isVideo(selectedOrderKey.value)) return "发布影视专辑";
|
||||
if (isAudio(selectedOrderKey.value)) return "发布音乐专辑";
|
||||
return "发布";
|
||||
});
|
||||
|
||||
const previewTooltip = computed(() => {
|
||||
if (isImage(selectedOrderKey.value)) return "相册展览";
|
||||
if (isVideo(selectedOrderKey.value)) return "影视厅播放";
|
||||
if (isAudio(selectedOrderKey.value)) return "音乐厅播放";
|
||||
return "预览";
|
||||
});
|
||||
|
||||
const triggerUpload = () => {
|
||||
uploadRef.value?.$el?.querySelector("input")?.click();
|
||||
};
|
||||
|
||||
const onBeforeUpload: UploadProps["beforeUpload"] = (file) => {
|
||||
emit("before-upload", file);
|
||||
return false;
|
||||
};
|
||||
|
||||
const onDownload = () => {
|
||||
emit("download", props.selectedItems);
|
||||
};
|
||||
|
||||
const onShare = () => {
|
||||
emit("share", props.selectedItems);
|
||||
};
|
||||
|
||||
const onPublish = () => {
|
||||
emit("publish", props.selectedItems);
|
||||
};
|
||||
|
||||
const onViewPreview = () => {
|
||||
emit("view-preview", props.selectedItems);
|
||||
};
|
||||
|
||||
const onPlayVideo = () => {
|
||||
emit("play-video", selectedItem.value);
|
||||
};
|
||||
|
||||
const onPlayAudio = () => {
|
||||
emit("play-audio", selectedItem.value);
|
||||
};
|
||||
|
||||
const onPauseAudio = () => {
|
||||
emit("pause-audio", selectedItem.value);
|
||||
};
|
||||
|
||||
const onContinueAudio = () => {
|
||||
emit("continue-audio", selectedItem.value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.operator-station {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 12px;
|
||||
background: #fafafa;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.operator-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.main-actions :deep(.ant-btn) {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.selection-actions :deep(.ant-btn) {
|
||||
padding: 4px 8px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user