shish 1 месяц назад
Родитель
Сommit
dd3d16e310

+ 1 - 1
ghsApp/src/admin/item/components/item-poster-popup.vue

@@ -5,7 +5,7 @@
 				<view class="poster-img-wrap">
 					<image class="poster-img" :src="posterUrl" mode="widthFix" show-menu-by-longpress />
 				</view>
-				<text class="poster-tip">长按图片可保存,或点击下方按钮</text>
+				<text class="poster-tip">长按图片可以转发或保存</text>
 				<view class="poster-actions">
 					<button class="admin-button-com big default poster-action-btn" @click="onClose">取消</button>
 					<button class="admin-button-com big blue poster-action-btn" @click="onSave">保存到相册</button>

+ 121 - 0
ghsApp/src/components/item-poster-popup.vue

@@ -0,0 +1,121 @@
+<template>
+	<uni-popup ref="posterPopup" background-color="transparent" type="top" :animation="true" class="poster-popup-root">
+		<view class="poster-popup-wrap">
+			<view class="poster-body">
+				<view class="poster-img-wrap">
+					<image class="poster-img" :src="posterUrl" mode="widthFix" show-menu-by-longpress />
+				</view>
+				<text class="poster-tip">长按图片可以转发或保存</text>
+				<view class="poster-actions">
+					<button class="admin-button-com big default poster-action-btn" @click="onClose">取消</button>
+					<button class="admin-button-com big blue poster-action-btn" @click="onSave">保存到相册</button>
+				</view>
+			</view>
+		</view>
+	</uni-popup>
+</template>
+
+<script>
+/**
+ * @description 通用海报预览与保存弹窗组件
+ * 职责:接收海报图片的临时/线上 URL,提供圆角海报的预览、长按保存、以及点击按钮保存到相册的功能。
+ */
+export default {
+	name: 'ItemPosterPopup',
+	props: {
+		posterUrl: {
+			type: String,
+			default: ''
+		}
+	},
+	methods: {
+		open() {
+			this.$refs.posterPopup.open('top')
+		},
+		close() {
+			this.$refs.posterPopup.close()
+		},
+		onClose() {
+			this.close()
+			this.$emit('close')
+		},
+		onSave() {
+			this.$emit('save')
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.poster-popup-root {
+	z-index: 999999;
+}
+
+::v-deep .uni-popup.top .uni-popup__wrapper {
+	width: 100% !important;
+	display: flex !important;
+	justify-content: center !important;
+	align-items: flex-start !important;
+}
+
+.poster-popup-wrap {
+	display: flex;
+	width: 100%;
+	padding: 20upx 0 36upx;
+	flex-direction: column;
+	align-items: stretch;
+	max-height: 92vh;
+	overflow: auto;
+	background: #fff;
+	border-radius: 0 0 24upx 24upx;
+	box-shadow: 0 16upx 48upx rgba(0, 0, 0, 0.18);
+	box-sizing: border-box;
+}
+
+.poster-body {
+	width: 100%;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+}
+
+.poster-img-wrap {
+	width: 100%;
+	display: flex;
+	justify-content: center;
+	padding: 0 28upx;
+	box-sizing: border-box;
+}
+
+.poster-img {
+	width: 100%;
+	max-width: 640upx;
+	border-radius: 12upx;
+	box-shadow: 0 8upx 24upx rgba(0, 0, 0, 0.12);
+}
+
+.poster-tip {
+	margin-top: 20upx;
+	font-size: 24upx;
+	color: #999;
+	text-align: center;
+}
+
+.poster-actions {
+	width: 100%;
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	margin-top: 28upx;
+	padding: 0 28upx;
+	box-sizing: border-box;
+}
+
+.poster-action-btn {
+	flex: 1;
+}
+
+.poster-action-btn + .poster-action-btn {
+	margin-left: 24upx;
+}
+</style>

+ 34 - 13
ghsApp/src/pagesClient/member/detail.vue

@@ -421,12 +421,16 @@
     <!-- 用于生成带支付宝背景和文字的结账二维码 -->
     <canvas canvas-id="shareCanvas" style="width: 360px; height: 490px; position: fixed; left: -9999px; top: -9999px; z-index: -1;"></canvas>
 
+    <!-- 支付宝结账海报弹窗 -->
+    <item-poster-popup ref="itemPosterPopup" :poster-url="posterUrl" @close="closePoster" @save="savePosterImg" />
+
   </view>
 </template>
 <script>
 import TuiListCell from '@/components/plugin/list-cell'
 import { share } from "@/mixins";
 import ModalModule from "@/components/plugin/modal"
+import ItemPosterPopup from '@/components/item-poster-popup.vue'
 import { getUserDet,debt} from "@/api/member";
 import { IMGHOST } from '@/config'
 import { mapGetters } from "vuex"
@@ -437,7 +441,7 @@ import { getAllWl } from "@/api/shop"
 export default {
   name: "detail",
   components: {
-    TuiListCell,ModalModule
+    TuiListCell,ModalModule,ItemPosterPopup
   },
   mixins: [share],
   props: {},
@@ -521,7 +525,8 @@ export default {
       title:'付款结账',
       needRefresh:0,
       allDist:[],
-      currentDist:{}
+      currentDist:{},
+      posterUrl: '' // 支付宝结账海报临时本地/线上链接
     };
   },
 	computed: {
@@ -611,6 +616,11 @@ export default {
      * @param {String} qrPath 二维码本地临时路径
      * 职责:通过 Canvas 绘制支付宝蓝色背景(带圆角剪裁)、白色圆角卡片、二维码图片、以及“推荐使用支付宝”、“支付宝扫一扫”等文字,最后导出并保存到用户相册。
      */
+    /**
+     * @description 使用 Canvas 绘制支付宝收款码海报并打开弹窗展示,不直接保存
+     * @param {String} qrPath 二维码本地临时路径
+     * 职责:通过 Canvas 绘制支付宝蓝色背景(带圆角剪裁)、白色圆角卡片、二维码图片、以及“推荐使用支付宝”、“扫一扫,向商家付款”等文字,最后导出并打开海报弹窗。
+     */
     drawAlipayPoster(qrPath) {
       const that = this
       const ctx = uni.createCanvasContext('shareCanvas', this)
@@ -679,7 +689,7 @@ export default {
       
       ctx.restore() // 恢复画布状态
 
-      // 8. 渲染并导出保存
+      // 8. 渲染并导出至临时路径,然后打开弹窗
       ctx.draw(false, () => {
         // 延迟 300ms 确保 Canvas 渲染引擎已完全绘制,防止部分平台导出空白图片
         setTimeout(() => {
@@ -689,16 +699,8 @@ export default {
             quality: 1,
             success: (res) => {
               uni.hideLoading()
-              // 保存图片到系统相册
-              uni.saveImageToPhotosAlbum({
-                filePath: res.tempFilePath,
-                success: () => {
-                  uni.showToast({ title: '保存成功', icon: 'success' })
-                },
-                fail: (err) => {
-                  uni.showToast({ title: '保存失败,请检查相册权限', icon: 'none' })
-                }
-              })
+              that.posterUrl = res.tempFilePath
+              that.$refs.itemPosterPopup.open()
             },
             fail: (err) => {
               uni.hideLoading()
@@ -707,6 +709,25 @@ export default {
           }, that)
         }, 300)
       })
+    },
+    closePoster() {
+      this.$refs.itemPosterPopup.close()
+    },
+    savePosterImg() {
+      const that = this
+      uni.showLoading({ title: '正在保存...', mask: true })
+      uni.saveImageToPhotosAlbum({
+        filePath: this.posterUrl,
+        success() {
+          uni.hideLoading()
+          that.$refs.itemPosterPopup.close()
+          uni.showToast({ title: '保存成功', icon: 'success' })
+        },
+        fail(err) {
+          uni.hideLoading()
+          uni.showToast({ title: '保存失败,请检查相册权限', icon: 'none' })
+        }
+      })
     },
 		inviteToPay(){
 			let that = this

+ 1 - 1
hdApp/src/components/item-poster-popup.vue

@@ -5,7 +5,7 @@
 				<view class="poster-img-wrap">
 					<image class="poster-img" :src="posterUrl" mode="widthFix" show-menu-by-longpress />
 				</view>
-				<text class="poster-tip">长按图片可保存,或点击下方按钮</text>
+				<text class="poster-tip">长按图片可以转发或保存</text>
 				<view class="poster-actions">
 					<button class="admin-button-com big default poster-action-btn" @click="onClose">取消</button>
 					<button class="admin-button-com big blue poster-action-btn" @click="onSave">保存到相册</button>