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

No files matched your search

@@ -1456,6 +1456,14 @@ namespace CloudBuilder.Master.Service
{
ImageToScare(fullName, dmsFile);
}
else if (FileTypePolicy.GetType(fileExtension.ToLower()) == FileTypePolicy.VIDEO)
{
// 单片上传(小文件、App 端整文件不分片)也要出视频封面:走与多片合并分支同一条链,
// 截图落在备份目录里的同名 .jpg(前端宫格/详情封面读的就是这个文件),
// 否则只有被切成多片的视频有封面,小视频上传后永远是黑块
dmsFile.TranscodeIndc = YesNoPolicy.YES;
TsToM3u8(dmsFile.OrderKey, backupName, backupName.Replace(fileExtension, FileTypePolicy.JPG));
}
}
else//合并文件
{
@@ -3,7 +3,7 @@
<Project>
<PropertyGroup>
<_PublishTargetUrl>C:\inetpub\wwwroot\dockwebapi2</_PublishTargetUrl>
<History>True|2026-10-20T07:45:39.3393674Z||;True|2026-10-17T20:49:21.0401213+08:00||;True|2026-09-23T13:19:13.0148919+08:00||;True|2026-09-23T13:16:07.8584304+08:00||;True|2026-09-22T23:03:13.6509491+08:00||;True|2026-09-22T16:07:15.9177123+08:00||;True|2026-09-22T11:19:19.6087109+08:00||;True|2026-09-22T11:09:24.9165065+08:00||;True|2026-09-21T22:40:07.1232044+08:00||;True|2026-09-21T22:35:06.9446571+08:00||;True|2026-09-21T22:27:42.1146825+08:00||;False|2026-09-21T22:27:17.6066573+08:00||;True|2026-09-21T21:01:22.8888913+08:00||;True|2026-09-21T19:15:03.4753747+08:00||;True|2026-09-21T18:08:30.0866986+08:00||;True|2026-09-21T16:51:19.8137872+08:00||;True|2026-09-21T16:30:01.0950896+08:00||;True|2026-09-21T15:09:00.2326737+08:00||;True|2026-09-21T14:47:09.6120256+08:00||;True|2026-09-21T14:16:35.3194409+08:00||;True|2026-09-21T13:54:58.2829712+08:00||;True|2026-09-21T13:36:45.3134499+08:00||;True|2026-09-19T09:48:52.0085130+08:00||;False|2026-09-19T09:47:56.1658214+08:00||;True|2026-09-17T18:50:15.9493380+08:00||;True|2026-09-17T18:11:11.5364547+08:00||;True|2026-09-17T18:07:27.7830758+08:00||;True|2026-09-17T17:58:16.5798560+08:00||;True|2026-09-17T15:37:30.9025614+08:00||;True|2026-09-17T15:25:46.9116292+08:00||;True|2026-09-17T15:05:18.6592403+08:00||;True|2026-09-17T14:57:28.7997437+08:00||;True|2026-09-17T14:36:00.6339386+08:00||;True|2026-09-17T13:56:43.2376873+08:00||;True|2026-09-16T13:56:51.8724546+08:00||;True|2026-09-15T20:44:46.6559899+08:00||;True|2026-09-13T19:02:59.5654245+08:00||;True|2026-09-10T09:14:56.2914193+08:00||;True|2026-09-09T16:40:16.6461154+08:00||;True|2026-09-08T13:55:23.1502435+08:00||;True|2026-09-08T08:04:53.4279263+08:00||;True|2026-09-07T08:48:17.4682304+08:00||;True|2026-09-04T14:39:08.7878670+08:00||;True|2026-09-04T14:35:48.2937877+08:00||;True|2026-09-04T11:45:16.1372876+08:00||;True|2026-09-04T11:42:59.9356436+08:00||;True|2026-09-03T16:05:52.5270232+08:00||;True|2026-09-03T14:52:56.8559144+08:00||;True|2026-09-02T11:08:23.8720038+08:00||;True|2026-09-02T10:58:16.8081797+08:00||;True|2026-08-26T13:34:12.3805892+08:00||;True|2026-08-25T08:31:30.7787234+08:00||;True|2026-08-20T13:10:46.4725468+08:00||;True|2026-08-20T13:10:28.3142576+08:00||;True|2026-08-19T16:10:27.3362887+08:00||;True|2026-08-19T16:01:12.6234971+08:00||;True|2026-08-19T15:42:46.6576265+08:00||;True|2026-08-19T13:39:59.9363522+08:00||;True|2026-08-19T13:36:53.0379313+08:00||;True|2026-08-19T13:31:36.0841398+08:00||;True|2026-08-19T11:44:37.5319626+08:00||;True|2026-08-19T09:36:45.6000047+08:00||;True|2026-08-19T09:34:36.8468631+08:00||;True|2026-08-19T08:35:41.2202300+08:00||;True|2026-08-18T16:20:59.0170916+08:00||;</History>
<History>True|2026-10-21T13:22:01.1456473Z||;True|2026-10-20T15:45:39.3393674+08:00||;True|2026-10-17T20:49:21.0401213+08:00||;True|2026-09-23T13:19:13.0148919+08:00||;True|2026-09-23T13:16:07.8584304+08:00||;True|2026-09-22T23:03:13.6509491+08:00||;True|2026-09-22T16:07:15.9177123+08:00||;True|2026-09-22T11:19:19.6087109+08:00||;True|2026-09-22T11:09:24.9165065+08:00||;True|2026-09-21T22:40:07.1232044+08:00||;True|2026-09-21T22:35:06.9446571+08:00||;True|2026-09-21T22:27:42.1146825+08:00||;False|2026-09-21T22:27:17.6066573+08:00||;True|2026-09-21T21:01:22.8888913+08:00||;True|2026-09-21T19:15:03.4753747+08:00||;True|2026-09-21T18:08:30.0866986+08:00||;True|2026-09-21T16:51:19.8137872+08:00||;True|2026-09-21T16:30:01.0950896+08:00||;True|2026-09-21T15:09:00.2326737+08:00||;True|2026-09-21T14:47:09.6120256+08:00||;True|2026-09-21T14:16:35.3194409+08:00||;True|2026-09-21T13:54:58.2829712+08:00||;True|2026-09-21T13:36:45.3134499+08:00||;True|2026-09-19T09:48:52.0085130+08:00||;False|2026-09-19T09:47:56.1658214+08:00||;True|2026-09-17T18:50:15.9493380+08:00||;True|2026-09-17T18:11:11.5364547+08:00||;True|2026-09-17T18:07:27.7830758+08:00||;True|2026-09-17T17:58:16.5798560+08:00||;True|2026-09-17T15:37:30.9025614+08:00||;True|2026-09-17T15:25:46.9116292+08:00||;True|2026-09-17T15:05:18.6592403+08:00||;True|2026-09-17T14:57:28.7997437+08:00||;True|2026-09-17T14:36:00.6339386+08:00||;True|2026-09-17T13:56:43.2376873+08:00||;True|2026-09-16T13:56:51.8724546+08:00||;True|2026-09-15T20:44:46.6559899+08:00||;True|2026-09-13T19:02:59.5654245+08:00||;True|2026-09-10T09:14:56.2914193+08:00||;True|2026-09-09T16:40:16.6461154+08:00||;True|2026-09-08T13:55:23.1502435+08:00||;True|2026-09-08T08:04:53.4279263+08:00||;True|2026-09-07T08:48:17.4682304+08:00||;True|2026-09-04T14:39:08.7878670+08:00||;True|2026-09-04T14:35:48.2937877+08:00||;True|2026-09-04T11:45:16.1372876+08:00||;True|2026-09-04T11:42:59.9356436+08:00||;True|2026-09-03T16:05:52.5270232+08:00||;True|2026-09-03T14:52:56.8559144+08:00||;True|2026-09-02T11:08:23.8720038+08:00||;True|2026-09-02T10:58:16.8081797+08:00||;True|2026-08-26T13:34:12.3805892+08:00||;True|2026-08-25T08:31:30.7787234+08:00||;True|2026-08-20T13:10:46.4725468+08:00||;True|2026-08-20T13:10:28.3142576+08:00||;True|2026-08-19T16:10:27.3362887+08:00||;True|2026-08-19T16:01:12.6234971+08:00||;True|2026-08-19T15:42:46.6576265+08:00||;True|2026-08-19T13:39:59.9363522+08:00||;True|2026-08-19T13:36:53.0379313+08:00||;True|2026-08-19T13:31:36.0841398+08:00||;True|2026-08-19T11:44:37.5319626+08:00||;True|2026-08-19T09:36:45.6000047+08:00||;True|2026-08-19T09:34:36.8468631+08:00||;True|2026-08-19T08:35:41.2202300+08:00||;True|2026-08-18T16:20:59.0170916+08:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>
@@ -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;
@@ -109,9 +109,9 @@ function onThumbError(row: FileItem): void {
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>
@@ -149,12 +149,13 @@ function thumbSrcOf(row: FileItem): string {
<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 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)" />
<!-- 缩略图:图片走 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>
@@ -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>