Commit 6ec18700 by 郑晓

Merge branch 'feat_group_booking_240731' into 'master'

Feat group booking 240731

See merge request !4
parents fb41884d d7f085a8
<template>
<view class="ShareCanvas">
<view class="canvas">
<canvas canvas-id="shareCanvas" />
</view>
</view>
</template>
<script>
export default {
name: 'ShareCanvas',
methods: {
// 文本2行换行与显示省略号
// 1、canvas对象 2、文本 3、X轴 4、Y轴 5、单行行高 6、文本的宽度
drawText(ctx, str, axisX, axisY, titleHeight, maxWidth, font = 14) {
// 字体
ctx.font = `normal 500 ${font}px sans-serif`
ctx.letterSpacing = '1px'
// 颜色
ctx.fillStyle = '#000000'
// 文本处理
const strArr = str.split('')
let row = []
let temp = ''
for (let i = 0; i < strArr.length; i++) {
if (ctx.measureText(temp).width < maxWidth) {
temp += strArr[i]
} else {
i-- // 这里添加了i-- 是为了防止字符丢失,效果图中有对比
row.push(temp)
temp = ''
}
}
row.push(temp) // row有多少项则就有多少行
// 如果数组长度大于2,现在只需要显示两行则只截取前两项,把第二行结尾设置成'...'
if (row.length > 2) {
const rowCut = row.slice(0, 2)
const rowPart = rowCut[1]
let test = ''
const empty = []
for (let i = 0; i < rowPart.length; i++) {
if (ctx.measureText(test).width < maxWidth) {
test += rowPart[i]
} else {
break
}
}
empty.push(test)
const group = empty[0].slice(0, -1) + '...' // 这里只显示两行,超出的用...表示
console.log('🚀 ~ drawText ~ group:', group)
rowCut.splice(1, 1, group)
row = rowCut
console.log('🚀 ~ drawText ~ row:', row)
}
// 把文本绘制到画布中
for (let i = 0; i < row.length; i++) {
// 一次渲染一行
ctx.fillText(row[i], axisX, axisY + i * titleHeight, maxWidth)
}
},
calcContainScale(w, h, cw, ch) {
const scaleW = cw / w
const scaleH = ch / h
const scale = Math.max(scaleW, scaleH) // 取大值
return scale
},
calcPos(w, h, cw, ch) {
return {
x: (cw - w) / 2,
y: (ch - h) / 2,
}
},
// 商品分享
setGoodsShareCanvas(info) {
console.log('商品分享--info', info)
return new Promise(async (resolve, reject) => {
try {
const ctx = uni.createCanvasContext('shareCanvas', this)
// 绘制背景图
// ctx.fillStyle = '#FF3E3E'
// ctx.fillRect(0, 0, 211, 170)
try {
const { path } = await this.getImge(info.cardBg)
ctx.drawImage(path, 0, 0, 211, 170)
} catch (error) {
console.error(error)
}
// 商品模块
ctx.save()
this.setRadius(ctx, 4, 8, 62, 195, 99)
ctx.fillStyle = '#ffffff'
ctx.fill()
ctx.restore()
// 商品图
ctx.save()
this.setRadius(ctx, 4, 13, 67, 73, 90)
ctx.fillStyle = '#E5E6EB'
ctx.fill()
ctx.clip() // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
try {
const { path, width, height } = await this.getImge(info.homeCover)
const scale = this.calcContainScale(width, height, 73, 90)
const w = width * scale // 图片缩放后的宽度
const h = height * scale // 图片缩放后的高度
const { x, y } = this.calcPos(w, h, 73, 90) // 顺便让图片居中
ctx.drawImage(path, x + 12, y + 66, w, h)
} catch (error) {
console.error(error)
}
ctx.restore()
ctx.save()
this.setRadius(ctx, 2, 15, 69, 31, 14)
ctx.fillStyle = '#FF644D'
ctx.fill()
ctx.restore()
ctx.font = '9px sans-serif'
ctx.textAlign = 'left'
ctx.fillStyle = '#ffffff'
ctx.fillText(`${info.requiredNum}人团`, 19, 80)
ctx.restore()
// 商品标题
this.drawText(ctx, info.title, 92, 82, 18, 106, 12)
ctx.restore()
// 已学人数
ctx.font = '10px sans-serif'
ctx.textAlign = 'left'
ctx.fillStyle = 'rgba(28,31,40, 0.4)'
ctx.fillText(`${info.applyNum}人已学`, 92, 118)
// 成团价
ctx.font = `normal bold 11px sans-serif`
ctx.textAlign = 'left'
ctx.fillStyle = '#FF5347'
ctx.fillText(`成团价 `, 92, 136)
// 成团价格
ctx.font = `normal bold 15px sans-serif`
ctx.textAlign = 'left'
ctx.fillStyle = '#FF5347'
ctx.fillText(${info.groupBuyingPrice}`, 127, 137)
// 单独购买价
ctx.font = `10px sans-serif`
ctx.textAlign = 'left'
ctx.fillStyle = '#999999'
ctx.fillText(`单独购买¥${info.salesPrice}`, 92, 153)
ctx.draw(false, () => {
uni.canvasToTempFilePath(
{
canvasId: 'shareCanvas',
success: res => {
return resolve(res.tempFilePath)
},
fail: function (error) {
console.log('fail----fail', error)
// TODO
return reject(error)
},
},
this,
)
})
} catch (error) {
uni.hideLoading()
console.log('画图失败error', error)
return reject(error)
}
})
},
/**
* 设置圆角矩形
*
* @param ctx 绘图上下文
* @param cornerRadius 圆角半径
* @param width 矩形宽度
* @param height 矩形高度
* @param x 矩形左上角的 x 坐标
* @param y 矩形左上角的 y 坐标
* @returns 无返回值
*/
setRadius(ctx, cornerRadius, x, y, width, height) {
// 开始绘制路径
ctx.beginPath()
// 绘制最左侧的圆角
ctx.arc(x + cornerRadius, y + cornerRadius, cornerRadius, Math.PI, Math.PI * 1.5)
// 绘制顶部边缘
ctx.moveTo(x + cornerRadius, y)
ctx.lineTo(x + width - cornerRadius, y)
ctx.lineTo(x + width, y + cornerRadius)
// 绘制最右侧的圆角
ctx.arc(x + width - cornerRadius, y + cornerRadius, cornerRadius, Math.PI * 1.5, Math.PI * 2)
// 绘制右侧边缘
ctx.lineTo(x + width, y + height - cornerRadius)
ctx.lineTo(x + width - cornerRadius, y + height)
// 绘制最下侧的圆角
ctx.arc(x + width - cornerRadius, y + height - cornerRadius, cornerRadius, 0, Math.PI * 0.5)
// 绘制底部边缘
ctx.lineTo(x + cornerRadius, y + height)
ctx.lineTo(x, y + height - cornerRadius)
// 绘制最左侧的圆角
ctx.arc(x + cornerRadius, y + height - cornerRadius, cornerRadius, Math.PI * 0.5, Math.PI)
// 绘制左侧边缘
ctx.lineTo(x, y + cornerRadius)
ctx.lineTo(x + cornerRadius, y)
// 闭合路径
ctx.closePath()
},
// 获取图片地址
getImge(path) {
// 利用promise异步转同步,否则可能显示不了~
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: path,
success: function (res) {
if (res && res.path) {
console.log('🚀 ~ returnnewPromise ~ res:', res)
resolve(res)
} else {
reject(false)
}
},
fail: function (res) {
reject(res)
},
})
})
},
getSales(sales) {
return sales >= 10000 ? sales / 10000 + 'w+' : sales
},
},
}
</script>
<style lang="less" scoped>
// 隐藏画布
.ShareCanvas {
position: absolute;
top: -200px;
z-index: -1;
opacity: 0;
.canvas canvas {
width: 211px;
height: 170px; // +16
}
}
</style>
......@@ -6,14 +6,14 @@ let h2Prefix
let ydlH5Prefix
if (isDevelopment) {
// 开发
// hostPrefix = 'https://testnewm.ydl.com'
// // hostPrefix = 'http://192.168.211.138'
// apiPrefix = 'https://testapi.ydl.com'
// // 开发
hostPrefix = 'https://testnewm.ydl.com'
// hostPrefix = 'http://192.168.211.138'
apiPrefix = 'https://testapi.ydl.com'
// 下云
hostPrefix = 'https://newm-test.ydl.com' // 下云
apiPrefix = 'https://api-test.ydl.com' // 下云
// hostPrefix = 'https://newm-test.ydl.com' // 下云
// apiPrefix = 'https://api-test.ydl.com' // 下云
h2Prefix = 'https://h2.yidianling.com'
ydlH5Prefix = 'https://testh5.ydl.com'
......
......@@ -74,6 +74,7 @@
<script>
import { hostPrefix } from '@/config'
import { setTrackData } from '@/utils/util'
import { ffrom } from '@/utils/enums'
export default {
name: 'MyPage',
......@@ -147,6 +148,9 @@ export default {
return ''
},
},
onShow() {
// this.getUserInfo()
},
mounted() {
// 页面访问埋点
setTrackData({
......@@ -161,8 +165,32 @@ export default {
},
],
})
// this.getUserInfo()
},
methods: {
// 获取个人信息
getUserInfo() {
if (this.$store.state.user.accessToken) {
const { uid, accessToken } = this.$store.state.user
console.log("🚀 ~ getUserInfo ~ uid:", uid)
this.$request.post(
`/login/v2/get_user_info`,
{
uid,
accessToken,
version: '',
},
{
headers: {
userPort: '1',
ffrom,
version: '',
},
},
)
}
},
// 菜单项的埋点
handleSendMenuTrackData(content) {
// setTrackData({
......
<template>
<view class="pay-page">
<div>正在支付中</div>
<view>正在支付中...</view>
</view>
</template>
......@@ -170,6 +170,7 @@ export default {
title: '支付失败',
icon: 'none',
})
uni.navigateBack()
},
})
},
......@@ -220,9 +221,10 @@ export default {
<style lang="less" scoped>
.pay-page {
padding: 10px 0;
padding: 30px 0;
height: 100%;
background: #f8f8f8;
overflow: auto;
text-align: center;
}
</style>
<template>
<view>
<web-view
v-if="!!loadUrl"
:src="loadUrl"
@onPostMessage="handlePostMessage"
@message="handleMessage"
></web-view>
<view>
<ShareCanvas ref="ShareCanvas" />
</view>
</view>
</template>
<script>
import { hostPrefix } from '@/config.js'
import { ffrom } from '@/utils/enums'
import ShareCanvas from '@/components/ShareCanvas'
export default {
name: 'WebPage',
components: {
ShareCanvas,
},
data() {
return {
loadUrl: '',
// 只用于页面第一次初始化的时候,只要加载页面数据一次,防止onShow时重复加载
isMountedPageLoaded: false,
options: {},
shareMessage: {},
}
},
onLoad(options) {
......@@ -56,9 +66,12 @@ export default {
}
},
// 分享给朋友
onShareAppMessage() {
const getDetailPageUrl = () => {
async onShareAppMessage() {
const getDetailPageUrl = (link = '') => {
let url = this.loadUrl
if (link) {
url = link
}
// 分享页面,去掉登陆信息
const query = {
accessToken: '',
......@@ -67,15 +80,48 @@ export default {
}
// 更新 url 中的参数
Object.keys(query).forEach(prop => {
url = this.changeURLArg(this.loadUrl, prop, query[prop])
url = this.changeURLArg(url, prop, query[prop])
})
url = `/pages/web/web?loadUrl=${encodeURIComponent(url)}`
return url
}
// 课程详情页面
if (this.loadUrl.includes('h5-course/detail')) {
// 拼团相关页面分享
if (
this.loadUrl.includes('h5-course/detail') ||
this.loadUrl.includes('h5-course/my/components/Buylist') ||
this.loadUrl.includes('h5-course/pay/groupSuccess') ||
this.loadUrl.includes('/h5-course/my/orderDetail/')
) {
if (this.shareMessage.share) {
try {
const courseDetail = this.shareMessage.share
uni.showLoading({
title: '正在唤起分享',
})
const imageUrl = await this.$refs.ShareCanvas.setGoodsShareCanvas({
homeCover: courseDetail.homeCover,
cardBg: 'https://static.ydlcdn.com/m/images/course/miniapp-share-bg.png',
title: courseDetail.title || '',
groupBuyingPrice: courseDetail.groupBuyingPrice,
salesPrice: courseDetail.salesPrice,
applyNum: courseDetail.applyNum,
requiredNum: courseDetail.groupBuyingDesc ? parseInt(courseDetail.groupBuyingDesc) : 0,
})
uni.hideLoading()
console.log(getDetailPageUrl(this.shareMessage.share_url))
return {
title: `我参与了「精品心理课程」拼团活动,快来组团一起学习吧👇`,
imageUrl: imageUrl,
path: getDetailPageUrl(this.shareMessage.share_url),
}
} catch (error) {
console.log("🚀 ~ onShareAppMessage ~ error:", error)
uni.hideLoading()
}
}
return {
title: `课程详情`,
imageUrl: this.shareMessage.imageUrl,
path: getDetailPageUrl(),
}
}
......@@ -83,14 +129,24 @@ export default {
computed: {
// 课程详情页需要回退后,刷新
isNeedLoadPageOnShow() {
return this.loadUrl && this.loadUrl.includes('h5-course/detail')
return (
this.loadUrl &&
(this.loadUrl.includes('h5-course/detail') ||
this.loadUrl.includes('h5-course/pay/groupSuccess'))
)
},
},
watch: {
loadUrl: {
handler(url) {
// 课程详情时不隐藏,其他都隐藏
if (url && url.includes('h5-course/detail')) {
const whiteMap = [
'/h5-course/my/orderDetail/',
'h5-course/detail',
'h5-course/my/components/Buylist',
'h5-course/pay/groupSuccess',
]
// 判断 url 是都包含whiteMap数组中的字符串
if (whiteMap.some(item => url.includes(item))) {
return
}
uni.hideShareMenu()
......@@ -163,8 +219,9 @@ export default {
.finally(() => (this.loading = false))
if (res) {
// `${hostPrefix}/h5-course/pay/groupSuccess?replace=1&courseId=${res.productId}&groupRecordId=${res.recordId}`
// https://testnewm.ydl.com/h5-course/detail/7529
const url = `${hostPrefix}/h5-course/detail/${res.productId}`
const url = `${hostPrefix}/h5-course/pay/groupSuccess?replace=1&courseId=${res.productId}&groupRecordId=${res.recordId}`
// productId 商品id
// activityId 拼团活动id
......@@ -208,11 +265,13 @@ export default {
},
// webview向外部发送消息
handlePostMessage: function (data) {
console.log('🚀 ~ data:', data)
console.log('接收到消息:' + JSON.stringify(data.detail))
},
// webview向外部发送消息
handleMessage: function (data) {
console.log('接收到消息22 Message:' + JSON.stringify(data.detail))
this.shareMessage = data.detail.data[data.detail.data.length - 1]
},
// 更新 url 中的参数
changeURLArg(url, arg, value) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment