From 802290838fd05c7236dae780900b4bacb20c82df Mon Sep 17 00:00:00 2001 From: xuxueyang <xuxy@fengyuntec.com> Date: 星期五, 02 八月 2024 16:27:26 +0800 Subject: [PATCH] add 二维码格式 --- sub_pages/partner/partner-info/partner-code-v2.vue | 754 ++++++--------------------------------------------------- 1 files changed, 89 insertions(+), 665 deletions(-) diff --git a/sub_pages/partner/partner-info/partner-code-v2.vue b/sub_pages/partner/partner-info/partner-code-v2.vue index 9746ae6..c6d015e 100644 --- a/sub_pages/partner/partner-info/partner-code-v2.vue +++ b/sub_pages/partner/partner-info/partner-code-v2.vue @@ -1,688 +1,112 @@ <template> - <view class="product-detail-page"> - <scroll-view enable-back-to-top scroll-y="true" class="product-detail-page__scroll"> - <view class="product-detail-page__scroll__swiper" v-if="info.ImageUrlList&&info.ImageUrlList.length>0"> - <swiper @change="onSwiperChange" :current="currentIndex" class="product-detail-page__scroll__swiper__target"> - <swiper-item class="product-detail-page__scroll__swiper__target__item" v-for="(item,index) in info.ImageUrlList" - :key="index"> - <image mode="aspectFit" :src="item" class="product-detail-page__scroll__swiper__target__item__img" lazy-load></image> - </swiper-item> - </swiper> - <view class="product-detail-page__scroll__swiper__page">{{currentIndex+1}}/{{info.ImageUrlList.length}}</view> - <button v-if="info.Id" @click="shareDetail" class="evan-share"> - <image src="/static/images/common/share_icon.png" class="evan-share__icon"></image> - <view class="evan-share__text">分享</view> - </button> - </view> - <image v-else mode="aspectFill" class="product-detail-page__scroll__default-image" src="/static/images/common/default_image_horizontal.png"></image> - <view class="product-detail-page__scroll__info"> - <view class="product-detail-page__scroll__info__title">{{info.Name||''}}</view> - <view class="product-detail-page__scroll__info__desc">{{info.Introduction||''}}</view> - <!-- <view class="product-detail-page__scroll__info__bulter">管家提成比例:</view> --> - <view class="product-detail-page__scroll__info__tags"> - <view class="product-detail-page__scroll__info__tags__item" v-for="(item,index) in tags" :key="index"> - <image class="product-detail-page__scroll__info__tags__item__icon" :src="item.icon"></image> - <view class="product-detail-page__scroll__info__tags__item__text">{{item.text}}</view> - </view> - <view v-if="!isGroup" class="product-detail-page__scroll__info__tags__count">已售{{info.SaleCount||0}}</view> - </view> - </view> - <view class="product-detail-page__scroll__team" v-if="isGroup"> - <view class="product-detail-page__scroll__team__title">批购进度及商品价格区间</view> - <view class="product-detail-page__scroll__team__main"> - <view v-if="!info.GroupRules||info.GroupRules.length===0" class="product-detail-page__scroll__team__main__progress"></view> - <view v-else class="product-detail-page__scroll__team__main__progress"> - <view class="product-detail-page__scroll__team__main__progress__active" :style="{width:getPercent()+'rpx'}"></view> - </view> - <!-- <template v-if="info.GroupRules&&info.GroupRules.length>0"> - <view v-for="(item,index) in info.GroupRules" :key="index" class="product-detail-page__scroll__team__main__price" - :style="{top:'80rpx',left:`${630 * 0.8 / lastInfo.GroupCountStart * item.GroupCountStart}rpx`}"> - <view class="product-detail-page__scroll__team__main__price__line"></view> - <view class="product-detail-page__scroll__team__main__price__target">{{item.GroupCountStart}}件</view> - <view class="product-detail-page__scroll__team__main__price__target">{{item.Amount}}元</view> - </view> - </template> --> - <view v-if="!$utils.isTrueEmpty(info.GroupCount)" class="product-detail-page__scroll__team__main__price" :style="{bottom:'80rpx',left:getLeftValue()+'rpx'}"> - <view class="product-detail-page__scroll__team__main__price__current">已批{{info.GroupCount}}件</view> - <view class="product-detail-page__scroll__team__main__price__line current"></view> - </view> - </view> - </view> - <view class="product-detail-page__scroll__team-intro" v-if="isGroup"> - <view class="product-detail-page__scroll__team-intro__target">批购说明:参与购买的人数越多,商品价格越实惠</view> - <view class="product-detail-page__scroll__team-intro__target">根据批购最终参与购买的人数,来确定你需要支付的最终价格</view> - </view> - <view class="product-detail-page__scroll__desc"> - <view class="product-detail-page__scroll__desc__title">商品详情</view> - <u-parse :content="info.ProductDesc" /> - </view> - </scroll-view> - <view class="evan-buy-bottom"> - <view class="evan-buy-bottom__item evan-buy-bottom__item--left"> - <view class="evan-buy-bottom__item__price"> - <view v-if="isGroup||info.PayType===1" class="evan-buy-bottom__item__price__unit">¥</view> - <!-- <view class="evan-buy-bottom__item__price__current">{{showPrice}}</view> --> - <view v-if="!isGroup&&info.PayType===1&&info.MarketPrice" class="evan-buy-bottom__item__price__old">¥{{info.MarketPrice}}</view> - </view> - <view v-if="info.GiveAwayHuidouCount" class="evan-buy-bottom__item__tip">赠送{{info.GiveAwayHuidouCount}}汇豆</view> - </view> - <view @tap="buy" class="evan-buy-bottom__item evan-buy-bottom__item--right">立即购买</view> + <view> + <view class="button p-t-12 bg-white"> + <button :disabled="canvasImages == '' ? true : false" type="primary" @click="downloadImg">下载二维码</button> + <button :disabled="canvasImages != '' ? false : true" @click="previewHandle">预览二维码</button> + <!-- #ifdef MP-WEIXIN --> + <!-- <button type="warn" :disabled="canvasImages != '' ? false : true" open-type="share">分享给朋友</button> --> + <!-- #endif --> </view> - <hjg-spec @confirm="onSpecConfirm" :changeCount="!isNewUserProduct" :specs="info.SpecInfos" ref="spec"></hjg-spec> - <view @tap="hideBarcode" class="evan-poster__mask" :class="{hide:!showBarcode}" :style="{paddingTop:posterPadding}"> - <canvas class="evan-poster__mask__canvas" :style="{width:canvasWidth+'px',height:canvasHeight+'px'}" canvas-id="barcode"></canvas> - <view @tap.stop.prevent="stopPop" class="evan-poster__mask__bottom"> - <button open-type="share" class="evan-poster__mask__bottom__item"> - <view class="evan-poster__mask__bottom__item__text">分享好友</view> - </button> - <button @tap="saveToAlbum" class="evan-poster__mask__bottom__item"> - <view class="evan-poster__mask__bottom__item__text">保存海报</view> - </button> - </view> - </view> + <shareImages ref="canvas" :canvasWidth="canvasWidth" :canvasHeight="canvasHeight" :shareTitle="shareTitle" + :goodsTitle="goodsTitle" :shareImage="shareImage" :goodsTitle2="goodsTitle2" :qrSize="qrSize" :qrUrl="qrUrl" + @success="shareSuccess" :canvasID="canvasID"> + </shareImages> </view> </template> <script> - - import { - mapGetters, - mapState - } from 'vuex' - let ENV = 'prod' + import shareImages from '@/components/hj-placard/shareImages.vue' export default { components: { - - }, - computed: { - - + shareImages }, data() { return { - memberId: '', - headUrl: '', - nickName: '', - id: null, - info: {}, - currentIndex: 0, - tags: [{ - icon: '/static/images/home/qqzx.png', - text: '全球精品' - }, - { - icon: '/static/images/home/jyps.png', - text: '正品保证' - }, - { - icon: '/static/images/home/shwy.png', - text: '商品包邮' - } - ], - isGroup: false, - groupId: null, - canvasWidth: 242, - canvasHeight: 430, - showBarcode: false, - ratio: 430 / 1920, - posterPadding: 0, - filePath: '', - isNewUserProduct: false, - canBuy: false + name: '', + canvasID: "myQrcode", + canvasImages: '', + canvasWidth: 375, // 宽度 + canvasHeight: 650, // 高度 + shareTitle: '我是这张图片的标题', // 分享标题 + goodsTitle: '\n', // 商品宣传标题 + goodsTitle2: '', + shareImage: 'https://hmy-flower.oss-cn-shanghai.aliyuncs.com/d4/d43cdefc7b8f4c3e91fb451a236a4435WechatIMG2882.jpg', // 背景图片 + qrSize: 100, // 二维码大小 + qrUrl: 'http://www.hmyxianhua.com/wx/jump?partnerUserId=1&partnerUserName=', // 生成二维码的链接 } + }, + onLoad() { + if (!this.currentInfo.partnerDTO) { + this.$message.showToast('请先完善合伙人信息') + return + } + this.name = this.currentInfo.partnerDTO.name || '佚名' + this.qrUrl = + `http://www.hmyxianhua.com/wx/jump?partnerUserId=${this.currentInfo.id||'-'}&partnerUserName=${this.name||'-'}` + this.goodsTitle = `${this.name||'-'}的推广二维码` + this.goodsTitle2 = `扫码注册绑定合伙人` + this.$message.showLoading() + setTimeout(() => { + this.createsShareImage() + }, 500) + setTimeout(() => { + this.$message.hideLoading() + }, 2000) }, methods: { - async getDetail() { - // const { - // code, - // data - // } = await productService.getDetail(this.id) - // if (code === 0) { - // this.info = data - // this.isNewUserProduct = data.IsNewUserTopic === 1 + // 生成分享图片 + createsShareImage() { + // console.log(this.$refs.canvas) + this.$refs.canvas.canvasCreate(); + }, + // 预览图片 + previewHandle() { + uni.previewImage({ + urls: [this.canvasImages], + }); + }, + // 回调图片地址 + shareSuccess(e) { + // console.log('地址',e) + this.canvasImages = e + }, + downloadImg() { + // this.$refs.canvas.downloadImg(); + uni.saveImageToPhotosAlbum({ + filePath: this.canvasImages, + success: function() { + console.log('save success'); + uni.showToast({ + title: '保存成功' + }) + }, + fail(res) { + console.error(res) + uni.showToast({ + title: '保存失败。', + icon: 'error' + }) + } + }) + + + }, + // 分享 + onShareAppMessage(res) { + // if (res.from === 'button') { + // console.log(res.target) // } - }, - async getGroupDetail() { - const { - code, - data - } = await assembleService.getAssembleDetail(this.id, this.groupId) - if (code === 0) { - this.info = data + return { + title: `${this.name||'-'}的推广二维码`, + path: this.canvasImages } - }, - onSwiperChange(e) { - this.currentIndex = e.detail.current - }, - async buy() { - - }, - onSpecConfirm(e) { - let specList = [] - if (Array.isArray(e.specs)) { - specList = e.specs.map((item) => { - return { - SpecName: item.SpecName, - SpecValue: item.SpecValue - } - }) - } - let orderInfo = { - ProductId: this.info.Id, - ProductSpecList: specList, - ProductCount: e.count, - ProductSaleType: this.isGroup ? 2 : 1, - ProductPayType: this.isGroup ? 1 : this.info.PayType - } - if (this.isGroup) { - orderInfo.GroupId = this.groupId - orderInfo.BookAmount = this.info.BookAmount - } else { - if (orderInfo.ProductPayType === 1) { - orderInfo.SaleAmount = this.info.SalePrice - } else { - orderInfo.SaleAmount = this.info.HuidouCount - } - } - uni.navigateTo({ - url: `./order?orderInfo=${JSON.stringify(orderInfo)}` - }) - }, - getPercent() { - if (!this.info.GroupRules || this.info.GroupRules.length === 0) { - return 0 - } - if (this.info.GroupCount > this.info.GroupRules[this.info.GroupRules.length - 1].GroupCountStart) { - return 0.85 * 630 - } else { - return this.info.GroupCount / this.info.GroupRules[this.info.GroupRules.length - 1].GroupCountStart * - 0.8 * 630 - } - }, - getLeftValue() { - if (!this.info.GroupRules || this.info.GroupRules.length === 0) { - if (this.info.GroupCount === 0) { - return 0 - } else { - return 630 * 0.8 - } - } else { - if (this.info.GroupCount > this.info.GroupRules[this.info.GroupRules.length - 1].GroupCountStart) { - return 630 * 0.85 - } else { - return 630 * 0.8 / Math.max(this.info.GroupRules[this.info.GroupRules.length - 1].GroupCountStart / - this.info.GroupCount, 1) - } - } - }, - formatCanvasSize(size) { - return Math.floor(this.ratio * size) - }, - async shareDetail() { - if (this.memberId) { - // #ifdef MP-WEIXIN - let params = `id=${this.info.Id}` - if (this.isGroup) { - params += `&groupId=${this.groupId}` - } - if (this.memberId) { - params += `&inviteId=${this.memberId}` - } - const { - code: sceneCode, - data: sceneData - } = await commonService.saveScene(encodeURIComponent(params)) - if (sceneCode === 0) { - const { - code, - data - } = await commonService.getUnlimitedBarcode('pages/home/product/detail', `posterId=${sceneData}`) - if (code === 0) { - const fsm = wx.getFileSystemManager() - this.filePath = `${wx.env.USER_DATA_PATH}/barcode_tmp_${(new Date).getTime()}.png` - fsm.writeFile({ - filePath: this.filePath, - data: data, - encoding: 'binary', - success: async () => { - const context = uni.createCanvasContext('barcode') - const headSize = this.formatCanvasSize(105) - const productSize = this.formatCanvasSize(540) - const canvasWidth = this.canvasWidth - const canvasHeight = this.canvasHeight - const headPath = await this.getImageInfo(this.headUrl) - const productPath = await this.getImageInfo(this.info.ImageUrlList[0]) - // 背景 - context.drawImage('/pages/home/static/images/sharebg.jpg', 0, 0, canvasWidth, - canvasHeight) - // 头像 - context.drawImage(headPath, this.formatCanvasSize(80), this.formatCanvasSize(70), headSize, headSize) - // 昵称 - context.font = `bold ${this.formatCanvasSize(40)}px system-ui` - context.setFillStyle('#000') - this.fillTextByLength(context, this.nickName, 20, this.formatCanvasSize(198), - this.formatCanvasSize(110)) - // 产品图 - context.drawImage(productPath, this.formatCanvasSize(260), this.formatCanvasSize(440), productSize, - productSize) - // 价格 - const priceWidth = this.formatCanvasSize(150) - const priceTop = this.formatCanvasSize(1240) - const priceLeft = this.formatCanvasSize(141) - // 当前价格 - if (this.showPrice) { - const price = (this.isGroup || this.info.PayType === 1) ? `¥${this.showPrice}` : this.showPrice - context.font = `bold ${this.formatCanvasSize(84)}px system-ui` - context.setFillStyle('#d92c21') - context.fillText(price, priceLeft, priceTop, priceWidth) - } - // 市场价格 - if (!this.isGroup && this.info.PayType === 1 && this.info.MarketPrice) { - context.font = `normal ${this.formatCanvasSize(54)}px system-ui` - context.setFillStyle('#61605e') - context.fillText(`¥${this.info.MarketPrice}`, priceLeft + priceWidth + 5, priceTop, priceWidth) - context.moveTo(priceLeft + priceWidth + 5, priceTop - this.formatCanvasSize(20)) - context.lineTo(priceLeft + priceWidth + 5 + context.measureText(`¥${this.info.MarketPrice}`).width + 2, - priceTop - this.formatCanvasSize(20)) - context.setStrokeStyle('#61605e') - context.stroke() - } - // 赠送汇豆 - if (this.info.GiveAwayHuidouCount) { - context.font = `normal ${this.formatCanvasSize(36)}px system-ui` - context.setFillStyle('#61605e') - context.fillText(`赠送${this.info.GiveAwayHuidouCount}汇豆`, priceLeft, priceTop + this.formatCanvasSize(36) + - 5, - priceWidth * 2) - } - // 商品名称 - let nameLeft = priceLeft + 2 * priceWidth + 10 - let nameTop = this.formatCanvasSize(1230) - context.font = `bold ${this.formatCanvasSize(50)}px system-ui` - context.setFillStyle('#000') - let nameWidth = 0 - // 换行次数 - let breakLineCount = 0 - for (let i = 0; i < this.info.Name.length; i++) { - const str = this.info.Name[i] - nameWidth += context.measureText(str).width - if (nameWidth > 80 && breakLineCount > 0) { - context.fillText('...', nameLeft, nameTop) - break - } - if (nameWidth > 90) { - nameTop += this.formatCanvasSize(74) - nameLeft = priceLeft + 2 * priceWidth + 10 - nameWidth = context.measureText(str).width - breakLineCount++ - } - context.fillText(str, nameLeft, nameTop) - nameLeft += context.measureText(str).width + 2 - } - // 二维码 - const barcodeSize = this.formatCanvasSize(250) - const barcodeLeft = this.formatCanvasSize(740) - const barcodeTop = this.formatCanvasSize(1500) - context.drawImage(this.filePath, barcodeLeft, barcodeTop, - barcodeSize, - barcodeSize) - this.showBarcode = true - this.$nextTick(() => { - context.draw(false, () => {}) - }) - }, - fail: (err) => { - this.$message.showToast('写入文件失败') - } - }) - } - } - // #endif - } else { - this.$message.confirm('登录后才能分享,是否立即登录?').then(() => { - uni.navigateTo({ - url: '/pages/account/login' - }) - }).catch(() => {}) - } - }, - fillTextSingleLine(context, text, maxLength, startLeft, startTop) { - let nameWidth = 0 - for (let i = 0; i < text.length; i++) { - const str = text[i] - nameWidth += context.measureText(str).width - if (nameWidth > maxLength - 10) { - context.fillText('...', startLeft, startTop) - break - } else { - context.fillText(str, startLeft, startTop) - startLeft += context.measureText(str).width + 2 - } - } - }, - fillTextByLength(context, text, len, startLeft, startTop) { - if (text.length > len - 3) { - text = text.substr(0, len - 3) + '...' - } - context.fillText(text, startLeft, startTop) - }, - getImageInfo(url) { - if (ENV === 'prod') { - url = url.replace(/http:\/\//g, 'https://') - } - return new Promise((resolve, reject) => { - uni.getImageInfo({ - src: url, - success: (res) => { - resolve(res.path) - }, - fail: (e) => { - reject(e) - } - }) - }) - }, - saveToAlbum() { - uni.canvasToTempFilePath({ - x: 0, - y: 0, - width: this.canvasWidth, - height: this.canvasHeight, - canvasId: 'barcode', - success: (res) => { - uni.saveImageToPhotosAlbum({ - filePath: res.tempFilePath, - success: () => { - this.$message.showToast('已为您保存至相册') - } - }) - } - }) - }, - hideBarcode() { - this.showBarcode = false - if (this.filePath) { - const fsm = wx.getFileSystemManager() - fsm.unlink({ - filePath: this.filePath, - success: () => { - this.filePath = '' - } - }) - } - }, - stopPop() { - // do nothing - }, - async getScene(id) { - const { - code, - data - } = await commonService.getScene(id) - if (code === 0) { - const productId = this.$utils.getBarcodeQueryString(data, 'id') - const inviteId = this.$utils.getBarcodeQueryString(data, 'inviteId') - const groupId = this.$utils.getBarcodeQueryString(data, 'groupId') - if (productId) { - this.id = productId - if (inviteId) { - this.$store.commit('account/SET_INVITEID', inviteId) - } - if (groupId) { - this.isGroup = true - this.groupId = groupId - this.getGroupDetail() - } else { - this.getDetail() - } - } - } - }, - setPosterPadding() { - const windowHeight = uni.getSystemInfoSync().windowHeight - this.posterPadding = (windowHeight - 126 - this.canvasHeight) / 2 + 'px' - } - }, - async onLoad(options) { - this.setPosterPadding() - this.id = options.id || '' - }, - onUnload() { - }, - onShareAppMessage() { - let params = `id=${this.info.Id}` - if (this.isGroup) { - params += `&groupId=${this.groupId}` - } - if (this.memberId) { - params += `&inviteId=${this.memberId}` - } - let path = `/pages/home/product/detail?${params}` - return { - title: this.info.Name, - path: path } } } </script> -<style lang="scss"> - .product-detail-page { - height: 100%; +<style scoped> + .button { display: flex; - flex-direction: column; - - &__scroll { - flex: 1; - overflow: auto; - - &__swiper { - position: relative; - width: 100%; - height: 446rpx; - background-color: #fff; - - &__target { - height: 100%; - - &__item { - display: flex; - align-items: center; - justify-content: center; - - &__img { - width: 400rpx; - height: 400rpx; - } - } - } - - &__page { - position: absolute; - bottom: 14rpx; - right: 40rpx; - height: 40rpx; - border-radius: 20rpx; - background-color: rgba(0, 0, 0, 0.6); - padding: 0 14rpx; - font-size: 28rpx; - color: #fff; - } - } - - &__default-image { - width: 100%; - height: 446rpx; - } - - &__info { - background-color: #fff; - padding: 18rpx 30rpx 28rpx 30rpx; - - &__title { - font-size: 32rpx; - color: #000; - font-weight: 500; - line-height: 44rpx; - margin-bottom: 14rpx; - } - - &__desc { - font-size: 28rpx; - color: #666; - line-height: 40rpx; - margin-bottom: 10rpx; - } - - &__bulter { - font-size: 28rpx; - color: #000; - line-height: 40rpx; - } - - &__tags { - display: flex; - align-items: center; - margin-top: 10rpx; - - &__item { - display: flex; - align-items: center; - margin-right: 44rpx; - - &__icon { - width: 28rpx; - height: 28rpx; - margin-right: 4rpx; - } - - &__text { - font-size: 24rpx; - color: #000; - } - } - - &__count { - flex: 1; - text-align: right; - font-size: 24rpx; - color: #666; - } - } - } - - &__desc { - padding: 30rpx; - background-color: #fff; - margin-top: 24rpx; - - &__title { - font-size: 36rpx; - color: #000; - font-weight: 500; - line-height: 50rpx; - margin-bottom: 26rpx; - } - } - - &__team { - background-color: #fff; - padding-bottom: 48rpx; - - &__title { - font-size: 28rpx; - color: #000; - padding: 0 30rpx; - font-weight: bold; - } - - &__main { - width: 750rpx; - padding: 60rpx 0; - position: relative; - display: flex; - justify-content: center; - - &__progress { - width: 630rpx; - height: 20rpx; - background-color: #d8d8d8; - border-radius: 16rpx; - - &__active { - height: 100%; - background-color: #d51d1d; - border-radius: 16rpx; - } - } - - &__price { - display: flex; - flex-direction: column; - align-items: center; - position: absolute; - min-width: 120rpx; - - &__line { - width: 2rpx; - height: 24rpx; - background-color: #979797; - - &.current { - background-color: #d51d1d; - } - } - - &__target { - font-size: 24rpx; - color: #000; - font-weight: bold; - } - - &__current { - font-size: 20rpx; - color: #d51d1d; - } - } - } - } - - &__team-intro { - padding: 8rpx 30rpx; - background-color: #EDE0CC; - margin-top: 24rpx; - - &__target { - font-size: 24rpx; - color: #9C753B; - font-weight: bold; - - &:not(:first-child) { - margin-top: 8rpx; - } - } - } - - &__team-info { - padding: 16rpx 30rpx 0 16rpx; - - &__line { - display: flex; - align-items: flex-start; - margin-bottom: 8rpx; - - &__label { - font-size: 28rpx; - color: #000; - } - - &__value { - font-size: 28rpx; - color: #000; - flex: 1; - } - } - } - } } -</style> +</style> \ No newline at end of file -- Gitblit v1.9.3