修改完成待测试

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
+145 -8
View File
@@ -32,7 +32,7 @@
<view>
<text class="publish-field__label">动态配图</text>
<text class="publish-field__hint"
>图片上传成功后会随动态一起发布</text
>{{ isEdit ? "可新增、预览或移除图片,保存后生效。" : "图片上传成功后会随动态一起发布。" }}</text
>
</view>
<button
@@ -42,12 +42,49 @@
>
{{ isUploading ? "上传中…" : "添加图片" }}
</button>
<text
v-for="(receipt, index) in mediaReceipts"
:key="`${receipt.ossId}-${index}`"
class="upload-receipt"
>已上传{{ receipt.fileName || "图片" }}</text
>
<template v-if="isEdit">
<view v-if="mediaReceipts.length" class="media-preview-grid">
<view
v-for="(receipt, index) in mediaReceipts"
:key="`${receipt.ossId}-${index}`"
class="media-preview-card"
>
<button
class="media-preview-card__preview"
:disabled="isUploading || isSubmitting || !getMediaPreviewUrl(receipt)"
:aria-label="`预览第${index + 1}张动态配图`"
@click="previewMedia(receipt)"
>
<image
v-if="getMediaPreviewUrl(receipt)"
class="media-preview-card__image"
:src="getMediaPreviewUrl(receipt)"
mode="aspectFill"
/>
<view v-else class="media-preview-card__fallback">
<text>图片暂不可预览</text>
</view>
</button>
<view class="media-preview-card__meta">
<text>{{ receipt.fileName || `动态配图${index + 1}` }}</text>
<button
class="media-preview-card__remove"
:disabled="isUploading || isSubmitting"
:aria-label="`移除第${index + 1}张动态配图`"
@click="removeMedia(index)"
>移除</button>
</view>
</view>
</view>
</template>
<template v-else>
<text
v-for="(receipt, index) in mediaReceipts"
:key="`${receipt.ossId}-${index}`"
class="upload-receipt"
>已上传{{ receipt.fileName || "图片" }}</text
>
</template>
<text v-if="uploadError" class="publish-error">{{
uploadError
}}</text>
@@ -204,6 +241,7 @@ const loadEditFeed = async (feedId) => {
mediaReceipts.value = detail.mediaFiles.map((file) => ({
ossId: file.ossId,
fileName: file.fileName,
accessUrl: file.accessUrl,
}));
editingFeed.value = {
id: detail.id,
@@ -254,6 +292,22 @@ const uploadImage = async () => {
}
};
const getMediaPreviewUrl = (receipt) =>
String(receipt?.thumbnailUrl || receipt?.accessUrl || receipt?.url || "").trim();
const previewMedia = (receipt) => {
const current = getMediaPreviewUrl(receipt);
if (!current) return;
const urls = mediaReceipts.value.map(getMediaPreviewUrl).filter(Boolean);
uni.previewImage({ current, urls });
};
const removeMedia = (index) => {
if (isUploading.value || isSubmitting.value || !Number.isInteger(index)) return;
mediaReceipts.value = mediaReceipts.value.filter((_, mediaIndex) => mediaIndex !== index);
uploadError.value = "";
};
const saveFeed = async () => {
if (isSubmitting.value || isUploading.value || !hasValidContext.value) return;
if (!form.feedContent.trim()) {
@@ -322,7 +376,7 @@ const requestBack = () =>
const returnToFamily = async () => {
const confirmed = isDirty.value ? await requestDiscardConfirmation() : true;
if (!confirmed) return false;
return returnTo("F01", { genealogyId: genealogyId.value });
return returnTo("F12", { genealogyId: genealogyId.value });
};
const handleResultAction = () => {
if (publishState.value === "success") {
@@ -474,6 +528,89 @@ onUnload(() => {
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.media-preview-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14rpx;
}
.media-preview-card {
min-width: 0;
overflow: hidden;
border: 1rpx solid rgba(128, 89, 49, 0.24);
border-radius: 10rpx;
background: rgba(255, 253, 248, 0.62);
}
.media-preview-card__preview {
display: block;
width: 100%;
height: 176rpx;
margin: 0;
padding: 0;
border: 0;
border-radius: 0;
background: rgba(128, 89, 49, 0.1);
line-height: 1;
}
.media-preview-card__preview::after,
.media-preview-card__remove::after {
border: 0;
}
.media-preview-card__preview:focus-visible,
.media-preview-card__remove:focus-visible {
outline: 2rpx solid $brand-red;
outline-offset: -2rpx;
}
.media-preview-card__preview:active:not([disabled]) {
background: rgba(128, 89, 49, 0.16);
}
.media-preview-card__preview[disabled],
.media-preview-card__remove[disabled] {
opacity: 0.55;
}
.media-preview-card__image,
.media-preview-card__fallback {
display: block;
width: 100%;
height: 100%;
}
.media-preview-card__fallback {
display: flex;
align-items: center;
justify-content: center;
color: $ink-muted;
font-size: clamp(12px, 19rpx, 15px);
}
.media-preview-card__meta {
display: flex;
min-height: 72rpx;
align-items: center;
gap: 8rpx;
padding: 6rpx 6rpx 6rpx 14rpx;
}
.media-preview-card__meta > text {
min-width: 0;
flex: 1;
overflow: hidden;
color: $ink-muted;
font-size: clamp(12px, 19rpx, 15px);
text-overflow: ellipsis;
white-space: nowrap;
}
.media-preview-card__remove {
min-width: var(--app-touch-min);
min-height: var(--app-touch-min);
margin: 0;
padding: 0 10rpx;
border: 0;
background: transparent;
color: $brand-red;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1;
white-space: nowrap;
}
.media-preview-card__remove:active:not([disabled]) {
background: rgba(159, 23, 15, 0.08);
}
.publish-placeholder {
color: #8e806e;
}