From 9043f7600dd71fd0d84dcf8a7a326873dda361bd Mon Sep 17 00:00:00 2001 From: Timi Date: Tue, 1 Sep 2026 14:07:23 +0800 Subject: [PATCH] fix store diary style --- src/components/PhotoScroller.vue | 4 + src/pages/notify/NotifyCreate.vue | 5 + src/pages/store/StoreDiaryDetail.vue | 32 ++++- src/pages/store/StoreDiaryEdit.vue | 134 ++++++++++++++++-- src/pages/store/StoreDiaryList.vue | 97 ++++++------- .../store/component/StoreDiaryListItem.vue | 107 ++++++++++++++ 6 files changed, 314 insertions(+), 65 deletions(-) create mode 100644 src/pages/store/component/StoreDiaryListItem.vue diff --git a/src/components/PhotoScroller.vue b/src/components/PhotoScroller.vue index 967a16c..b453ecc 100644 --- a/src/components/PhotoScroller.vue +++ b/src/components/PhotoScroller.vue @@ -22,6 +22,7 @@ />
@@ -165,6 +166,7 @@ interface Props { showViewerActions?: boolean; showAdd?: boolean; showRemove?: boolean; + showTypeLabel?: boolean; submit?: (photoItems: PhotoItem[]) => Promise; title?: string; } @@ -181,6 +183,7 @@ type ViewerPhotoItem = PhotoItem & { }; const ATTACH_TYPE_TEXT_MAP: Record = { + ADDITIONAL: "附加照片", PHOTO: "照片", POINT_CARD: "积分卡", OTHER: "其他文件" @@ -196,6 +199,7 @@ const props = withDefaults(defineProps(), { required: false, showAdd: true, showRemove: true, + showTypeLabel: true, showViewerActions: true }); diff --git a/src/pages/notify/NotifyCreate.vue b/src/pages/notify/NotifyCreate.vue index 5e92e1e..73741d5 100644 --- a/src/pages/notify/NotifyCreate.vue +++ b/src/pages/notify/NotifyCreate.vue @@ -423,7 +423,12 @@ onUnmounted(() => navBarStore.clearRight()); } :deep(.content) { + padding: 0; overflow: visible; + + .value { + border-radius: 0; + } } :deep(.toolbar) { diff --git a/src/pages/store/StoreDiaryDetail.vue b/src/pages/store/StoreDiaryDetail.vue index ee95a23..2a6dbe8 100644 --- a/src/pages/store/StoreDiaryDetail.vue +++ b/src/pages/store/StoreDiaryDetail.vue @@ -11,6 +11,18 @@ underline /> +
+ +
(() => (article.value?.attachmentList || []) + .filter(item => item.attachType === "ADDITIONAL" && !!item.id) + .map(item => ({ + attachment: item as Partial, + attachType: "ADDITIONAL", + previewUrl: getAttachmentReadURL(item.id || ""), + url: getAttachmentReadURL(item.id || "", 90) + }))); +const additionalPhotoList = computed(() => additionalPhotoItemList.value.map(item => item.url)); + function resolveAttachmentUrl(attachmentId: string): string { return getAttachmentReadURL(attachmentId); } @@ -222,6 +246,12 @@ onUnmounted(() => navBarStore.clearRight()); } } + .additional-photos-wrapper { + margin: 1rem 1rem 0 1rem; + border-bottom: 1px solid rgba(148, 163, 184, .2); + padding-bottom: 1rem; + } + .content { padding: 1rem; diff --git a/src/pages/store/StoreDiaryEdit.vue b/src/pages/store/StoreDiaryEdit.vue index 4106e19..6573607 100644 --- a/src/pages/store/StoreDiaryEdit.vue +++ b/src/pages/store/StoreDiaryEdit.vue @@ -21,6 +21,26 @@ placeholder="可填写本篇日记摘要" /> +
+ + +
(); +const photoItemList = ref([]); +const isPhotoUploading = ref(false); +const photoList = computed({ + get: () => photoItemList.value.map(item => item.url), + set: value => { + const urlSet = new Set(value); + photoItemList.value = photoItemList.value.filter(item => urlSet.has(item.url)); + } +}); + +function openPhotoPicker(): void { + photoInputRef.value?.click(); +} + +async function handlePhotoSelected(event: Event): Promise { + const input = event.target as HTMLInputElement; + const fileList = Array.from(input.files || []); + if (!fileList.length) { + return; + } + + isPhotoUploading.value = true; + try { + const tempFileList = await AttachmentAPI.upload(await compressUploadImageList(fileList)); + for (const tempFile of tempFileList) { + if (!tempFile.id) { + continue; + } + photoItemList.value.push({ + tempFileId: tempFile.id, + attachType: "ADDITIONAL", + url: AttachmentAPI.getTempReadURL(tempFile.id) + }); + } + } catch (error) { + Message.error(getErrorMessage(error, "附加照片上传失败")); + } finally { + isPhotoUploading.value = false; + input.value = ""; + } +} + +function buildPhotoItemList(attachmentList?: StoreDiary["attachmentList"]): PhotoItem[] { + return (attachmentList || []).flatMap(item => { + if (item.attachType !== "ADDITIONAL" || !item.id) { + return []; + } + return [{ + attachment: item as Partial, + attachType: "ADDITIONAL", + previewUrl: getAttachmentReadURL(item.id), + url: getAttachmentReadURL(item.id, 90) + }]; + }); +} + +function buildAdditionalAttachmentList(): Attachment[] { + return photoItemList.value.flatMap(item => { + if (item.attachment) { + return [{ + ...item.attachment, + attachType: "ADDITIONAL" + }]; + } + if (item.tempFileId) { + return [{ + attachType: "ADDITIONAL", + tempFileId: item.tempFileId + }]; + } + return []; + }); +} + const selectedStoreName = computed(() => { const store = currentStoreStore.storeList.find(item => item.id === article.value.bizId) || (currentStoreStore.loginStore?.id === article.value.bizId ? currentStoreStore.loginStore : undefined); @@ -187,7 +286,10 @@ async function save(): Promise { description: article.value.description?.trim() || "", contentType: normalizeContentType(editorValue?.contentType ?? article.value.contentType), content: editorValue?.content ?? article.value.content ?? "", - attachmentList: editorValue?.attachmentList ?? article.value.attachmentList ?? [], + attachmentList: [ + ...(editorValue?.attachmentList ?? article.value.attachmentList ?? []).filter(item => item.attachType !== "ADDITIONAL"), + ...buildAdditionalAttachmentList() + ], status: article.value.status || "NORMAL" }; if (!validateArticle(value)) { @@ -234,6 +336,7 @@ async function loadArticle(): Promise { ...createEmptyArticle(), bizId: article.value.bizId || currentStoreStore.currentStoreId }; + photoItemList.value = []; return; } @@ -246,6 +349,7 @@ async function loadArticle(): Promise { content: result.content || "", attachmentList: result.attachmentList || [] }; + photoItemList.value = buildPhotoItemList(result.attachmentList); } onMounted(async () => { @@ -278,9 +382,10 @@ onUnmounted(() => navBarStore.clearRight()); .editor-wrapper { width: 100%; + overflow: visible; min-width: 0; max-width: 100%; - overflow: visible; + border-top: 1px solid var(--td-component-border); .editor { width: 100%; @@ -292,23 +397,28 @@ onUnmounted(() => navBarStore.clearRight()); :deep(.tp-editor) { width: 100%; + height: auto; min-width: 0; max-width: 100%; - height: auto; overflow: visible; } :deep(.content) { + padding: 0; overflow: visible; + + .value { + border-radius: 0; + } } :deep(.toolbar) { - width: 100%; - min-width: 0; - max-width: 100%; top: var(--app-nav-height); + width: 100%; z-index: 10; position: sticky; + min-width: 0; + max-width: 100%; } :deep(.toolbar .scroll) { @@ -317,6 +427,14 @@ onUnmounted(() => navBarStore.clearRight()); max-width: 100%; } } + + .photo-wrapper { + padding: 1rem; + + .file-input { + display: none; + } + } } } diff --git a/src/pages/store/StoreDiaryList.vue b/src/pages/store/StoreDiaryList.vue index 5349c90..5f5ff70 100644 --- a/src/pages/store/StoreDiaryList.vue +++ b/src/pages/store/StoreDiaryList.vue @@ -12,6 +12,7 @@ :key="calendarRenderKey" class="calendar-view" :value="selectedCalendarDate" + :min-date="calendarMinDate" :format="calendarFormat" switch-mode="month" :use-popup="false" @@ -26,17 +27,7 @@ class="item" v-entrance-transition="index * 30" > - - - +