This commit is contained in:
owenchen committed 2026-10-22 07:59:53 +08:00
1 parent 7fb4503e0e
commit 69046e827c
9 files changed
+292 -245

No files matched your search

@@ -65,9 +65,9 @@ function onThumbError(file: FileItem): void {
thumbFailed.value.add(file.id);
}
/** 可显缩略图的地址:仅图片类型且后端 Url(Scale 压缩图)有值、未报错 */
/** 可显缩略图的地址:图片是 Scale 压缩图、视频是上传时抽的同名 jpg(两者都在 thumbUrl 里),有值且未报错才显 */
function thumbSrcOf(file: FileItem): string {
return file.kind === "image" && file.thumbUrl && !thumbFailed.value.has(file.id) ? file.thumbUrl : "";
return file.thumbUrl && !thumbFailed.value.has(file.id) ? file.thumbUrl : "";
}
function isSelected(file: FileItem): boolean {
@@ -120,7 +120,7 @@ function onCardTap(file: FileItem): void {
<view v-if="file.kind === 'folder'" class="fgl-card__folder" :style="folderStyle">
<view class="fgl-card__folder-tab" :style="folderTabStyle" />
</view>
<!-- 图片卡:后端 Url 指向 Scale 原图压缩缩略(旧系统宫格同款),失败回退图标 -->
<!-- 缩略图:图片是后端 Scale 压缩图,视频是上传时 ffmpeg 抽的同名 jpg(旧系统 MyComputer 同款),失败回退图标 -->
<image v-else-if="thumbSrcOf(file)" class="fgl-card__thumb" :src="thumbSrcOf(file)"
mode="aspectFill" @error="onThumbError(file)" />
<u-icon v-else :name="visualOf(file.kind)!.icon" size="88" :color="visualOf(file.kind)!.color" />
@@ -134,6 +134,10 @@ function onCardTap(file: FileItem): void {
:color="file.permission === 'Y' ? '#52c41a' : '#8c8c8c'" />
<u-icon v-if="file.shared" name="share-fill" size="28" color="#1890ff" />
</view>
<!-- 视频封右下角的播放角标(旧系统 play-overlay 同位):没截到图回退图标时不叠 -->
<view v-if="file.kind === 'video' && thumbSrcOf(file)" class="fgl-card__play">
<u-icon name="play-right-fill" size="18" color="#ffffff" />
</view>
</view>
<view class="fgl-card__info">
@@ -259,6 +263,20 @@ function onCardTap(file: FileItem): void {
background-color: rgba(31, 35, 41, 0.04);
}
/* 视频播放角标:压在封面右下角,半透黑圆底 + 白三角 */
.fgl-card__play {
position: absolute;
right: 6rpx;
bottom: 6rpx;
display: flex;
align-items: center;
justify-content: center;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: rgba(31, 35, 41, 0.55);
}
.fgl-card__info {
width: 100%;
padding: 0 12rpx;
@@ -12,23 +12,23 @@ import { computed, ref, watch } from "vue";
import { useDmsFiles, useThemeTokens } from "@/composables";
const props = defineProps({
/** 弹层是否展开 */
visible: {
type: Boolean,
default: false,
},
/** 可选文件类型(folder 不在此列也始终可进入) */
accept: {
type: Array as PropType<FileKind[]>,
default: () => ["image", "audio", "document"],
},
/** 弹层是否展开 */
visible: {
type: Boolean,
default: false,
},
/** 可选文件类型(folder 不在此列也始终可进入) */
accept: {
type: Array as PropType<FileKind[]>,
default: () => ["image", "audio", "document"],
},
});
const emit = defineEmits<{
/** 关闭弹层(遮罩/关闭按钮/根目录点返回) */
(e: "close"): void;
/** 选中一个文件,回传完整记录(FileName 是提交值,Url 可直接预览) */
(e: "select", record: DmsFileUploadViewDisplayData): void;
/** 关闭弹层(遮罩/关闭按钮/根目录点返回) */
(e: "close"): void;
/** 选中一个文件,回传完整记录(FileName 是提交值,Url 可直接预览) */
(e: "select", record: DmsFileUploadViewDisplayData): void;
}>();
const { t } = useLocale();
@@ -39,278 +39,279 @@ const keyword = ref("");
/** 类型过滤:文件夹保留用于下钻,文件只留 accept 内的类型 */
const rows = computed<FileItem[]>(() =>
files.files.value.filter(
file => file.kind === "folder" || props.accept.includes(file.kind),
),
files.files.value.filter(
file => file.kind === "folder" || props.accept.includes(file.kind),
),
);
const loading = files.loading;
/** 当前目录名(面包屑末项),用于顶部路径展示 */
const currName = computed(
() => files.pathStack.value[files.pathStack.value.length - 1]?.displayName || t("FilePage.myCloud"),
() => files.pathStack.value[files.pathStack.value.length - 1]?.displayName || t("FilePage.myCloud"),
);
// 每次打开都从「我的网盘」根目录重新加载:目录可能被别的操作改过,也避免停在上一轮的下钻位置
watch(
() => props.visible,
(open) => {
if (!open) {
return;
}
keyword.value = "";
void files.init();
},
{ immediate: true },
() => props.visible,
(open) => {
if (!open) {
return;
}
keyword.value = "";
void files.init();
},
{ immediate: true },
);
/** 点文件夹下钻,点文件回传并关闭 */
async function onTap(row: FileItem): Promise<void> {
if (row.kind === "folder") {
await files.openFolder(row);
return;
}
const record = files.records.value.get(row.id);
if (!record) {
return;
}
emit("select", record);
emit("close");
if (row.kind === "folder") {
await files.openFolder(row);
return;
}
const record = files.records.value.get(row.id);
if (!record) {
return;
}
emit("select", record);
emit("close");
}
/** 返回上级;已在根目录则关闭弹层 */
async function onBack(): Promise<void> {
const stayed = await files.back();
if (!stayed) {
emit("close");
}
const stayed = await files.back();
if (!stayed) {
emit("close");
}
}
async function onSearch(): Promise<void> {
await files.search(keyword.value);
await files.search(keyword.value);
}
/** 文件类型 -> 图标与配色(与 file-grid-list 同套;文件夹用 CSS 造型,图标库没有 folder) */
const kindVisual: Record<Exclude<FileKind, "folder">, { icon: string; color: string }> = {
image: { icon: "photo-fill", color: "#0ea5e9" },
video: { icon: "play-right-fill", color: "#8b5cf6" },
document: { icon: "file-text-fill", color: "#3b82f6" },
audio: { icon: "volume-up", color: "#f59e0b" },
image: { icon: "photo-fill", color: "#0ea5e9" },
video: { icon: "play-right-fill", color: "#8b5cf6" },
document: { icon: "file-text-fill", color: "#3b82f6" },
audio: { icon: "volume-up", color: "#f59e0b" },
};
function visualOf(kind: FileKind): { icon: string; color: string } {
return kind === "folder" ? { icon: "file-text-fill", color: "#8f959e" } : kindVisual[kind];
return kind === "folder" ? { icon: "file-text-fill", color: "#8f959e" } : kindVisual[kind];
}
// 缩略图加载失败的行记住失败态,回退类型图标(与网盘宫格同一套处理,图被清理时不致白块)
const thumbFailed = ref(new Set<number>());
function onThumbError(row: FileItem): void {
thumbFailed.value.add(row.id);
thumbFailed.value.add(row.id);
}
/** 可显缩略图的地址:仅图片类型且后端 Url(Scale 压缩图)有值、未报错 */
/** 可显缩略图的地址:图片是 Scale 压缩图、视频是上传时抽的同名 jpg(两者都在 thumbUrl 里),有值且未报错才显 */
function thumbSrcOf(row: FileItem): string {
return row.kind === "image" && row.thumbUrl && !thumbFailed.value.has(row.id) ? row.thumbUrl : "";
return row.thumbUrl && !thumbFailed.value.has(row.id) ? row.thumbUrl : "";
}
</script>
<template>
<!-- u-popup 只认 modelValue(v-model),绑 :show 会静默弹不出 -->
<u-popup :model-value="visible" mode="bottom" round="24" @close="emit('close')">
<view class="file-pick">
<view class="file-pick__head">
<text class="file-pick__title">{{ t("FilePage.pickFile") }}</text>
<u-icon name="close" size="32" color="#8f959e" @click="emit('close')" />
</view>
<!-- u-popup 只认 modelValue(v-model),绑 :show 会静默弹不出 -->
<u-popup :model-value="visible" mode="bottom" round="24" @close="emit('close')">
<view class="file-pick">
<view class="file-pick__head">
<text class="file-pick__title">{{ t("FilePage.pickFile") }}</text>
<u-icon name="close" size="32" color="#8f959e" @click="emit('close')" />
</view>
<!-- 当前目录 + 返回上级 -->
<view class="file-pick__bar">
<view class="file-pick__back" @tap="onBack">
<u-icon name="arrow-left" size="28" color="#5c626b" />
</view>
<text class="file-pick__path">{{ currName }}</text>
</view>
<!-- 当前目录 + 返回上级 -->
<view class="file-pick__bar">
<view class="file-pick__back" @tap="onBack">
<u-icon name="arrow-left" size="28" color="#5c626b" />
</view>
<text class="file-pick__path">{{ currName }}</text>
</view>
<!-- 按名称搜索当前目录(回车或点放大镜) -->
<view class="file-pick__search">
<input v-model="keyword" class="file-pick__search-input" :placeholder="t('FilePage.searchPlaceholder')"
confirm-type="search" @confirm="onSearch">
<view class="file-pick__search-btn" @tap="onSearch">
<u-icon name="search" size="32" color="#8f959e" />
</view>
</view>
<!-- 按名称搜索当前目录(回车或点放大镜) -->
<view class="file-pick__search">
<input v-model="keyword" class="file-pick__search-input" :placeholder="t('FilePage.searchPlaceholder')"
confirm-type="search" @confirm="onSearch">
<view class="file-pick__search-btn" @tap="onSearch">
<u-icon name="search" size="32" color="#8f959e" />
</view>
</view>
<scroll-view scroll-y class="file-pick__list">
<view v-if="loading" class="file-pick__empty">
<text>{{ t("FilePage.loading") }}</text>
</view>
<view v-else-if="!rows.length" class="file-pick__empty">
<text>{{ t("FilePage.emptyText") }}</text>
</view>
<view v-for="row in rows" :key="row.id" class="file-pick__row" @tap="onTap(row)">
<view v-if="row.kind === 'folder'" class="file-pick__folder" :style="{ background: accentGradient }">
<view class="file-pick__folder-tab" :style="{ background: accentGradient }" />
</view>
<!-- 图片行:后端 Url 指向 Scale 压缩缩略(网盘宫格同源),失败回退类型图标 -->
<image v-else-if="thumbSrcOf(row)" class="file-pick__thumb" :src="thumbSrcOf(row)"
mode="aspectFill" @error="onThumbError(row)" />
<u-icon v-else :name="visualOf(row.kind).icon" size="36" :color="visualOf(row.kind).color" />
<view class="file-pick__row-main">
<text class="file-pick__row-name">{{ row.name }}</text>
<text v-if="row.sizeText" class="file-pick__row-meta">{{ row.sizeText }}</text>
</view>
<u-icon v-if="row.kind === 'folder'" name="arrow-right" size="24" color="#c0c4cc" />
</view>
</scroll-view>
<scroll-view scroll-y class="file-pick__list">
<view v-if="loading" class="file-pick__empty">
<text>{{ t("FilePage.loading") }}</text>
</view>
<view v-else-if="!rows.length" class="file-pick__empty">
<text>{{ t("FilePage.emptyText") }}</text>
</view>
<view v-for="row in rows" :key="row.id" class="file-pick__row" @tap="onTap(row)">
<view v-if="row.kind === 'folder'" class="file-pick__folder"
:style="{ background: accentGradient }">
<view class="file-pick__folder-tab" :style="{ background: accentGradient }" />
</view>
<!-- 缩略图:图片走 Scale 压缩图,视频走后端抽的同名 jpg(网盘宫格同源),失败回退类型图标 -->
<image v-else-if="thumbSrcOf(row)" class="file-pick__thumb" :src="thumbSrcOf(row)" mode="aspectFill"
@error="onThumbError(row)" />
<u-icon v-else :name="visualOf(row.kind).icon" size="36" :color="visualOf(row.kind).color" />
<view class="file-pick__row-main">
<text class="file-pick__row-name">{{ row.name }}</text>
<text v-if="row.sizeText" class="file-pick__row-meta">{{ row.sizeText }}</text>
</view>
<u-icon v-if="row.kind === 'folder'" name="arrow-right" size="24" color="#c0c4cc" />
</view>
</scroll-view>
<view class="file-pick__safe" />
</view>
</u-popup>
<view class="file-pick__safe" />
</view>
</u-popup>
</template>
<style lang="scss" scoped>
/* 底部抽屉统一风格:浅灰面板底 + 白色圆角行 */
.file-pick {
padding: 32rpx 24rpx 0;
background-color: #f2f3f5;
padding: 32rpx 24rpx 0;
background-color: #f2f3f5;
&__head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 8rpx 24rpx;
}
&__head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 8rpx 24rpx;
}
&__title {
font-size: 30rpx;
font-weight: 600;
color: #1f2329;
}
&__title {
font-size: 30rpx;
font-weight: 600;
color: #1f2329;
}
&__bar {
display: flex;
align-items: center;
gap: 16rpx;
padding: 20rpx 24rpx;
border-radius: 16rpx;
background-color: #ffffff;
}
&__bar {
display: flex;
align-items: center;
gap: 16rpx;
padding: 20rpx 24rpx;
border-radius: 16rpx;
background-color: #ffffff;
}
&__back {
display: flex;
align-items: center;
justify-content: center;
}
&__back {
display: flex;
align-items: center;
justify-content: center;
}
&__path {
flex: 1;
min-width: 0;
overflow: hidden;
font-size: 26rpx;
color: #5c626b;
text-overflow: ellipsis;
white-space: nowrap;
}
&__path {
flex: 1;
min-width: 0;
overflow: hidden;
font-size: 26rpx;
color: #5c626b;
text-overflow: ellipsis;
white-space: nowrap;
}
&__search {
display: flex;
align-items: center;
gap: 12rpx;
height: 76rpx;
margin-top: 16rpx;
padding: 0 24rpx;
border-radius: 16rpx;
background-color: #ffffff;
}
&__search {
display: flex;
align-items: center;
gap: 12rpx;
height: 76rpx;
margin-top: 16rpx;
padding: 0 24rpx;
border-radius: 16rpx;
background-color: #ffffff;
}
&__search-input {
flex: 1;
min-width: 0;
font-size: 28rpx;
color: #1f2329;
}
&__search-input {
flex: 1;
min-width: 0;
font-size: 28rpx;
color: #1f2329;
}
&__search-btn {
display: flex;
align-items: center;
justify-content: center;
}
&__search-btn {
display: flex;
align-items: center;
justify-content: center;
}
&__list {
height: 52vh;
margin-top: 16rpx;
}
&__list {
height: 52vh;
margin-top: 16rpx;
}
&__row {
display: flex;
align-items: center;
gap: 20rpx;
margin-bottom: 16rpx;
padding: 24rpx 28rpx;
border-radius: 16rpx;
background-color: #ffffff;
}
&__row {
display: flex;
align-items: center;
gap: 20rpx;
margin-bottom: 16rpx;
padding: 24rpx 28rpx;
border-radius: 16rpx;
background-color: #ffffff;
}
&__row-main {
display: flex;
flex: 1;
flex-direction: column;
min-width: 0;
}
&__row-main {
display: flex;
flex: 1;
flex-direction: column;
min-width: 0;
}
/* 图片预览缩略:尺寸与网盘宫格缩略一致 */
&__thumb {
flex-shrink: 0;
width: 96rpx;
height: 96rpx;
border-radius: 14rpx;
background-color: rgba(31, 35, 41, 0.04);
}
/* 图片预览缩略:尺寸与网盘宫格缩略一致 */
&__thumb {
flex-shrink: 0;
width: 96rpx;
height: 96rpx;
border-radius: 14rpx;
background-color: rgba(31, 35, 41, 0.04);
}
&__row-name {
overflow: hidden;
font-size: 28rpx;
color: #1f2329;
text-overflow: ellipsis;
white-space: nowrap;
}
&__row-name {
overflow: hidden;
font-size: 28rpx;
color: #1f2329;
text-overflow: ellipsis;
white-space: nowrap;
}
&__row-meta {
margin-top: 6rpx;
font-size: 22rpx;
color: #a8adb5;
}
&__row-meta {
margin-top: 6rpx;
font-size: 22rpx;
color: #a8adb5;
}
/* 文件夹:纯 CSS 造型(主体 + 左上页签) */
&__folder {
position: relative;
width: 44rpx;
height: 32rpx;
border-radius: 6rpx;
}
/* 文件夹:纯 CSS 造型(主体 + 左上页签) */
&__folder {
position: relative;
width: 44rpx;
height: 32rpx;
border-radius: 6rpx;
}
&__folder-tab {
position: absolute;
top: -8rpx;
left: 0;
width: 20rpx;
height: 10rpx;
border-radius: 4rpx 4rpx 0 0;
}
&__folder-tab {
position: absolute;
top: -8rpx;
left: 0;
width: 20rpx;
height: 10rpx;
border-radius: 4rpx 4rpx 0 0;
}
&__empty {
display: flex;
align-items: center;
justify-content: center;
padding: 80rpx 0;
font-size: 26rpx;
color: #a8adb5;
}
&__empty {
display: flex;
align-items: center;
justify-content: center;
padding: 80rpx 0;
font-size: 26rpx;
color: #a8adb5;
}
/* 底部留白:贴屏安全区 */
&__safe {
height: calc(32rpx + env(safe-area-inset-bottom));
}
/* 底部留白:贴屏安全区 */
&__safe {
height: calc(32rpx + env(safe-area-inset-bottom));
}
}
</style>
@@ -20,6 +20,7 @@ import { computed, ref } from "vue";
import { DmsFileSearchCriteria } from "@/data/auto/dmsFileSearchCriteria";
import { DmsFileUploadViewDisplayData as UploadView } from "@/data/auto/dmsFileUploadViewDisplayData";
import { SearchFilter } from "@/data/auto/searchFilter";
import { pickThumbUrl } from "@/data/custom/fileBrowser";
import fileTypePolicy, { FileTypePolicy } from "@/policy/custom/fileTypePolicy";
import dmsFileService from "@/service/master/dmsFileService";
@@ -132,8 +133,8 @@ export function useDmsFiles() {
id: record.FileId,
name: record.OrgFileName || record.FileName,
kind,
// 图片卡显 Scale 缩略图(后端 Url 字段已拼好,旧系统宫格同款)
thumbUrl: kind === "image" ? record.Url || undefined : undefined,
// 图片卡显 Scale 缩略图(后端 Url),视频卡显上传时抽的同名 jpg(后端 FormattedPic,旧系统视频卡同款)
thumbUrl: pickThumbUrl(kind, record.Url, record.FormattedPic),
// 卡片元数据不显示用户:文件夹 sizeText 为空只剩时间,文件显示大小+时间
// FileSize 单位是 KB(旧系统 DmsFileEnquiry 下载缓冲 (FileSize+1)*1024 字节佐证),先换算成字节
sizeText: formatSize(
@@ -24,6 +24,7 @@ import { DmsFileSearchCriteria } from "@/data/auto/dmsFileSearchCriteria";
import { FamilyDmsFileViewDisplayData as FamilyView } from "@/data/auto/familyDmsFileViewDisplayData";
import { FamilyDmsFileViewEntity } from "@/data/auto/familyDmsFileViewEntity";
import { SearchFilter } from "@/data/auto/searchFilter";
import { pickThumbUrl } from "@/data/custom/fileBrowser";
import dmsFileService from "@/service/master/dmsFileService";
import familyGroupService from "@/service/master/familyGroupService";
import {
@@ -88,8 +89,8 @@ export function useShareHall() {
id: record.FileId,
name: record.OrgFileName || record.FileName,
kind,
// 图片卡显 Scale 缩略图(后端 Url 字段已拼好,旧系统宫格同款)
thumbUrl: kind === "image" ? record.Url || undefined : undefined,
// 图片卡显 Scale 缩略图(后端 Url),视频卡显上传时抽的同名 jpg(后端 FormattedPic,旧系统视频卡同款)
thumbUrl: pickThumbUrl(kind, record.Url, record.FormattedPic),
// FileSize 单位是 KB(旧系统下载缓冲 (FileSize+1)*1024 字节佐证),先换算成字节
sizeText: formatSize(
record.FileSize ? record.FileSize * 1024 : undefined,
@@ -16,6 +16,7 @@ import { ref } from "vue";
import { DmsFileSearchCriteria } from "@/data/auto/dmsFileSearchCriteria";
import { DmsFileUploadDeleteLogViewDisplayData as DeleteLogView } from "@/data/auto/dmsFileUploadDeleteLogViewDisplayData";
import { SearchFilter } from "@/data/auto/searchFilter";
import { pickThumbUrl } from "@/data/custom/fileBrowser";
import dmsFileService from "@/service/master/dmsFileService";
import {
formatModifiedLabel,
@@ -45,8 +46,8 @@ export function useTrashFiles() {
id: record.FileId,
name: record.OrgFileName || record.FileName,
kind,
// 回收站也显缩略图(日志视图 Url 同口径拼的 Scale 图,文件删了图还在)
thumbUrl: kind === "image" ? record.Url || undefined : undefined,
// 回收站也显缩略图:图片是 Scale 压缩图、视频是同名 jpg 封面(日志视图同口径拼的,文件删了图还在)
thumbUrl: pickThumbUrl(kind, record.Url, record.FormattedPic),
// FileSize 单位是 KB(旧系统下载缓冲 (FileSize+1)*1024 字节佐证),先换算成字节
sizeText: formatSize(
record.FileSize ? record.FileSize * 1024 : undefined,
+20 -1
View File
@@ -28,10 +28,29 @@ export interface FileItem {
permission?: "Y" | "N";
/** 已被收藏共享(PermissionIndc=Y 且 FavoriteIndc=Y):显示蓝色共享角标 */
shared?: boolean;
/** 图片缩略图地址(后端 PackUrl 拼的 Scale 压缩图,旧系统宫格同款);仅 image 类型且有值时卡片显图,否则显类型图标 */
/** 缩略图地址:图片是后端 PackUrl 拼的 Scale 压缩图,视频是后端 ffmpeg 截的同名 jpg(旧系统 MyComputer 同款);
* 没值(如老视频从未截过图)时卡片回退类型图标 */
thumbUrl?: string;
}
/**
* 卡片缩略图取值:图片用 Url(Scale 压缩图)、视频用 FormattedPic(上传时抽帧的同名 .jpg),
* 其余类型不给图。三处列表(网盘 / 共享域 / 回收站)统一走这里,不再各自写判断。
*/
export function pickThumbUrl(
kind: FileKind,
url?: string | null,
formattedPic?: string | null,
): string | undefined {
if (kind === "image") {
return url || undefined;
}
if (kind === "video") {
return formattedPic || undefined;
}
return undefined;
}
/** 快捷功能入口的单项:图标 + 渐变底色,页面给什么画什么 */
export interface QuickEntryItem {
key: string;
+13 -15
View File
@@ -1013,7 +1013,8 @@ function onRemoveGroup(familyName: string): void {
<u-icon name="close" size="32" color="#8f959e" @click="closeDetailEditor" />
</view>
<!-- 音轨 6 个字段超出小屏时表单内滚动,按钮固定在底部 -->
<scroll-view scroll-y class="detail-sheet__scroll" :class="{ 'detail-sheet__scroll--audio': kind === 'audio' }">
<scroll-view scroll-y class="detail-sheet__scroll"
:class="{ 'detail-sheet__scroll--audio': kind === 'audio' }">
<view class="detail-sheet__form">
<!-- 音轨:标题/歌手/封面/地址/歌词(对齐旧系统表单),文件字段走「我的网盘」选择 -->
<template v-if="kind === 'audio'">
@@ -1031,10 +1032,9 @@ function onRemoveGroup(familyName: string): void {
<text class="detail-sheet-field__label">{{ t("MediaPage.detailCover") }}</text>
<view class="detail-sheet-field__file">
<view class="detail-sheet-field__static">
<text
class="detail-sheet-field__static-text"
:class="{ 'detail-sheet-field__static-text--empty': !detailDraft.picName }"
>{{ detailDraft.picName || t("MediaPage.detailCover") }}</text>
<text class="detail-sheet-field__static-text"
:class="{ 'detail-sheet-field__static-text--empty': !detailDraft.picName }">{{
detailDraft.picName || t("MediaPage.detailCover") }}</text>
</view>
<view class="detail-sheet-field__pick" @tap="openFilePicker('pic')">
<u-icon name="search" size="32" color="#8f959e" />
@@ -1045,10 +1045,9 @@ function onRemoveGroup(familyName: string): void {
<text class="detail-sheet-field__label">{{ t("MediaPage.detailUrl") }}</text>
<view class="detail-sheet-field__file">
<view class="detail-sheet-field__static">
<text
class="detail-sheet-field__static-text"
:class="{ 'detail-sheet-field__static-text--empty': !detailDraft.urlName }"
>{{ detailDraft.urlName || t("MediaPage.detailUrl") }}</text>
<text class="detail-sheet-field__static-text"
:class="{ 'detail-sheet-field__static-text--empty': !detailDraft.urlName }">{{
detailDraft.urlName || t("MediaPage.detailUrl") }}</text>
</view>
<view class="detail-sheet-field__pick" @tap="openFilePicker('url')">
<u-icon name="search" size="32" color="#8f959e" />
@@ -1059,10 +1058,9 @@ function onRemoveGroup(familyName: string): void {
<text class="detail-sheet-field__label">{{ t("MediaPage.detailLrc") }}</text>
<view class="detail-sheet-field__file">
<view class="detail-sheet-field__static">
<text
class="detail-sheet-field__static-text"
:class="{ 'detail-sheet-field__static-text--empty': !detailDraft.lrcName }"
>{{ detailDraft.lrcName || t("MediaPage.detailLrc") }}</text>
<text class="detail-sheet-field__static-text"
:class="{ 'detail-sheet-field__static-text--empty': !detailDraft.lrcName }">{{
detailDraft.lrcName || t("MediaPage.detailLrc") }}</text>
</view>
<view class="detail-sheet-field__pick" @tap="openFilePicker('lrc')">
<u-icon name="search" size="32" color="#8f959e" />
@@ -1092,8 +1090,8 @@ function onRemoveGroup(familyName: string): void {
</u-popup>
<!-- 明细文件选择(封面/地址/歌词):从我的网盘挑文件,回填 DMS 文件名 -->
<file-picker-sheet :visible="filePickerVisible" :accept="filePickerAccept"
@close="filePickerVisible = false" @select="onPickFile" />
<file-picker-sheet :visible="filePickerVisible" :accept="filePickerAccept" @close="filePickerVisible = false"
@select="onPickFile" />
</view>
</app-page>
</template>