From dcf67dedfca4fa7be8715378df9fc5ba8aee49a8 Mon Sep 17 00:00:00 2001 From: duanshuwen Date: Thu, 16 Jul 2026 11:25:39 +0800 Subject: [PATCH] feat(aigc/detail): add share preview popup create reusable SharePreviewPopup component for share preview update ResultActions to emit share event instead of direct native share add share preview flow in aigc detail page update native share config with correct image and fallback title --- .../detail/components/ResultActions/index.vue | 4 +- .../components/SharePreviewPopup/index.vue | 99 +++++++++ .../SharePreviewPopup/styles/index.scss | 200 ++++++++++++++++++ src/pages-aigc/detail/detail.vue | 19 +- 4 files changed, 316 insertions(+), 6 deletions(-) create mode 100644 src/pages-aigc/detail/components/SharePreviewPopup/index.vue create mode 100644 src/pages-aigc/detail/components/SharePreviewPopup/styles/index.scss diff --git a/src/pages-aigc/detail/components/ResultActions/index.vue b/src/pages-aigc/detail/components/ResultActions/index.vue index f2c21b7..331804f 100644 --- a/src/pages-aigc/detail/components/ResultActions/index.vue +++ b/src/pages-aigc/detail/components/ResultActions/index.vue @@ -4,7 +4,7 @@ {{ saving ? "保存中..." : "保存图片" }} - + @@ -16,7 +16,7 @@ const props = defineProps({ }, }); -const emit = defineEmits(["save"]); +const emit = defineEmits(["save", "share"]); const handleSave = () => { if (!props.saving) { diff --git a/src/pages-aigc/detail/components/SharePreviewPopup/index.vue b/src/pages-aigc/detail/components/SharePreviewPopup/index.vue new file mode 100644 index 0000000..75c9809 --- /dev/null +++ b/src/pages-aigc/detail/components/SharePreviewPopup/index.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/pages-aigc/detail/components/SharePreviewPopup/styles/index.scss b/src/pages-aigc/detail/components/SharePreviewPopup/styles/index.scss new file mode 100644 index 0000000..7232426 --- /dev/null +++ b/src/pages-aigc/detail/components/SharePreviewPopup/styles/index.scss @@ -0,0 +1,200 @@ +.share-preview-popup { + width: calc(100vw - 28px); + max-width: 420px; + max-height: calc(100vh - 56px); + overflow-y: auto; + padding: 18px 16px 14px; + border: 1px solid rgba(73, 143, 205, 0.42); + border-radius: 20px; + background: + radial-gradient(90% 72% at 100% 0%, rgba(32, 207, 117, 0.15), rgba(32, 207, 117, 0) 60%), + linear-gradient(180deg, #dceeff 0%, #cfe7fb 100%); + box-shadow: 0 22px 54px rgba(16, 44, 73, 0.24); + box-sizing: border-box; +} + +.share-preview-badge, +.share-preview-heading, +.share-preview-title, +.share-preview-variant, +.share-preview-brand-name, +.share-preview-brand-type, +.share-preview-footer-label, +.share-preview-footer-action { + display: block; +} + +.share-preview-badge { + width: max-content; + margin: 0 auto; + padding: 3px 9px; + border-radius: 999px; + background: rgba(32, 207, 117, 0.13); + color: #0e9f61; + font-size: 10px; + line-height: 16px; + font-weight: 900; +} + +.share-preview-heading { + margin-top: 7px; + color: #173a5f; + font-size: 20px; + line-height: 26px; + font-weight: 900; + text-align: center; +} + +.share-preview-card { + margin-top: 12px; + overflow: hidden; + border: 1px solid rgba(73, 143, 205, 0.26); + border-radius: 12px; + background: rgba(255, 255, 255, 0.62); + box-shadow: 0 10px 24px rgba(23, 58, 95, 0.08); +} + +.share-preview-brand { + display: flex; + align-items: center; + gap: 10px; + padding: 12px 12px 7px; +} + +.share-preview-brand-mark { + flex: 0 0 30px; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background: #20cf75; + color: #173a5f; + font-size: 15px; + line-height: 30px; + font-weight: 900; +} + +.share-preview-brand-copy { + min-width: 0; +} + +.share-preview-brand-name { + overflow: hidden; + color: #173a5f; + font-size: 13px; + line-height: 18px; + font-weight: 900; + text-overflow: ellipsis; + white-space: nowrap; +} + +.share-preview-brand-type { + margin-top: 1px; + color: #6b8299; + font-size: 9px; + line-height: 12px; + font-weight: 700; +} + +.share-preview-title { + overflow: hidden; + padding: 4px 12px 0; + color: #172033; + font-size: 17px; + line-height: 23px; + font-weight: 900; + text-overflow: ellipsis; + white-space: nowrap; +} + +.share-preview-variant { + padding: 1px 12px 10px; + color: #4e7394; + font-size: 11px; + line-height: 16px; + font-weight: 800; +} + +.share-preview-image { + width: 100%; + height: 232px; + display: block; + background: #e8f2f8; +} + +.share-preview-image-placeholder { + display: flex; + align-items: center; + justify-content: center; + background: + radial-gradient(80% 85% at 50% 15%, rgba(32, 207, 117, 0.18), rgba(32, 207, 117, 0) 70%), + #e8f2f8; + color: #6b8299; + font-size: 13px; + line-height: 18px; + font-weight: 800; +} + +.share-preview-footer { + min-height: 40px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 0 12px; +} + +.share-preview-footer-label, +.share-preview-footer-action { + min-width: 0; + overflow: hidden; + color: #4e7394; + font-size: 10px; + line-height: 14px; + font-weight: 800; + text-overflow: ellipsis; + white-space: nowrap; +} + +.share-preview-footer-action { + flex: 0 0 auto; + color: #173a5f; +} + +.share-preview-share-button, +.share-preview-cancel-button { + width: 100%; + height: 44px; + margin: 12px 0 0; + padding: 0; + border: 0; + border-radius: 10px; + box-sizing: border-box; + font-size: 14px; + line-height: 44px; + font-weight: 900; + text-align: center; +} + +.share-preview-share-button { + background: #20cf75; + color: #ffffff; + box-shadow: 0 8px 18px rgba(32, 207, 117, 0.2); +} + +.share-preview-share-button::after { + border: 0; +} + +.share-preview-cancel-button { + margin-top: 8px; + background: rgba(255, 255, 255, 0.45); + color: #385875; +} + +.share-preview-share-button.is-pressed, +.share-preview-cancel-button.is-pressed { + opacity: 0.82; +} diff --git a/src/pages-aigc/detail/detail.vue b/src/pages-aigc/detail/detail.vue index 5442c39..44826a1 100644 --- a/src/pages-aigc/detail/detail.vue +++ b/src/pages-aigc/detail/detail.vue @@ -6,7 +6,7 @@ + +