mirror of
https://gitee.com/ShopeX/ECShopX_mobile-frontend
synced 2026-08-12 22:35:37 +08:00
fix: 海报优化
This commit is contained in:
@@ -336,10 +336,10 @@ export default {
|
||||
'navigationBarTextStyle': 'black'
|
||||
},
|
||||
plugins: {
|
||||
'live-player-plugin': {
|
||||
'version': '1.3.0', // 注意填写该直播组件最新版本号,微信开发者工具调试时可获取最新版本号(复制时请去掉注释)
|
||||
'provider': 'wx2b03c6e691cd7370' // 必须填该直播组件appid,该示例值即为直播组件appid(复制时请去掉注释)
|
||||
}
|
||||
// 'live-player-plugin': {
|
||||
// 'version': '1.3.0', // 注意填写该直播组件最新版本号,微信开发者工具调试时可获取最新版本号(复制时请去掉注释)
|
||||
// 'provider': 'wx2b03c6e691cd7370' // 必须填该直播组件appid,该示例值即为直播组件appid(复制时请去掉注释)
|
||||
// }
|
||||
},
|
||||
requiredPrivateInfos: [
|
||||
"getLocation",
|
||||
|
||||
@@ -61,7 +61,7 @@ function SpAddress(props) {
|
||||
level
|
||||
}
|
||||
})
|
||||
console.log('resAddressList:', resAddressList, _areaList)
|
||||
// console.log('resAddressList:', resAddressList, _areaList)
|
||||
setState((draft) => {
|
||||
draft.addressList = resAddressList
|
||||
draft.areaList = _areaList
|
||||
@@ -123,7 +123,7 @@ function SpAddress(props) {
|
||||
console.log('pindex',pindex);
|
||||
console.log('selectValue',selectValue);
|
||||
console.log('areaList',areaList);
|
||||
|
||||
|
||||
return (
|
||||
<View className='sp-address'>
|
||||
<View className='address-content'></View>
|
||||
@@ -131,7 +131,7 @@ function SpAddress(props) {
|
||||
<View className='address-hd'>
|
||||
{selectValue.map((vitem, vindex) => (
|
||||
<View
|
||||
className={classNames(`tab-item`,
|
||||
className={classNames(`tab-item`,
|
||||
{
|
||||
active: pindex === vindex || vindex === 2 && pindex === 3
|
||||
})}
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
import Taro, { Component } from '@tarojs/taro'
|
||||
import api from '@/api'
|
||||
import { getExtConfigData, isAlipay } from '@/utils'
|
||||
import { drawText, drawImage, drawBlock } from './helper.alipay'
|
||||
import { drawText, drawImage, drawBlock } from './helper'
|
||||
// const canvasWidth = 750
|
||||
// const canvasHeight = 1335
|
||||
|
||||
|
||||
const UI_Width = 750
|
||||
//同步获取设备系统信息
|
||||
const info = Taro.getSystemInfoSync()
|
||||
//设备像素密度
|
||||
const dpr = info.pixelRatio;
|
||||
//计算比例
|
||||
const scale = info.screenWidth / UI_Width
|
||||
console.log('scale', scale)
|
||||
//计算canvas实际渲染尺寸
|
||||
let width = parseInt(scale * 335)
|
||||
let height = parseInt(scale * 596)
|
||||
//计算canvas画布尺寸
|
||||
let canvasWidth = width * dpr
|
||||
let canvasHeight = height * dpr
|
||||
|
||||
let alipayScaleW = 1.5
|
||||
let alipayScaleH = 1.2
|
||||
const canvasWidth = 600
|
||||
const canvasHeight = 960
|
||||
|
||||
class DistributionPoster {
|
||||
constructor(props) {
|
||||
const { ctx, info, userInfo, toPx, toRpx } = props
|
||||
this.ctx = ctx
|
||||
ctx.scale(dpr, dpr)
|
||||
this.info = info
|
||||
this.userInfo = userInfo
|
||||
this.toPx = toPx
|
||||
@@ -51,18 +35,15 @@ class DistributionPoster {
|
||||
const url = (isOpenShop && shop_status == 1) ? `marketing/pages/distribution/shop-home` : `pages/index`
|
||||
let wxappCode
|
||||
// TODO 获取微信二维码的接口,需要换alipay https://ecshopx1.shopex123.com/api/h5app/alipaymini/qrcode.png?company_id=1&page=page/index
|
||||
if(isAlipay){
|
||||
// const res = await api.alipay.alipay_qrcode(`page=${`pages/item/espier-detail`}&appid=${appid}&company_id=${company_id}&id=${itemId}&uid=${user_id}`)
|
||||
const res = await Taro.request({
|
||||
url: `${host}/api/h5app/alipaymini/qrcode.png?path=${url}&appid=${appid}&company_id=${company_id}&user_id=${user_id}`, //仅为示例,并非真实的接口地址
|
||||
header: {
|
||||
'content-type': 'application/json' // 默认值
|
||||
},
|
||||
})
|
||||
wxappCode = res.data.data.qr_code_url
|
||||
}else{
|
||||
wxappCode = `${process.env.APP_BASE_URL}/promoter/qrcode.png?path=${url}&appid=${appid}&company_id=${company_id}&user_id=${user_id}`
|
||||
}
|
||||
// const res = await api.alipay.alipay_qrcode(`page=${`pages/item/espier-detail`}&appid=${appid}&company_id=${company_id}&id=${itemId}&uid=${user_id}`)
|
||||
const res = await Taro.request({
|
||||
url: `${host}/api/h5app/alipaymini/qrcode.png?path=${url}&appid=${appid}&company_id=${company_id}&user_id=${user_id}`, //仅为示例,并非真实的接口地址
|
||||
header: {
|
||||
'content-type': 'application/json' // 默认值
|
||||
},
|
||||
})
|
||||
wxappCode = res.data.data.qr_code_url
|
||||
debugger
|
||||
|
||||
console.log('DistributionPoster-wxappCode:', wxappCode)
|
||||
|
||||
@@ -99,12 +80,12 @@ class DistributionPoster {
|
||||
imgPath: this.bkg.path,
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: isAlipay ? canvasWidth / alipayScaleW : canvasWidth,
|
||||
h: isAlipay ? canvasHeight / alipayScaleH : canvasHeight,
|
||||
w: canvasWidth,
|
||||
h: canvasHeight,
|
||||
sx: 0,
|
||||
sy: 0,
|
||||
sw: isAlipay ? this.bkg.width : this.bkg.width,
|
||||
sh: isAlipay ? this.bkg.height : this.bkg.height,
|
||||
sw: this.bkg.width,
|
||||
sh: this.bkg.height,
|
||||
// borderRadius: 80
|
||||
},
|
||||
drawOptions
|
||||
@@ -113,24 +94,24 @@ class DistributionPoster {
|
||||
drawImage(
|
||||
{
|
||||
imgPath: this.avatar.path,
|
||||
x: isAlipay ? 40 : 220,
|
||||
y: isAlipay ? 20 : 60,
|
||||
w: isAlipay ? 30 : 80,
|
||||
h: isAlipay ? 30 : 80,
|
||||
x: 145,
|
||||
y: 50,
|
||||
w: 80,
|
||||
h: 80,
|
||||
sx: 0,
|
||||
sy: 0,
|
||||
sw: isAlipay ? 30 : this.avatar.width,
|
||||
sh: isAlipay ? 30 : this.avatar.height,
|
||||
borderRadius: isAlipay ? 30 : 80
|
||||
sw: this.avatar.width,
|
||||
sh: this.avatar.height,
|
||||
borderRadius: 80
|
||||
},
|
||||
drawOptions
|
||||
)
|
||||
// 姓名
|
||||
drawText(
|
||||
{
|
||||
x: isAlipay ? 76 : 310,
|
||||
y: isAlipay ? 34 : 110,
|
||||
fontSize: isAlipay ? 10 : 30,
|
||||
x: 260,
|
||||
y: 100,
|
||||
fontSize: 30,
|
||||
color: '#000',
|
||||
text: username
|
||||
},
|
||||
@@ -140,14 +121,14 @@ class DistributionPoster {
|
||||
drawImage(
|
||||
{
|
||||
imgPath: this.codeImg.path,
|
||||
x: isAlipay ? 30 : 120,
|
||||
y: isAlipay ? 90 : 620,
|
||||
w: isAlipay ? 220 : 480,
|
||||
h: isAlipay ? 240 : 480,
|
||||
x: 140,
|
||||
y: 442,
|
||||
w: 320,
|
||||
h: 390,
|
||||
sx: 0,
|
||||
sy: 0,
|
||||
sw:this.codeImg.width,
|
||||
sh:this.codeImg.width
|
||||
sw: this.codeImg.width,
|
||||
sh: this.codeImg.height
|
||||
},
|
||||
drawOptions
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Taro, { Component } from '@tarojs/taro'
|
||||
import api from '@/api'
|
||||
import { getExtConfigData } from '@/utils'
|
||||
import { drawText, drawImage, drawBlock, drawLine } from './helper.alipay'
|
||||
import { drawText, drawImage, drawBlock, drawLine } from './helper'
|
||||
|
||||
const canvasWidth = 600
|
||||
const canvasHeight = 960
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Taro, { Component } from '@tarojs/taro'
|
||||
import api from '@/api'
|
||||
import { getExtConfigData } from '@/utils'
|
||||
import { drawText, drawImage, drawBlock } from './helper.alipay'
|
||||
import { drawText, drawImage, drawBlock } from './helper'
|
||||
|
||||
const canvasWidth = 600
|
||||
const canvasHeight = 960
|
||||
|
||||
@@ -1,458 +0,0 @@
|
||||
/**
|
||||
* @description 绘制圆角矩形
|
||||
* @param { object } drawData - 绘制数据
|
||||
* @param { number } drawData.x - 左上角x坐标
|
||||
* @param { number } drawData.y - 左上角y坐标
|
||||
* @param { number } drawData.w - 矩形的宽
|
||||
* @param { number } drawData.h - 矩形的高
|
||||
* @param { number } drawData.r - 圆角半径
|
||||
*
|
||||
* @param { object } drawOptions - 绘制对象
|
||||
* @param { object } drawOptions.ctx - ctx对象
|
||||
* @param { function } drawOptions.toPx - toPx方法
|
||||
* @param { function } drawOptions.toRpx - toRpx方法
|
||||
*/
|
||||
import { isAlipay, } from '@/utils'
|
||||
|
||||
export function _drawRadiusRect(drawData, drawOptions) {
|
||||
const { x, y, w, h, r } = drawData
|
||||
const {
|
||||
ctx,
|
||||
toPx
|
||||
// toRpx,
|
||||
} = drawOptions
|
||||
const br = r / 2
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(toPx(x + br), toPx(y)) // 移动到左上角的点
|
||||
ctx.lineTo(toPx(x + w - br), toPx(y))
|
||||
ctx.arc(toPx(x + w - br), toPx(y + br), toPx(br), 2 * Math.PI * (3 / 4), 2 * Math.PI * (4 / 4))
|
||||
ctx.lineTo(toPx(x + w), toPx(y + h - br))
|
||||
ctx.arc(toPx(x + w - br), toPx(y + h - br), toPx(br), 0, 2 * Math.PI * (1 / 4))
|
||||
ctx.lineTo(toPx(x + br), toPx(y + h))
|
||||
ctx.arc(toPx(x + br), toPx(y + h - br), toPx(br), 2 * Math.PI * (1 / 4), 2 * Math.PI * (2 / 4))
|
||||
ctx.lineTo(toPx(x), toPx(y + br))
|
||||
ctx.arc(toPx(x + br), toPx(y + br), toPx(br), 2 * Math.PI * (2 / 4), 2 * Math.PI * (3 / 4))
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 计算文本长度
|
||||
* @param { Array | Object } text 数组 或者 对象
|
||||
*
|
||||
* @param { object } drawOptions - 绘制对象
|
||||
* @param { object } drawOptions.ctx - ctx对象
|
||||
* @param { function } drawOptions.toPx - toPx方法
|
||||
* @param { function } drawOptions.toRpx - toRpx方法
|
||||
*/
|
||||
export function _getTextWidth(text, drawOptions) {
|
||||
const { ctx, toPx, toRpx } = drawOptions
|
||||
let texts = []
|
||||
if (Object.prototype.toString.call(text) === '[object Object]') {
|
||||
texts.push(text)
|
||||
} else {
|
||||
texts = text
|
||||
}
|
||||
let width = 0
|
||||
// eslint-disable-next-line no-shadow
|
||||
texts.forEach(({ fontSize, text, marginLeft = 0, marginRight = 0 }) => {
|
||||
ctx.setFontSize(toPx(fontSize))
|
||||
width += ctx.measureText(text).width + marginLeft + marginRight
|
||||
})
|
||||
return toRpx(width)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 渲染一段文字
|
||||
* @param { object } drawData - 绘制数据
|
||||
* @param { number } drawData.x - x坐标 rpx
|
||||
* @param { number } drawData.y - y坐标 rpx
|
||||
* @param { number } drawData.fontSize - 文字大小 rpx
|
||||
* @param { number } [drawData.color] - 颜色
|
||||
* @param { string } [drawData.baseLine] - 基线对齐方式 top| middle|bottom
|
||||
* @param { string } [drawData.textAlign='left'] - 对齐方式 left|center|right
|
||||
* @param { string } drawData.text - 当Object类型时,参数为 text 字段的参数,marginLeft、marginRight这两个字段可用
|
||||
* @param { number } [drawData.opacity=1] - 1为不透明,0为透明
|
||||
* @param { string } [drawData.textDecoration='none']
|
||||
* @param { number } [drawData.width] - 文字宽度 没有指定为画布宽度
|
||||
* @param { number } [drawData.lineNum=1] - 根据宽度换行,最多的行数
|
||||
* @param { number } [drawData.lineHeight=0] - 行高
|
||||
* @param { string } [drawData.fontWeight='normal'] - 'bold' 加粗字体,目前小程序不支持 100 - 900 加粗
|
||||
* @param { string } [drawData.fontStyle='normal'] - 'italic' 倾斜字体
|
||||
* @param { string } [drawData.fontFamily="sans-serif"] - 小程序默认字体为 'sans-serif', 请输入小程序支持的字体
|
||||
*
|
||||
* @param { object } drawOptions - 绘制对象
|
||||
* @param { object } drawOptions.ctx - ctx对象
|
||||
* @param { function } drawOptions.toPx - toPx方法
|
||||
* @param { function } drawOptions.toRpx - toRpx方法
|
||||
*/
|
||||
export function _drawSingleText(drawData, drawOptions) {
|
||||
if(isAlipay){
|
||||
// drawData.x = drawData.x / 4
|
||||
// drawData.y = drawData.y / 4
|
||||
// drawData.fontSize = drawData.fontSize / 2
|
||||
}
|
||||
const {
|
||||
x,
|
||||
y,
|
||||
fontSize,
|
||||
color,
|
||||
baseLine,
|
||||
textAlign = 'left',
|
||||
text,
|
||||
opacity = 1,
|
||||
textDecoration = 'none',
|
||||
width,
|
||||
lineNum = 1,
|
||||
lineHeight = 0,
|
||||
fontWeight = 'normal',
|
||||
fontStyle = 'normal',
|
||||
fontFamily = 'sans-serif'
|
||||
} = drawData
|
||||
console.log('_drawSingleText:drawData',drawData)
|
||||
const { ctx, toPx, toRpx } = drawOptions
|
||||
ctx.save()
|
||||
ctx.beginPath()
|
||||
ctx.font = fontStyle + ' ' + fontWeight + ' ' + toPx(fontSize, true) + 'px ' + fontFamily
|
||||
ctx.setGlobalAlpha(opacity)
|
||||
// ctx.setFontSize(toPx(fontSize));
|
||||
ctx.setFillStyle(color)
|
||||
ctx.setTextBaseline(baseLine)
|
||||
ctx.setTextAlign(textAlign)
|
||||
let textWidth = toRpx(ctx.measureText(text).width)
|
||||
const textArr = []
|
||||
if (textWidth > width) {
|
||||
// 文本宽度 大于 渲染宽度
|
||||
let fillText = ''
|
||||
let line = 1
|
||||
for (let i = 0; i <= text.length - 1; i++) {
|
||||
// 将文字转为数组,一行文字一个元素
|
||||
fillText = fillText + text[i]
|
||||
if (toRpx(ctx.measureText(fillText).width) >= width) {
|
||||
if (line === lineNum) {
|
||||
if (i !== text.length - 1) {
|
||||
fillText = fillText.substring(0, fillText.length - 1) + '...'
|
||||
}
|
||||
}
|
||||
if (line <= lineNum) {
|
||||
textArr.push(fillText)
|
||||
}
|
||||
fillText = ''
|
||||
line++
|
||||
} else {
|
||||
if (line <= lineNum) {
|
||||
if (i === text.length - 1) {
|
||||
textArr.push(fillText)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
textWidth = width
|
||||
} else {
|
||||
textArr.push(text)
|
||||
}
|
||||
textArr.forEach((item, index) => {
|
||||
ctx.fillText(item, toPx(x), toPx(y + (lineHeight || fontSize) * index))
|
||||
})
|
||||
ctx.restore()
|
||||
// textDecoration
|
||||
if (textDecoration !== 'none') {
|
||||
let lineY = y
|
||||
if (textDecoration === 'line-through') {
|
||||
// 目前只支持贯穿线
|
||||
lineY = y - fontSize * 0.4
|
||||
}
|
||||
ctx.save()
|
||||
ctx.moveTo(toPx(x), toPx(lineY))
|
||||
ctx.lineTo(toPx(x) + toPx(textWidth), toPx(lineY))
|
||||
ctx.setStrokeStyle(color)
|
||||
ctx.stroke()
|
||||
ctx.restore()
|
||||
}
|
||||
return textWidth
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染文字
|
||||
* @param { object } params - 绘制数据
|
||||
* @param { number } params.x - x坐标 rpx
|
||||
* @param { number } params.y - y坐标 rpx
|
||||
* @param { number } params.fontSize - 文字大小 rpx
|
||||
* @param { number } [params.color] - 颜色
|
||||
* @param { string } [params.baseLine] - 基线对齐方式 top| middle|bottom
|
||||
* @param { string } [params.textAlign='left'] - 对齐方式 left|center|right
|
||||
* @param { string } params.text - 当Object类型时,参数为 text 字段的参数,marginLeft、marginRight这两个字段可用
|
||||
* @param { number } [params.opacity=1] - 1为不透明,0为透明
|
||||
* @param { string } [params.textDecoration='none']
|
||||
* @param { number } [params.width] - 文字宽度 没有指定为画布宽度
|
||||
* @param { number } [params.lineNum=1] - 根据宽度换行,最多的行数
|
||||
* @param { number } [params.lineHeight=0] - 行高
|
||||
* @param { string } [params.fontWeight='normal'] - 'bold' 加粗字体,目前小程序不支持 100 - 900 加粗
|
||||
* @param { string } [params.fontStyle='normal'] - 'italic' 倾斜字体
|
||||
* @param { string } [params.fontFamily="sans-serif"] - 小程序默认字体为 'sans-serif', 请输入小程序支持的字体
|
||||
*
|
||||
* @param { object } drawOptions - 绘制对象
|
||||
* @param { object } drawOptions.ctx - ctx对象
|
||||
* @param { function } drawOptions.toPx - toPx方法
|
||||
* @param { function } drawOptions.toRpx - toRpx方法
|
||||
*/
|
||||
export function drawText(params, drawOptions) {
|
||||
// const { ctx, toPx, toRpx } = drawOptions;
|
||||
const {
|
||||
x,
|
||||
y,
|
||||
text,
|
||||
baseLine
|
||||
// fontSize,
|
||||
// color,
|
||||
// textAlign,
|
||||
// opacity = 1,
|
||||
// width,
|
||||
// lineNum,
|
||||
// lineHeight
|
||||
} = params
|
||||
console.log('drawText', params)
|
||||
if (Object.prototype.toString.call(text) === '[object Array]') {
|
||||
let preText = { x, y, baseLine }
|
||||
text.forEach((item) => {
|
||||
preText.x += item.marginLeft || 0
|
||||
const textWidth = _drawSingleText(
|
||||
Object.assign(item, {
|
||||
...preText
|
||||
}),
|
||||
drawOptions
|
||||
)
|
||||
preText.x += textWidth + (item.marginRight || 0) // 下一段字的 x 轴为上一段字 x + 上一段字宽度
|
||||
})
|
||||
} else {
|
||||
_drawSingleText(params, drawOptions)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 渲染图片
|
||||
* @param { object } data
|
||||
* @param { number } x - 图像的左上角在目标 canvas 上 x 轴的位置
|
||||
* @param { number } y - 图像的左上角在目标 canvas 上 y 轴的位置
|
||||
* @param { number } w - 在目标画布上绘制图像的宽度,允许对绘制的图像进行缩放
|
||||
* @param { number } h - 在目标画布上绘制图像的高度,允许对绘制的图像进行缩放
|
||||
* @param { number } sx - 源图像的矩形选择框的左上角 x 坐标
|
||||
* @param { number } sy - 源图像的矩形选择框的左上角 y 坐标
|
||||
* @param { number } sw - 源图像的矩形选择框的宽度
|
||||
* @param { number } sh - 源图像的矩形选择框的高度
|
||||
* @param { number } [borderRadius=0] - 圆角
|
||||
* @param { number } [borderWidth=0] - 边框
|
||||
*
|
||||
* @param { object } drawOptions - 绘制对象
|
||||
* @param { object } drawOptions.ctx - ctx对象
|
||||
* @param { function } drawOptions.toPx - toPx方法
|
||||
* @param { function } drawOptions.toRpx - toRpx方法
|
||||
*/
|
||||
export function drawImage(data, drawOptions) {
|
||||
const { ctx, toPx } = drawOptions
|
||||
if(isAlipay){
|
||||
data.sw = data.sw * 2
|
||||
data.sh = data.sh * 2
|
||||
data.h = data.h / 1.3
|
||||
}
|
||||
const {
|
||||
imgPath,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
sx,
|
||||
sy,
|
||||
sw,
|
||||
sh,
|
||||
borderRadius = 0,
|
||||
borderWidth = 0,
|
||||
borderColor
|
||||
} = data
|
||||
ctx.save()
|
||||
console.log('drawImage:data', data)
|
||||
if (borderRadius > 0) {
|
||||
let drawData = {
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
r: borderRadius
|
||||
}
|
||||
_drawRadiusRect(drawData, drawOptions)
|
||||
ctx.strokeStyle = 'rgba(255,255,255,0)'
|
||||
ctx.stroke()
|
||||
ctx.clip()
|
||||
ctx.drawImage(
|
||||
imgPath,
|
||||
toPx(sx),
|
||||
toPx(sy),
|
||||
toPx(sw),
|
||||
toPx(sh),
|
||||
toPx(x),
|
||||
toPx(y),
|
||||
toPx(w),
|
||||
toPx(h)
|
||||
)
|
||||
if (borderWidth > 0) {
|
||||
ctx.setStrokeStyle(borderColor)
|
||||
ctx.setLineWidth(toPx(borderWidth))
|
||||
ctx.stroke()
|
||||
}
|
||||
} else {
|
||||
ctx.drawImage(
|
||||
imgPath,
|
||||
toPx(sx),
|
||||
toPx(sy),
|
||||
toPx(sw),
|
||||
toPx(sh),
|
||||
toPx(x),
|
||||
toPx(y),
|
||||
toPx(w),
|
||||
toPx(h)
|
||||
)
|
||||
}
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 渲染线
|
||||
* @param { number } startX - 起始坐标
|
||||
* @param { number } startY - 起始坐标
|
||||
* @param { number } endX - 终结坐标
|
||||
* @param { number } endY - 终结坐标
|
||||
* @param { number } width - 线的宽度
|
||||
* @param { string } [color] - 线的颜色
|
||||
*
|
||||
* @param { object } drawOptions - 绘制对象
|
||||
* @param { object } drawOptions.ctx - ctx对象
|
||||
* @param { function } drawOptions.toPx - toPx方法
|
||||
* @param { function } drawOptions.toRpx - toRpx方法
|
||||
*/
|
||||
export function drawLine(drawData, drawOptions) {
|
||||
const { startX, startY, endX, endY, color, width } = drawData
|
||||
const { ctx, toPx } = drawOptions
|
||||
ctx.save()
|
||||
ctx.beginPath()
|
||||
ctx.setStrokeStyle(color)
|
||||
ctx.setLineWidth(toPx(width))
|
||||
ctx.moveTo(toPx(startX), toPx(startY))
|
||||
ctx.lineTo(toPx(endX), toPx(endY))
|
||||
ctx.stroke()
|
||||
ctx.closePath()
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 渲染块
|
||||
* @param { number } x - x坐标
|
||||
* @param { number } y - y坐标
|
||||
* @param { number } height -高
|
||||
* @param { string|object } [text] - 块里面可以填充文字,参考texts字段
|
||||
* @param { number } [width=0] - 宽 如果内部有文字,由文字宽度和内边距决定
|
||||
* @param { number } [paddingLeft=0] - 内左边距
|
||||
* @param { number } [paddingRight=0] - 内右边距
|
||||
* @param { number } [borderWidth] - 边框宽度
|
||||
* @param { string } [backgroundColor] - 背景颜色
|
||||
* @param { string } [borderColor] - 边框颜色
|
||||
* @param { number } [borderRadius=0] - 圆角
|
||||
* @param { number } [opacity=1] - 透明度
|
||||
*
|
||||
* @param { object } drawOptions - 绘制对象
|
||||
* @param { object } drawOptions.ctx - ctx对象
|
||||
* @param { function } drawOptions.toPx - toPx方法
|
||||
* @param { function } drawOptions.toRpx - toRpx方法
|
||||
*/
|
||||
export function drawBlock(
|
||||
{
|
||||
text,
|
||||
width = 0,
|
||||
height,
|
||||
x,
|
||||
y,
|
||||
paddingLeft = 0,
|
||||
paddingRight = 0,
|
||||
borderWidth,
|
||||
backgroundColor,
|
||||
borderColor,
|
||||
borderRadius = 0,
|
||||
opacity = 1
|
||||
},
|
||||
drawOptions
|
||||
) {
|
||||
console.log('drawBlock:data',arguments[0])
|
||||
height = height * 2
|
||||
const { ctx, toPx } = drawOptions
|
||||
// 判断是否块内有文字
|
||||
let blockWidth = 0 // 块的宽度
|
||||
let textX = 0
|
||||
let textY = 0
|
||||
if (typeof text !== 'undefined') {
|
||||
// 如果有文字并且块的宽度小于文字宽度,块的宽度为 文字的宽度 + 内边距
|
||||
const textWidth = _getTextWidth(typeof text.text === 'string' ? text : text.text, drawOptions)
|
||||
blockWidth = textWidth > width ? textWidth : width
|
||||
blockWidth += paddingLeft + paddingLeft
|
||||
|
||||
const {
|
||||
textAlign = 'left'
|
||||
// text: textCon,
|
||||
} = text
|
||||
textY = height / 2 + y // 文字的y轴坐标在块中线
|
||||
if (textAlign === 'left') {
|
||||
// 如果是右对齐,那x轴在块的最左边
|
||||
textX = x + paddingLeft
|
||||
} else if (textAlign === 'center') {
|
||||
textX = blockWidth / 2 + x
|
||||
} else {
|
||||
textX = x + blockWidth - paddingRight
|
||||
}
|
||||
} else {
|
||||
blockWidth = width
|
||||
}
|
||||
|
||||
if (backgroundColor) {
|
||||
// 画面
|
||||
ctx.save()
|
||||
ctx.setGlobalAlpha(opacity)
|
||||
ctx.setFillStyle(backgroundColor)
|
||||
if (borderRadius > 0) {
|
||||
// 画圆角矩形
|
||||
let drawData = {
|
||||
x,
|
||||
y,
|
||||
w: blockWidth,
|
||||
h: height,
|
||||
r: borderRadius
|
||||
}
|
||||
_drawRadiusRect(drawData, drawOptions)
|
||||
ctx.fill()
|
||||
} else {
|
||||
ctx.fillRect(toPx(x), toPx(y), toPx(blockWidth), toPx(height))
|
||||
}
|
||||
ctx.restore()
|
||||
}
|
||||
if (borderWidth) {
|
||||
// 画线
|
||||
ctx.save()
|
||||
ctx.setGlobalAlpha(opacity)
|
||||
ctx.setStrokeStyle(borderColor)
|
||||
ctx.setLineWidth(toPx(borderWidth))
|
||||
if (borderRadius > 0) {
|
||||
// 画圆角矩形边框
|
||||
let drawData = {
|
||||
x,
|
||||
y,
|
||||
w: blockWidth,
|
||||
h: height,
|
||||
r: borderRadius
|
||||
}
|
||||
_drawRadiusRect(drawData, drawOptions)
|
||||
ctx.stroke()
|
||||
} else {
|
||||
ctx.strokeRect(toPx(x), toPx(y), toPx(blockWidth), toPx(height))
|
||||
}
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
if (text) {
|
||||
drawText(Object.assign(text, { x: textX, y: textY }), drawOptions)
|
||||
}
|
||||
}
|
||||
@@ -1,299 +0,0 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useSelector } from 'react-redux'
|
||||
import Taro from '@tarojs/taro'
|
||||
import { View, Text, Image, Button, Canvas } from '@tarojs/components'
|
||||
import { useImmer } from 'use-immer'
|
||||
import { useAsyncCallback } from '@/hooks'
|
||||
import { classNames, authSetting, showToast, isAlipay } from '@/utils'
|
||||
import GoodsDetailPoster from './dw-goodsdetail.alipay'
|
||||
import GuideGoodsDetailPoster from './dw-guidegoodsdetail.wx'
|
||||
import GuideCheckout from './dw-guidecheckout.wx'
|
||||
import Distribution from './dw-distribution.wx'
|
||||
import './index.scss'
|
||||
|
||||
const initialState = {
|
||||
poster: null,
|
||||
pxWidth: 200,
|
||||
pxHeight: 200,
|
||||
factor: 1,
|
||||
eleId: 'poster-canvas',
|
||||
ctx: null
|
||||
}
|
||||
|
||||
function SpPoster(props) {
|
||||
const { info, type, onClose = () => {} } = props
|
||||
console.log('SpPoster:props', props)
|
||||
const { userInfo } = useSelector((state) => state.user)
|
||||
const { userInfo: guideInfo } = useSelector((state) => state.guide)
|
||||
const [state, setState] = useAsyncCallback(initialState)
|
||||
|
||||
const { poster, pxWidth, pxHeight, eleId, ctx } = state
|
||||
console.log('SpPoster:state', state)
|
||||
useEffect(() => {
|
||||
// !isAlipay ? handleCreatePoster() : handleCreatePoster3()
|
||||
handleCreatePoster()
|
||||
}, [])
|
||||
|
||||
/**
|
||||
* @description rpx => px 基础方法
|
||||
* @param { number } rpx - 需要转换的数值
|
||||
* @param { boolean} int - 是否为 int
|
||||
* @param { number } [factor] - 转化因子
|
||||
* @returns { number }
|
||||
*/
|
||||
const toPx = (rpx, int, factor = 1) => {
|
||||
if (int) {
|
||||
return parseInt(rpx * factor)
|
||||
}
|
||||
return rpx * factor
|
||||
}
|
||||
/**
|
||||
* @description px => rpx
|
||||
* @param { number } px - 需要转换的数值
|
||||
* @param { boolean} int - 是否为 int
|
||||
* @param { number } [factor] - 转化因子
|
||||
* @returns { number }
|
||||
*/
|
||||
const toRpx = (px, int, factor = 1) => {
|
||||
if (int) {
|
||||
return parseInt(px / factor)
|
||||
}
|
||||
return px / factor
|
||||
}
|
||||
|
||||
const handleCreatePoster = async () => {
|
||||
Taro.showLoading({
|
||||
title: '海报生成中...'
|
||||
})
|
||||
const ctx = Taro.createCanvasContext(eleId, Taro.getCurrentInstance().page)
|
||||
console.log('sp-handleCreatePoster:ctx', ctx)
|
||||
let canvasObj
|
||||
switch (type) {
|
||||
case 'goodsDetial':
|
||||
canvasObj = new GoodsDetailPoster({
|
||||
ctx,
|
||||
info,
|
||||
userInfo,
|
||||
toPx,
|
||||
toRpx
|
||||
})
|
||||
break
|
||||
case 'guideGoodsDetial':
|
||||
canvasObj = new GuideGoodsDetailPoster({
|
||||
ctx,
|
||||
info,
|
||||
userInfo: guideInfo,
|
||||
toPx,
|
||||
toRpx
|
||||
})
|
||||
break
|
||||
case 'guideCheckout':
|
||||
canvasObj = new GuideCheckout({
|
||||
ctx,
|
||||
info,
|
||||
userInfo: guideInfo,
|
||||
toPx,
|
||||
toRpx
|
||||
})
|
||||
break
|
||||
case 'distribution':
|
||||
canvasObj = new Distribution({
|
||||
ctx,
|
||||
info,
|
||||
userInfo,
|
||||
toPx,
|
||||
toRpx
|
||||
})
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
const { canvasWidth, canvasHeight } = canvasObj.getCanvasSize()
|
||||
setState(
|
||||
(draft) => {
|
||||
draft.pxWidth = canvasWidth
|
||||
draft.pxHeight = canvasHeight
|
||||
draft.ctx = ctx
|
||||
},
|
||||
async (_state) => {
|
||||
console.log('handleCreatePoster-setState:_state1', _state)
|
||||
await canvasObj.drawPoster()
|
||||
const poster = await getPoster(_state)
|
||||
Taro.hideLoading()
|
||||
setState((draft) => {
|
||||
draft.poster = poster
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
const handleCreatePoster2 = () => {
|
||||
Taro.showLoading({
|
||||
title: '海报生成中...'
|
||||
})
|
||||
console.log('handleCreatePoster run')
|
||||
let ctx = null
|
||||
// 通过 SelectorQuery 获取 Canvas 实例
|
||||
Taro.createSelectorQuery()
|
||||
.select('#poster-canvas')
|
||||
.node()
|
||||
.exec((res) => {
|
||||
console.log('alipay:res', res)
|
||||
const canvas = res[0].node
|
||||
ctx = canvas.getContext('2d')
|
||||
console.log('canvas', canvas)
|
||||
console.log('alipay:ctx1', ctx)
|
||||
// 开始绘画
|
||||
// ctx.fillRect(0, 100, 50, 50)
|
||||
console.log('alipay:ctx2', ctx)
|
||||
let canvasObj
|
||||
switch (type) {
|
||||
case 'goodsDetial':
|
||||
canvasObj = new GoodsDetailPoster({
|
||||
canvas,
|
||||
ctx,
|
||||
info,
|
||||
userInfo,
|
||||
toPx,
|
||||
toRpx
|
||||
})
|
||||
break
|
||||
case 'guideGoodsDetial':
|
||||
canvasObj = new GuideGoodsDetailPoster({
|
||||
ctx,
|
||||
info,
|
||||
userInfo: guideInfo,
|
||||
toPx,
|
||||
toRpx
|
||||
})
|
||||
break
|
||||
case 'guideCheckout':
|
||||
canvasObj = new GuideCheckout({
|
||||
ctx,
|
||||
info,
|
||||
userInfo: guideInfo,
|
||||
toPx,
|
||||
toRpx
|
||||
})
|
||||
break
|
||||
case 'distribution':
|
||||
canvasObj = new Distribution({
|
||||
ctx,
|
||||
info,
|
||||
userInfo,
|
||||
toPx,
|
||||
toRpx
|
||||
})
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
console.log('handleCreatePoster:canvasObj', canvasObj)
|
||||
const { canvasWidth, canvasHeight } = canvasObj.getCanvasSize()
|
||||
console.log('handleCreatePoster:canvasWidth', canvasWidth)
|
||||
console.log('handleCreatePoster:canvasHeight', canvasHeight)
|
||||
setState(
|
||||
(draft) => {
|
||||
draft.pxWidth = canvasWidth
|
||||
draft.pxHeight = canvasHeight
|
||||
draft.ctx = ctx
|
||||
draft.canvas = res[0].node
|
||||
},
|
||||
async (_state) => {
|
||||
console.log('handleCreatePoster-setState:_state2', _state)
|
||||
await canvasObj.drawPoster()
|
||||
const poster = await getPoster(_state)
|
||||
Taro.hideLoading()
|
||||
setState((draft) => {
|
||||
draft.poster = poster
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
const getPoster = ({ ctx, pxWidth, pxHeight, eleId }) => {
|
||||
console.log('getPoster:ctx', ctx)
|
||||
return new Promise((resolve, reject) => {
|
||||
ctx.draw(false, async () => {
|
||||
const { tempFilePath: poster } = await Taro.canvasToTempFilePath(
|
||||
{
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: pxWidth,
|
||||
height: pxHeight,
|
||||
canvasId: eleId
|
||||
},
|
||||
Taro.getCurrentInstance().page
|
||||
)
|
||||
console.log('getPoster:poster', poster)
|
||||
resolve(poster)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const saveToAlbum = () => {
|
||||
authSetting(
|
||||
'writePhotosAlbum',
|
||||
() => {
|
||||
savePoster()
|
||||
},
|
||||
() => {
|
||||
showToast('请设置允许保存到相册')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const savePoster = () => {
|
||||
Taro.saveImageToPhotosAlbum({
|
||||
filePath: poster
|
||||
})
|
||||
.then((res) => {
|
||||
showToast('保存成功')
|
||||
})
|
||||
.catch((res) => {
|
||||
showToast('保存失败')
|
||||
})
|
||||
}
|
||||
|
||||
// const onCanvasReady = () => {
|
||||
// console.log('onCanvasReady2222')
|
||||
// // 通过 SelectorQuery 获取 Canvas 实例
|
||||
// Taro.createSelectorQuery().select('#canvas1').node().exec((res) => {
|
||||
// console.log('canvas1:Res', res)
|
||||
// const canvas = res[0].node;
|
||||
// const ctx = canvas.getContext('2d');
|
||||
// console.log('canvas 宽高', canvas.width, canvas.height)
|
||||
// // 开始绘画
|
||||
// ctx.fillRect(0, 0, 50, 50);
|
||||
// });
|
||||
// }
|
||||
return (
|
||||
<View className={classNames('sp-poster')}>
|
||||
{/* <Canvas id="canvas1" type="2d" onReady={onCanvasReady} /> */}
|
||||
<View className='share-panel__overlay'></View>
|
||||
{poster && (
|
||||
<View className='share-panel__poster'>
|
||||
<View className='poster-container'>
|
||||
<Image className='poster' src={poster} mode='widthFix' />
|
||||
</View>
|
||||
<View className='poster-ft'>
|
||||
<Text className='iconfont icon-guanbi' onClick={onClose}></Text>
|
||||
<View className='poster-save' onClick={saveToAlbum}>
|
||||
<Text className='iconfont icon-download'></Text>
|
||||
保存图片
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
<Canvas
|
||||
className='canvasbox'
|
||||
// type='2d'
|
||||
id='poster-canvas'
|
||||
canvasId='poster-canvas'
|
||||
style={`width:${pxWidth}px; height:${pxHeight}px;`}
|
||||
// onReady={handleCreatePoster2}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export default SpPoster
|
||||
@@ -4,22 +4,11 @@ import Taro from '@tarojs/taro'
|
||||
import { View, Text, Image, Canvas } from '@tarojs/components'
|
||||
import { useAsyncCallback } from '@/hooks'
|
||||
import { classNames, authSetting, showToast, isAlipay } from '@/utils'
|
||||
import GoodsDetailPosterAl from './dw-goodsdetail.alipay'
|
||||
import GoodsDetailPosterWx from './dw-goodsdetail.wx'
|
||||
import GuideGoodsDetailPosterAl from './dw-guidegoodsdetail.alipay'
|
||||
import GuideGoodsDetailPosterWx from './dw-guidegoodsdetail.wx'
|
||||
import GuideCheckoutWx from './dw-guidecheckout.wx'
|
||||
import GuideCheckoutAl from './dw-guidecheckout.alipay'
|
||||
import DistributionAl from './dw-distribution.alipay'
|
||||
import DistributionWx from './dw-distribution.wx'
|
||||
import GoodsDetailPoster from './dw-goodsdetail'
|
||||
import Distribution from './dw-distribution'
|
||||
import GuideGoodsDetailPoster from './dw-guidegoodsdetail'
|
||||
import GuideCheckout from './dw-guidecheckout'
|
||||
|
||||
const DwArray = [
|
||||
isAlipay ? GoodsDetailPosterAl : GoodsDetailPosterWx,
|
||||
isAlipay ? GuideGoodsDetailPosterAl : GuideGoodsDetailPosterWx,
|
||||
isAlipay ? GuideCheckoutAl : GuideCheckoutWx,
|
||||
isAlipay ? DistributionAl : DistributionWx,
|
||||
]
|
||||
const [GoodsDetailPoster, GuideGoodsDetailPoster, GuideCheckout, Distribution] = DwArray
|
||||
|
||||
import './index.scss'
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ function SpSkuSelect(props) {
|
||||
const {
|
||||
info,
|
||||
open = false,
|
||||
onClose = () => {},
|
||||
onChange = () => {},
|
||||
onClose = () => { },
|
||||
onChange = () => { },
|
||||
type,
|
||||
hideInputNumber = false
|
||||
} = props
|
||||
@@ -69,7 +69,7 @@ function SpSkuSelect(props) {
|
||||
skuDictRef.current[key] = item
|
||||
})
|
||||
// 默认选中有库存并且前端可销售的sku
|
||||
const defaultSpecItem = specItems.find((item) => item.store > 0 && item.approveStatus == 'onsale')
|
||||
const defaultSpecItem = specItems.find((item) => item.store > 0 && ['onsale', 'offline_sale'].includes(item.approveStatus))
|
||||
let selection = Array(specItems.length).fill(null)
|
||||
if (defaultSpecItem) {
|
||||
selection = defaultSpecItem.specItem.map((item) => item.specId)
|
||||
@@ -91,7 +91,7 @@ function SpSkuSelect(props) {
|
||||
const reg = makeReg(sel, row, val)
|
||||
|
||||
return Object.keys(skuDictRef.current).some((key) => {
|
||||
return key.match(reg) && skuDictRef.current[key].store > 0 && skuDictRef.current[key].approveStatus == 'onsale'
|
||||
return key.match(reg) && skuDictRef.current[key].store > 0 && ['onsale', 'offline_sale'].includes(skuDictRef.current[key].approveStatus)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ function SpSkuSelect(props) {
|
||||
item_id: curItem ? curItem.itemId : info.itemId,
|
||||
num,
|
||||
distributor_id: distributorId
|
||||
}, !!info.point ) // info.point 有积分值时是积分商品
|
||||
}, !!info.point) // info.point 有积分值时是积分商品
|
||||
let url = !!info.point ? '/subpages/pointshop/espier-checkout?cart_type=fastbuy&shop_id=0' : `/pages/cart/espier-checkout?cart_type=fastbuy&shop_id=${distributorId}`
|
||||
if (activityType == 'seckill' || activityType === 'limited_time_sale') {
|
||||
const { seckill_id } = activityInfo
|
||||
@@ -295,7 +295,7 @@ function SpSkuSelect(props) {
|
||||
limitTxt = `(限购${purlimitByCart}件)`
|
||||
}
|
||||
|
||||
if(type == 'fastbuy' && purlimitByFastbuy) {
|
||||
if (type == 'fastbuy' && purlimitByFastbuy) {
|
||||
limitNum = purlimitByFastbuy
|
||||
limitTxt = `(限购${purlimitByFastbuy}件)`
|
||||
}
|
||||
@@ -352,7 +352,7 @@ function SpSkuSelect(props) {
|
||||
</View> */}
|
||||
<SpGoodsPrice info={curItem || info} />
|
||||
<View className='goods-sku-txt'>{skuText}</View>
|
||||
<View className='goods-sku-store'>库存:{curItem ? curItem.store : info.store}</View>
|
||||
{info.store_setting && <View className='goods-sku-store'>库存:{curItem ? curItem.store : info.store}</View>}
|
||||
</View>
|
||||
</View>
|
||||
<View className='sku-list'>
|
||||
|
||||
@@ -12,35 +12,16 @@ import './index.scss'
|
||||
@connect(({ colors }) => ({
|
||||
colors: colors.current
|
||||
}))
|
||||
|
||||
|
||||
|
||||
export default class DistributionDashboard extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
const UI_Width = 750
|
||||
//同步获取设备系统信息
|
||||
const info = Taro.getSystemInfoSync()
|
||||
//设备像素密度
|
||||
const dpr = info.pixelRatio;
|
||||
//计算比例
|
||||
const scale = info.screenWidth / UI_Width
|
||||
//计算canvas实际渲染尺寸
|
||||
let width = parseInt(scale * 335)
|
||||
let height = parseInt(scale * 536)
|
||||
//计算canvas画布尺寸
|
||||
let canvasWidth = width * dpr
|
||||
let canvasHeight = height * dpr
|
||||
|
||||
this.state = {
|
||||
info: null,
|
||||
showPoster: false,
|
||||
poster: null,
|
||||
posterImgs: null,
|
||||
adapay_status: null,
|
||||
dpr,
|
||||
canvasWidth,
|
||||
canvasHeight
|
||||
adapay_status: null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,195 +133,14 @@ export default class DistributionDashboard extends Component {
|
||||
}
|
||||
|
||||
handleClick = async () => {
|
||||
const { posterImgs } = this.state
|
||||
if (!posterImgs || !posterImgs.avatar || !posterImgs.code || !posterImgs.username) {
|
||||
const imgs = await this.downloadPosterImg()
|
||||
if (imgs && imgs.avatar && imgs.code && imgs.username) {
|
||||
this.setState({
|
||||
showPoster: true
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
showPoster: true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
downloadPosterImg = async () => {
|
||||
// 处理海报信息以及太阳码
|
||||
let {
|
||||
info: { username, isOpenShop, shop_status, qrcode_bg_img },
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
} = this.state
|
||||
|
||||
|
||||
let userinfo = Taro.getStorageSync('userinfo')
|
||||
const { avatar, userId } = userinfo
|
||||
if (S.getAuthToken() && (!userinfo || !userId)) {
|
||||
const res = await api.member.memberInfo()
|
||||
const userObj = {
|
||||
avatar: res.memberInfo.avatar,
|
||||
userId: res.memberInfo.user_id
|
||||
}
|
||||
Taro.setStorageSync('userinfo', userObj)
|
||||
userinfo = userObj
|
||||
}
|
||||
// const extConfig =
|
||||
// Taro.getEnv() === 'WEAPP' && wx.getExtConfigSync
|
||||
// ? wx.getExtConfigSync()
|
||||
// : { appid: process.env.APP_ID, company_id: process.env.APP_COMPANY_ID }
|
||||
const extConfig = getExtConfigData()
|
||||
shop_status = JSON.parse(shop_status === 1)
|
||||
const url = isOpenShop && shop_status ? `marketing/pages/distribution/shop-home` : `pages/index`
|
||||
const wxappCode = `${req.baseURL}promoter/qrcode.png?path=${url}&appid=${extConfig.appid}&company_id=${extConfig.company_id}&user_id=${userId}`
|
||||
console.log('DistributionDashboard-wxappCode:', wxappCode)
|
||||
let avatarImg, bck
|
||||
|
||||
//头像
|
||||
let nAvatar = avatar === '' ? `${process.env.APP_IMAGE_CDN}/user_icon.png` : avatar
|
||||
avatarImg = await Taro.getImageInfo({ src: nAvatar })
|
||||
|
||||
if (qrcode_bg_img) {
|
||||
// 背景
|
||||
bck = await Taro.getImageInfo({ src: qrcode_bg_img })
|
||||
} else {
|
||||
bck = await Taro.getImageInfo({
|
||||
src: `${process.env.APP_IMAGE_CDN}/fenxiao_bk.png`
|
||||
}) // 背景图片
|
||||
}
|
||||
|
||||
const codeImg = await Taro.getImageInfo({ src: wxappCode }) // 二维码
|
||||
console.log('DistributionDashboard-avatarImg:', avatarImg)
|
||||
console.log('DistributionDashboard-codeImg:', codeImg)
|
||||
|
||||
if (avatarImg || isAlipay) {
|
||||
const posterImgs = {
|
||||
avatar: avatarImg ? avatarImg.path : null,
|
||||
code: codeImg.path,
|
||||
bck: bck.path,
|
||||
username
|
||||
}
|
||||
await this.setState(
|
||||
{
|
||||
posterImgs
|
||||
},
|
||||
() => {
|
||||
this.drawImage()
|
||||
}
|
||||
)
|
||||
return posterImgs
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
drawImage = () => {
|
||||
// 分享海报
|
||||
console.log('drawImage run')
|
||||
const { posterImgs } = this.state
|
||||
if (!posterImgs) return
|
||||
const { avatar, code, bck, username } = posterImgs
|
||||
const ctx = Taro.createCanvasContext('myCanvas')
|
||||
console.log('drawImage:ctx', ctx)
|
||||
canvasExp.roundRect(ctx, '#fff', 0, 0, 375, 640, 5)
|
||||
// canvasExp.drawImageFill(ctx, bck, 0, 0, 375, 640)
|
||||
// ctx.drawImage(bck, 0, 0, 750, 1335, 0, 0, 375, 640)
|
||||
// ctx.save()
|
||||
canvasExp.textFill(ctx, username, 180, 50, 18, '#222')
|
||||
canvasExp.drawImageFill(ctx, code, 100, 325, 180, 180)
|
||||
canvasExp.imgCircleClip(ctx, avatar, 100, 15, 65, 65)
|
||||
ctx.draw(true, () => {
|
||||
Taro.canvasToTempFilePath({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 375,
|
||||
height: 640,
|
||||
canvasId: 'myCanvas'
|
||||
}).then((res) => {
|
||||
const shareImg = res.tempFilePath
|
||||
this.setState(
|
||||
{
|
||||
poster: shareImg
|
||||
},
|
||||
() => {
|
||||
this.setState({
|
||||
showPoster: true
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/** 点击保存按钮 */
|
||||
handleSavePoster = () => {
|
||||
const { poster } = this.state
|
||||
Taro.getSetting().then((res) => {
|
||||
if (!res.authSetting['scope.writePhotosAlbum']) {
|
||||
Taro.authorize({
|
||||
scope: 'scope.writePhotosAlbum',
|
||||
success: async () => {
|
||||
await this.savePoster(poster)
|
||||
},
|
||||
fail: () => {
|
||||
Taro.showModal({
|
||||
title: '提示',
|
||||
content: '请打开保存到相册权限',
|
||||
success: async (resConfirm) => {
|
||||
if (resConfirm.confirm) {
|
||||
await Taro.openSetting()
|
||||
const setting = await Taro.getSetting()
|
||||
if (setting.authSetting['scope.writePhotosAlbum']) {
|
||||
await this.savePoster(poster)
|
||||
} else {
|
||||
Taro.showToast({ title: '保存失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.savePoster(poster)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 保存图片 */
|
||||
savePoster = (poster) => {
|
||||
Taro.saveImageToPhotosAlbum({
|
||||
filePath: poster
|
||||
})
|
||||
.then(() => {
|
||||
Taro.showToast({
|
||||
icon: 'none',
|
||||
title: '保存成功'
|
||||
})
|
||||
this.setState({
|
||||
showPoster: false
|
||||
})
|
||||
})
|
||||
.catch((res) => {
|
||||
console.log(res)
|
||||
Taro.showToast({
|
||||
icon: 'none',
|
||||
title: '保存失败'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
handleHidePoster = () => {
|
||||
this.setState({
|
||||
showPoster: false
|
||||
showPoster: true
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { colors } = this.props
|
||||
const { info, showPoster, poster, adapay_status,canvasWidth,
|
||||
canvasHeight, } = this.state
|
||||
const { info, showPoster, adapay_status } = this.state
|
||||
if (!info) {
|
||||
return <Loading />
|
||||
}
|
||||
@@ -471,9 +271,8 @@ export default class DistributionDashboard extends Component {
|
||||
<Navigator
|
||||
className='list-item'
|
||||
open-type='navigateTo'
|
||||
url={`/marketing/pages/distribution/goods?status=${
|
||||
info.isOpenShop && info.shop_status === 1
|
||||
}`}
|
||||
url={`/marketing/pages/distribution/goods?status=${info.isOpenShop && info.shop_status === 1
|
||||
}`}
|
||||
>
|
||||
<View className='iconfont icon-weChat icon-fontsize' />
|
||||
<View className='list-item-txt'>推广商品</View>
|
||||
@@ -519,9 +318,9 @@ export default class DistributionDashboard extends Component {
|
||||
className={classNames(
|
||||
'cicle',
|
||||
(adapay_status == '审核中' && 'approve') ||
|
||||
(adapay_status == '未认证' && 'NotCertified') ||
|
||||
(adapay_status == '认证失败' && 'fail') ||
|
||||
(adapay_status == '已认证' && 'success')
|
||||
(adapay_status == '未认证' && 'NotCertified') ||
|
||||
(adapay_status == '认证失败' && 'fail') ||
|
||||
(adapay_status == '已认证' && 'success')
|
||||
)}
|
||||
/>
|
||||
<View style={{ marginRight: '15rpx' }}>{adapay_status}</View>
|
||||
@@ -555,8 +354,8 @@ export default class DistributionDashboard extends Component {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Canvas className='canvas' canvas-id='myCanvas' width={canvasWidth}
|
||||
height={canvasHeight} id='myCanvas'></Canvas>
|
||||
{/* <Canvas className='canvas' canvas-id='myCanvas' width={canvasWidth}
|
||||
height={canvasHeight} id='myCanvas'></Canvas> */}
|
||||
</SpPage>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ const initialState = {
|
||||
locationIng: false,
|
||||
chooseValue: ['北京市', '北京市', '昌平区'],
|
||||
keyword: '', // 参数
|
||||
type: 0, // 参数
|
||||
type: 0, // 0:正常流程 1:基于省市区过滤 2:基于默认收货地址强制定位
|
||||
search_type: undefined, // 参数
|
||||
isSpAddressOpened: false,
|
||||
}
|
||||
@@ -37,9 +37,14 @@ function NearlyShop(props) {
|
||||
const dispatch = useDispatch()
|
||||
|
||||
useEffect(() => {
|
||||
// fetchAddressList()
|
||||
if (address) {
|
||||
shopRef.current.reset()
|
||||
}
|
||||
return () => {
|
||||
dispatch(updateChooseAddress(null)) // 清空地址信息
|
||||
}
|
||||
// onPickerClick()
|
||||
}, [])
|
||||
}, [address])
|
||||
|
||||
const fetchShop = async (params) => {
|
||||
const { pageIndex: page, pageSize } = params
|
||||
@@ -62,7 +67,7 @@ function NearlyShop(props) {
|
||||
const { list, total_count: total, defualt_address } = await api.shop.list(query)
|
||||
|
||||
setState((v) => {
|
||||
v.shopList = uniqueFunc(v.shopList.concat(pickBy(list, doc.shop.SHOP_ITEM)),'distributor_id')
|
||||
v.shopList = uniqueFunc(v.shopList.concat(pickBy(list, doc.shop.SHOP_ITEM)), 'distributor_id')
|
||||
v.chooseValue = [query.province, query.city, query.area]
|
||||
})
|
||||
|
||||
@@ -195,7 +200,7 @@ function NearlyShop(props) {
|
||||
selectValue[1].label,
|
||||
selectValue[2].label
|
||||
]
|
||||
setState((v)=>{
|
||||
setState((v) => {
|
||||
v.chooseValue = chooseValue
|
||||
v.type = 1
|
||||
})
|
||||
@@ -210,7 +215,7 @@ function NearlyShop(props) {
|
||||
<View className='search-block'>
|
||||
<View className='search-bar'>
|
||||
<View className='region-picker'>
|
||||
<SpAddress isOpened={isSpAddressOpened} onClose={handleClickCloseSpAddress} onChange={onPickerChange}/>
|
||||
<SpAddress isOpened={isSpAddressOpened} onClose={handleClickCloseSpAddress} onChange={onPickerChange} />
|
||||
<View className='pick-title' onClick={handleClickOpenSpAddress}>
|
||||
<View className='iconfont icon-periscope'></View>
|
||||
<Text className='pick-address'>{chooseValue.join('') || '选择地区'}</Text>
|
||||
@@ -253,7 +258,7 @@ function NearlyShop(props) {
|
||||
</View>
|
||||
<View className='block-title block-flex'>
|
||||
<View>我的收货地址</View>
|
||||
{address && (
|
||||
{!address && (
|
||||
<View
|
||||
className='arrow'
|
||||
onClick={() =>
|
||||
|
||||
@@ -138,34 +138,28 @@ function PointShopEspierCheckout() {
|
||||
return
|
||||
}
|
||||
|
||||
setState(
|
||||
(draft) => {
|
||||
draft.submitLoading = true
|
||||
},
|
||||
async () => {
|
||||
if (isWeixin) {
|
||||
const templeparams = {
|
||||
temp_name: 'yykweishop',
|
||||
source_type: receiptType === 'logistics' ? 'logistics_order' : 'ziti_order'
|
||||
}
|
||||
const { template_id } = await api.user.newWxaMsgTmpl(templeparams)
|
||||
Taro.requestSubscribeMessage({
|
||||
tmplIds: template_id,
|
||||
success: () => {
|
||||
handlePay()
|
||||
},
|
||||
fail: () => {
|
||||
handlePay()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
handlePay()
|
||||
}
|
||||
if (isWeixin) {
|
||||
const templeparams = {
|
||||
temp_name: 'yykweishop',
|
||||
source_type: receiptType === 'logistics' ? 'logistics_order' : 'ziti_order'
|
||||
}
|
||||
)
|
||||
const { template_id } = await api.user.newWxaMsgTmpl(templeparams)
|
||||
try {
|
||||
await Taro.requestSubscribeMessage({ tmplIds: template_id })
|
||||
handlePay()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
handlePay()
|
||||
}
|
||||
} else {
|
||||
handlePay()
|
||||
}
|
||||
}
|
||||
|
||||
const handlePay = async () => {
|
||||
setState((draft) => {
|
||||
draft.submitLoading = true
|
||||
})
|
||||
const params = await getParamsInfo()
|
||||
console.log('trade params:', params)
|
||||
if (payType === 'deposit') {
|
||||
|
||||
Reference in New Issue
Block a user