修改完成待测试

This commit is contained in:
2026-09-13 17:45:47 +08:00
parent 9ad572907b
commit bbc024f7f2
80 changed files with 3844 additions and 1672 deletions
+62 -4
View File
@@ -129,6 +129,20 @@
<AppButton block label="发布视频" @click="openPublishForm" />
</view>
<view v-else class="video-card-list">
<BatchManagementBar
v-if="deletableVideos.length"
resource-name="视频"
:active="videoBatch.selectionMode.value"
:selected-count="videoBatch.selectedCount.value"
:all-selected="videoBatch.allSelected.value"
:busy="videoBatch.deleting.value"
@start="videoBatch.enterSelectionMode"
@finish="videoBatch.exitSelectionMode"
@toggle-all="videoBatch.toggleAll"
@delete="videoBatch.requestDelete"
/>
<text v-if="videoBatch.notice.value" class="batch-notice" role="status">{{ videoBatch.notice.value }}</text>
<text v-if="videoBatch.error.value" class="field-error" role="alert">{{ videoBatch.error.value }}</text>
<AppButton
block
type="secondary"
@@ -136,10 +150,16 @@
@click="openVerticalViewer(videos[0])"
/>
<view v-for="video in videos" :key="video.id" class="video-card">
<BatchSelectionMark
v-if="videoBatch.selectionMode.value && video.canDelete"
:selected="videoBatch.isSelected(video)"
:label="`视频:${video.title}`"
@toggle="videoBatch.toggleSelection(video)"
/>
<button
class="video-card__cover-action"
:aria-label="`播放${video.title}`"
@click="openVerticalViewer(video)"
@click="videoBatch.selectionMode.value && video.canDelete ? videoBatch.toggleSelection(video) : openVerticalViewer(video)"
>
<image
class="video-card__cover"
@@ -156,7 +176,7 @@
video.publishTime || "刚刚发布"
}}</text>
<view
v-if="video.canEdit || video.canDelete"
v-if="!videoBatch.selectionMode.value && (video.canEdit || video.canDelete)"
class="video-card__actions"
>
<AppButton
@@ -175,7 +195,7 @@
@click="requestDeleteVideo(video)"
/>
</view>
<view class="video-card__actions">
<view v-if="!videoBatch.selectionMode.value" class="video-card__actions">
<AppButton compact type="secondary" label="沉浸观看" @click="openVerticalViewer(video)" />
<AppButton compact type="secondary" :disabled="videoActionKey === `like-${video.id}`" :label="video.likedByCurrentUser ? `已赞 ${video.likeCount || 0}` : `点赞 ${video.likeCount || 0}`" @click="toggleVideoLike(video)" />
<AppButton compact type="secondary" :disabled="videoActionKey === `comments-${video.id}`" label="查看评论" @click="openVideoComments(video)" />
@@ -192,6 +212,18 @@
<AppButton block :label="stateCopy.action" @click="handleStateAction" />
</view>
</view>
<AppDialog
:visible="videoBatch.confirmationVisible.value"
eyebrow="批量删除"
title="将选中的视频移入回收站?"
:message="videoBatch.confirmationMessage.value"
:confirm-text="videoBatch.deleting.value ? '正在删除' : '移入回收站'"
cancel-text="继续选择"
show-cancel
:close-on-mask="false"
@confirm="videoBatch.confirmDelete"
@cancel="videoBatch.cancelDelete"
/>
<AppDialog
:visible="deleteConfirmVisible"
eyebrow="删除确认"
@@ -305,6 +337,8 @@ import { onBackPress, onLoad, onUnload } from "@dcloudio/uni-app";
import AppLoading from "@/components/AppLoading.vue";
import AppButton from "@/components/AppButton.vue";
import AppDialog from "@/components/AppDialog.vue";
import BatchManagementBar from "@/components/BatchManagementBar.vue";
import BatchSelectionMark from "@/components/BatchSelectionMark.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
import VerticalVideoViewer from "@/components/family/VerticalVideoViewer.vue";
@@ -315,6 +349,7 @@ import {
import { familyMediaApi } from "@/services/api/family-media-service.js";
import { genealogyCapabilityApi } from "@/services/api/genealogy-capability-service.js";
import { getRequestErrorMessage } from "@/services/api/request-error-message.js";
import { useBatchDeletion } from "@/composables/use-batch-deletion.js";
import {
isImagePickCancelled,
isVideoPickCancelled,
@@ -372,6 +407,19 @@ const discardConfirmation = createDiscardConfirmation((visible) => {
const confirmDiscard = discardConfirmation.confirm;
const cancelDiscard = discardConfirmation.cancel;
const hasValidContext = computed(() => /^[1-9]\d*$/.test(genealogyId.value));
const videoBatch = useBatchDeletion({
items: videos,
deleteOne: (video) =>
familyMediaApi.deleteVideo(genealogyId.value, video.id, {
requestController: videoDeletionRequestController,
}),
resourceName: "视频",
isActive: () => pageActive,
onEmpty: () => {
videoListState.value = "ready";
},
});
const deletableVideos = videoBatch.deletableItems;
const videoCommentPlaceholder = computed(() =>
replyTarget.value ? `回复 ${replyTarget.value.author}` : "说说你的看法",
);
@@ -599,6 +647,7 @@ const loadVideos = async () => {
});
if (!pageActive) return;
videos.value = videoRows;
videoBatch.exitSelectionMode();
videoListState.value = "ready";
} catch (error) {
if (!pageActive || isRequestCancelled(error)) return;
@@ -822,7 +871,7 @@ const submitVideo = async () => {
};
const returnToFamily = () =>
hasValidContext.value
? returnTo("F01", { genealogyId: genealogyId.value })
? returnTo("G05", { genealogyId: genealogyId.value })
: goBack();
const returnToVideoList = () => {
pageState.value = "list";
@@ -833,6 +882,15 @@ const returnToVideoList = () => {
return true;
};
const requestBack = async () => {
if (videoBatch.deleting.value) return true;
if (videoBatch.confirmationVisible.value) {
videoBatch.cancelDelete();
return true;
}
if (videoBatch.selectionMode.value) {
videoBatch.exitSelectionMode();
return true;
}
if (verticalViewerVisible.value) {
closeVerticalViewer();
return true;