678744e3 by simon

版本提交

1 parent 28e34513
Showing 40 changed files with 1705 additions and 28 deletions
......@@ -33,6 +33,7 @@ App({
loading: true,
}).then((result) => {
this.globalData.indexInfo = result;
this.globalData.userInfo = result.userInfo;
if (result.isNeedAuth == 1) {
//需要授权
this.router.push({
......
......@@ -105,6 +105,7 @@
// 通用按钮
@mixin cb($width:320px, $height:80px, $fontSize:32px) {
font-weight: 300;
position: relative;
width: $width;
height: $height;
......
let app = getApp();
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod() {
this.triggerEvent('evtcomp', {
name: "_evt_custom"
})
},
// 隐藏蒙层
hideMask() {
this.triggerEvent('evtcomp', {
name: "_evt_hide_mask"
});
},
toMyWishHandler() {
app.router.push({
openType: "reLaunchs",
path: "wish"
})
}
}
})
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.comp-item {
position: relative;
width: 654px;
height: 732px;
font-weight: 300;
// background-color: wheat;
.bg {
position: absolute;
width: 654px;
height: 732px;
}
.cont {
position: relative;
text-align: center;
color: #333333;
.space1 {
height: 92px;
}
.tit {
color: #ba3038;
font-size: 36px;
}
.tips {
margin-top: 42px;
font-size: 32px;
.val {
color: #ba3138;
}
}
}
.btn-wrap {
position: absolute;
left: 0;
right: 0;
bottom: 100px;
display: flex;
justify-content: center;
padding: 0 50px;
@extend .bb;
.btn {
margin: 0 auto;
@include cb(234px, 64px);
}
.btn2 {
border: solid 1px #b83138;
background: transparent;
color: #ba3039;
}
}
}
// 心愿
.wish {
position: relative;
margin: 0 auto 0;
display: flex;
justify-content: space-between;
@extend .bb;
// padding-top: 116px;
padding: 56px 80px 0;
&-item {
position: relative;
text-align: center;
.display {
position: relative;
width: 140px;
height: 140px;
border-radius: 70px;
background-image: radial-gradient(circle at 0 0, #ffffff, #f2e6e6);
@extend .fcc;
.prod {
max-width: 200px;
max-height: 200px;
margin-bottom: 10px;
}
.close {
width: 30px;
height: 30px;
position: absolute;
bottom: 0;
right: 0;
}
}
.name {
width: 160px;
margin: 8px auto 0;
color: #333333;
font-size: 20px;
// font-weight: 300;
}
.val {
@extend .fcc;
color: #b93138;
font-size: 20px;
margin-top: 12px;
.icon {
margin-left: 6px;
width: 11px;
height: 18px;
}
}
}
}
<view class="comp-item">
<image class="bg" src="../../image/oss/tips/tips-create-complete.png" mode="widthFix" />
<view class="cont">
<view class="space1"></view>
<view class="tit">· 太棒了 ·</view>
<view class="tips">
共获得
<span class="val">100</span>
弹力值
</view>
<!-- 心愿容器 -->
<view class="wish">
<view class="wish-item">
<view class="display">
<image class="prod" mode="aspectFit" src="../../image/oss/prize/prize_3.png" />
<!-- <image class="close" mode="widthFix" src="../../image/oss/create-wish/cw-close-btn.png" /> -->
</view>
<!-- <view class="name">丸美弹力蛋白凝时紧致乳</view> -->
<view class="val">
<image class="icon" mode="widthFix" src="../../image/oss/create-wish/cw-light.png" />
获得20
</view>
</view>
<view class="wish-item">
<view class="display">
<image class="prod" mode="aspectFit" src="../../image/oss/prize/prize_2.png" />
<!-- <image class="close" mode="widthFix" src="../../image/oss/create-wish/cw-close-btn.png" /> -->
</view>
<!-- <view class="name">丸美弹力蛋白凝时紧致乳</view> -->
<view class="val">
<image class="icon" mode="widthFix" src="../../image/oss/create-wish/cw-light.png" />
获得20
</view>
</view>
<view class="wish-item">
<view class="display">
<image class="prod" mode="aspectFit" src="../../image/oss/prize/prize_1.png" />
<!-- <image class="close" mode="widthFix" src="../../image/oss/create-wish/cw-close-btn.png" /> -->
</view>
<!-- <view class="name">丸美弹力蛋白凝时紧致乳</view> -->
<view class="val">
<image class="icon" mode="widthFix" src="../../image/oss/create-wish/cw-light.png" />
获得20
</view>
</view>
</view>
</view>
<view class="btn-wrap">
<view bindtap="toMyWishHandler" class="btn">立即查看</view>
</view>
</view>
......@@ -24,8 +24,12 @@ Component({
this.triggerEvent('_evt_hide_mask', {
name: "_evt_custom"
})
// app.router.push({
// path:"question"
// })
app.router.push({
path:"question"
openType: "reLaunchs",
path: "wish"
})
}
}
......
......@@ -4,13 +4,13 @@
.comp-item {
position: relative;
width: 654px;
height: 588px;
height: 861px;
// background-color: wheat;
.bg {
position: absolute;
width: 654px;
height: 588px;
height: 861px;
}
.space1 {
......
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod() {
this.triggerEvent('evtcomp', {
name: "_evt_custom"
})
},
// 隐藏蒙层
hideMask() {
this.triggerEvent('evtcomp', {
name: "_evt_hide_mask"
});
},
onCreateHandler(){
this.triggerEvent('evtcomp', {
name: "_evt_create_wish"
});
}
}
})
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.comp-item {
position: relative;
width: 654px;
height: 951px;
// background-color: wheat;
.bg {
position: absolute;
width: 654px;
height: 951px;
}
.cont {
position: relative;
.space1 {
height: 250px;
}
// 心愿列表
.wish {
@extend .bb;
padding: 0 80px;
.row {
display: flex;
}
.row2 {
justify-content: flex-end;
.desc {
padding-left: 32px;
}
}
.wish-item {
width: 420px;
height: 122px;
box-shadow: 0px 6px 30px 0 rgba(0, 0, 0, 0.3);
background-color: #ffffff;
display: flex;
justify-content: center;
margin-bottom: 32px;
.prod {
position: relative;
width: 122px;
height: 122px;
text-align: center;
image {
position: absolute;
max-width: 120px;
max-height: 120px;
bottom: 12px;
left: 0;
right: 0;
margin: 0 auto;
}
}
.desc {
width: 300px;
font-weight: 300;
font-size: 22px;
display: flex;
flex-wrap: wrap;
align-content: center;
@extend .bb;
.name {
color: #333333;
}
.val {
font-size: 18px;
color: #999999;
margin-top: 4px;
}
}
}
&-item2 {
justify-self: flex-end;
align-self: flex-end;
}
}
// 累计心愿值
.wish-val {
@extend .fcc;
color: #333333;
font-size: 24px;
.icon {
width: 12px;
height: 25px;
margin-right: 8px;
}
.val {
color: #b93138;
}
}
}
.btn-wrap {
position: absolute;
left: 0;
right: 0;
bottom: 100px;
display: flex;
justify-content: center;
padding: 0 50px;
@extend .bb;
.btn {
margin: 0 auto;
@include cb(234px, 64px);
}
.btn2 {
border: solid 1px #b83138;
background: transparent;
color: #ba3039;
}
}
}
<view class="comp-item">
<image class="bg" src="../../image/oss/tips/tips-wish.png" mode="widthFix" />
<view class="cont">
<view class="space1"></view>
<view class="wish">
<view class="row">
<view class="wish-item">
<view class="prod">
<image mode="widthFix" src="../../image/oss/prize/prize_1.png" />
</view>
<view class="desc">
<view class="name">丸美弹力蛋白凝时紧致乳</view>
<view class="val">需弹力值:5480</view>
</view>
</view>
</view>
<view class="row row2">
<view class="wish-item ">
<view class="desc">
<view class="name">丸美弹力蛋白凝时紧致乳</view>
<view class="val">需弹力值:5480</view>
</view>
<view class="prod">
<image mode="widthFix" src="../../image/oss/prize/prize_2.png" />
</view>
</view>
</view>
<view class="row">
<view class="wish-item">
<view class="prod">
<image mode="widthFix" src="../../image/oss/prize/prize_3.png" />
</view>
<view class="desc">
<view class="name">丸美弹力蛋白凝时紧致乳</view>
<view class="val">需弹力值:5480</view>
</view>
</view>
</view>
</view>
<view class="wish-val">
<image class="icon" mode="widthFix" src="../../image/oss/question/question-light.png" />
累计心愿单所需弹力值:
<span class="val">2500</span>
</view>
</view>
<view class="btn-wrap">
<view bindtap="hideMask" class="btn btn2">返回修改</view>
<view bindtap="onCreateHandler" class="btn">马上创建</view>
</view>
</view>
......@@ -22,4 +22,5 @@ module.exports = {
wishbillAcceptTypeSubmit: '/warubiEyeCreamApi/app/wishbill/accept/type/submit', // post 提交礼品领取方式
wishbillAddressSubmit: '/warubiEyeCreamApi/app/wishbill/address/submit', // post 提交邮寄地址
wishbillStoreAppoint: '/warubiEyeCreamApi/app/wishbill/store/appoint', // post 预约自提门店
wxacodeGet: '/warubiEyeCreamApi/app/qrcode/create', //
}
......
const main = {
/**
* 渲染块
* @param {Object} params
*/
drawBlock({ text, width = 0, height, x, y, paddingLeft = 0, paddingRight = 0, borderWidth, backgroundColor, borderColor, borderRadius = 0, opacity = 1 }) {
// 判断是否块内有文字
let blockWidth = 0; // 块的宽度
let textX = 0;
let textY = 0;
if (typeof text !== 'undefined') {
// 如果有文字并且块的宽度小于文字宽度,块的宽度为 文字的宽度 + 内边距
const textWidth = this._getTextWidth(typeof text.text === 'string' ? text : text.text);
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) {
// 画面
this.ctx.save();
this.ctx.setGlobalAlpha(opacity);
this.ctx.setFillStyle(backgroundColor);
if (borderRadius > 0) {
// 画圆角矩形
this._drawRadiusRect(x, y, blockWidth, height, borderRadius);
this.ctx.fill();
} else {
this.ctx.fillRect(this.toPx(x), this.toPx(y), this.toPx(blockWidth), this.toPx(height));
}
this.ctx.restore();
}
if (borderWidth) {
// 画线
this.ctx.save();
this.ctx.setGlobalAlpha(opacity);
this.ctx.setStrokeStyle(borderColor);
this.ctx.setLineWidth(this.toPx(borderWidth));
if (borderRadius > 0) {
// 画圆角矩形边框
this._drawRadiusRect(x, y, blockWidth, height, borderRadius);
this.ctx.stroke();
} else {
this.ctx.strokeRect(this.toPx(x), this.toPx(y), this.toPx(blockWidth), this.toPx(height));
}
this.ctx.restore();
}
if (text) {
this.drawText(Object.assign(text, { x: textX, y: textY }))
}
},
/**
* 渲染文字
* @param {Object} params
*/
drawText(params) {
const { x, y, fontSize, color, baseLine, textAlign, text, opacity = 1, width, lineNum, lineHeight } = params;
if (Object.prototype.toString.call(text) === '[object Array]') {
let preText = { x, y, baseLine };
text.forEach(item => {
preText.x += item.marginLeft || 0;
const textWidth = this._drawSingleText(Object.assign(item, {
...preText,
}));
preText.x += textWidth + (item.marginRight || 0); // 下一段字的x轴为上一段字x + 上一段字宽度
})
} else {
this._drawSingleText(params);
}
},
/**
* 渲染图片
*/
drawImage(data) {
const { imgPath, x, y, w, h, sx, sy, sw, sh, borderRadius = 0, borderWidth = 0, borderColor } = data;
this.ctx.save();
if (borderRadius > 0) {
this._drawRadiusRect(x, y, w, h, borderRadius);
this.ctx.strokeStyle = 'rgba(255,255,255,0)';
this.ctx.stroke();
this.ctx.clip();
this.ctx.drawImage(imgPath, this.toPx(sx), this.toPx(sy), this.toPx(sw), this.toPx(sh), this.toPx(x), this.toPx(y), this.toPx(w), this.toPx(h));
if (borderWidth > 0) {
this.ctx.setStrokeStyle(borderColor);
this.ctx.setLineWidth(this.toPx(borderWidth));
this.ctx.stroke();
}
} else {
this.ctx.drawImage(imgPath, this.toPx(sx), this.toPx(sy), this.toPx(sw), this.toPx(sh), this.toPx(x), this.toPx(y), this.toPx(w), this.toPx(h));
}
this.ctx.restore();
},
/**
* 渲染线
* @param {*} param0
*/
drawLine({ startX, startY, endX, endY, color, width }) {
this.ctx.save();
this.ctx.beginPath();
this.ctx.setStrokeStyle(color);
this.ctx.setLineWidth(this.toPx(width));
this.ctx.moveTo(this.toPx(startX), this.toPx(startY));
this.ctx.lineTo(this.toPx(endX), this.toPx(endY));
this.ctx.stroke();
this.ctx.closePath();
this.ctx.restore();
},
downloadResource(images = []) {
const drawList = [];
this.drawArr = [];
images.forEach((image, index) => drawList.push(this._downloadImageAndInfo(image, index)));
return Promise.all(drawList);
},
initCanvas(w, h, debug) {
return new Promise((resolve) => {
this.setData({
pxWidth: this.toPx(w),
pxHeight: this.toPx(h),
debug,
}, resolve);
});
}
}
const handle = {
/**
* 画圆角矩形
*/
_drawRadiusRect(x, y, w, h, r) {
const br = r / 2;
this.ctx.beginPath();
this.ctx.moveTo(this.toPx(x + br), this.toPx(y)); // 移动到左上角的点
this.ctx.lineTo(this.toPx(x + w - br), this.toPx(y));
this.ctx.arc(this.toPx(x + w - br), this.toPx(y + br), this.toPx(br), 2 * Math.PI * (3 / 4), 2 * Math.PI * (4 / 4))
this.ctx.lineTo(this.toPx(x + w), this.toPx(y + h - br));
this.ctx.arc(this.toPx(x + w - br), this.toPx(y + h - br), this.toPx(br), 0, 2 * Math.PI * (1 / 4))
this.ctx.lineTo(this.toPx(x + br), this.toPx(y + h));
this.ctx.arc(this.toPx(x + br), this.toPx(y + h - br), this.toPx(br), 2 * Math.PI * (1 / 4), 2 * Math.PI * (2 / 4))
this.ctx.lineTo(this.toPx(x), this.toPx(y + br));
this.ctx.arc(this.toPx(x + br), this.toPx(y + br), this.toPx(br), 2 * Math.PI * (2 / 4), 2 * Math.PI * (3 / 4))
},
/**
* 计算文本长度
* @param {Array|Object}} text 数组 或者 对象
*/
_getTextWidth(text) {
let texts = [];
if (Object.prototype.toString.call(text) === '[object Object]') {
texts.push(text);
} else {
texts = text;
}
let width = 0;
texts.forEach(({ fontSize, text, marginLeft = 0, marginRight = 0 }) => {
this.ctx.setFontSize(this.toPx(fontSize));
width += this.ctx.measureText(text).width + marginLeft + marginRight;
})
return this.toRpx(width);
},
/**
* 渲染一段文字
*/
_drawSingleText({ x, y, fontSize, color, baseLine, textAlign = 'left', text, opacity = 1, textDecoration = 'none',
width, lineNum = 1, lineHeight = 0, fontWeight = 'normal', fontStyle = 'normal', fontFamily = "sans-serif"}) {
this.ctx.save();
this.ctx.beginPath();
this.ctx.font = fontStyle + " " + fontWeight + " " + this.toPx(fontSize, true) + "px " + fontFamily
this.ctx.setGlobalAlpha(opacity);
// this.ctx.setFontSize(this.toPx(fontSize));
this.ctx.setFillStyle(color);
this.ctx.setTextBaseline(baseLine);
this.ctx.setTextAlign(textAlign);
let textWidth = this.toRpx(this.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 (this.toRpx(this.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) => {
this.ctx.fillText(item, this.toPx(x), this.toPx(y + (lineHeight || fontSize) * index));
})
this.ctx.restore();
// textDecoration
if (textDecoration !== 'none') {
let lineY = y;
if (textDecoration === 'line-through') {
// 目前只支持贯穿线
lineY = y;
}
this.ctx.save();
this.ctx.moveTo(this.toPx(x), this.toPx(lineY));
this.ctx.lineTo(this.toPx(x) + this.toPx(textWidth), this.toPx(lineY));
this.ctx.setStrokeStyle(color);
this.ctx.stroke();
this.ctx.restore();
}
return textWidth;
},
}
const helper = {
/**
* 下载图片并获取图片信息
*/
_downloadImageAndInfo(image, index) {
return new Promise((resolve, reject) => {
const { x, y, url, zIndex } = image;
const imageUrl = url;
// 下载图片
this._downImage(imageUrl, index)
// 获取图片信息
.then(imgPath => this._getImageInfo(imgPath, index))
.then(({ imgPath, imgInfo }) => {
// 根据画布的宽高计算出图片绘制的大小,这里会保证图片绘制不变形
let sx;
let sy;
const borderRadius = image.borderRadius || 0;
const setWidth = image.width;
const setHeight = image.height;
const width = this.toRpx(imgInfo.width);
const height = this.toRpx(imgInfo.height);
if (width / height <= setWidth / setHeight) {
sx = 0;
sy = (height - ((width / setWidth) * setHeight)) / 2;
} else {
sy = 0;
sx = (width - ((height / setHeight) * setWidth)) / 2;
}
this.drawArr.push({
type: 'image',
borderRadius,
borderWidth: image.borderWidth,
borderColor: image.borderColor,
zIndex: typeof zIndex !== 'undefined' ? zIndex : index,
imgPath,
sx,
sy,
sw: (width - (sx * 2)),
sh: (height - (sy * 2)),
x,
y,
w: setWidth,
h: setHeight,
});
resolve();
})
.catch(err => reject(err));
});
},
/**
* 下载图片资源
* @param {*} imageUrl
*/
_downImage(imageUrl) {
return new Promise((resolve, reject) => {
if (/^http/.test(imageUrl) && !new RegExp(wx.env.USER_DATA_PATH).test(imageUrl)) {
wx.downloadFile({
url: this._mapHttpToHttps(imageUrl),
success: (res) => {
if (res.statusCode === 200) {
resolve(res.tempFilePath);
} else {
reject(res.errMsg);
}
},
fail(err) {
reject(err);
},
});
} else {
// 支持本地地址
resolve(imageUrl);
}
});
},
/**
* 获取图片信息
* @param {*} imgPath
* @param {*} index
*/
_getImageInfo(imgPath, index) {
return new Promise((resolve, reject) => {
wx.getImageInfo({
src: imgPath,
success(res) {
resolve({ imgPath, imgInfo: res, index });
},
fail(err) {
reject(err);
},
});
});
},
toPx(rpx, int) {
if (int) {
return parseInt(rpx * this.factor);
}
return rpx * this.factor;
},
toRpx(px, int) {
if (int) {
return parseInt(px / this.factor);
}
return px / this.factor;
},
/**
* 将http转为https
* @param {String}} rawUrl 图片资源url
*/
_mapHttpToHttps(rawUrl) {
if (rawUrl.indexOf(':') < 0) {
return rawUrl;
}
const urlComponent = rawUrl.split(':');
if (urlComponent.length === 2) {
if (urlComponent[0] === 'http') {
urlComponent[0] = 'https';
return `${urlComponent[0]}:${urlComponent[1]}`;
}
}
return rawUrl;
},
}
Component({
properties: {
},
created() {
const sysInfo = wx.getSystemInfoSync();
const screenWidth = sysInfo.screenWidth;
this.factor = screenWidth / 750;
},
methods: Object.assign({
/**
* 计算画布的高度
* @param {*} config
*/
getHeight(config) {
const getTextHeight = (text) => {
let fontHeight = text.lineHeight || text.fontSize;
let height = 0;
if (text.baseLine === 'top') {
height = fontHeight;
} else if (text.baseLine === 'middle') {
height = fontHeight / 2;
} else {
height = 0;
}
return height;
}
const heightArr = [];
(config.blocks || []).forEach((item) => {
heightArr.push(item.y + item.height);
});
(config.texts || []).forEach((item) => {
let height;
if (Object.prototype.toString.call(item.text) === '[object Array]') {
item.text.forEach((i) => {
height = getTextHeight({...i, baseLine: item.baseLine});
heightArr.push(item.y + height);
});
} else {
height = getTextHeight(item);
heightArr.push(item.y + height);
}
});
(config.images || []).forEach((item) => {
heightArr.push(item.y + item.height);
});
(config.lines || []).forEach((item) => {
heightArr.push(item.startY);
heightArr.push(item.endY);
});
const sortRes = heightArr.sort((a, b) => b - a);
let canvasHeight = 0;
if (sortRes.length > 0) {
canvasHeight = sortRes[0];
}
if (config.height < canvasHeight || !config.height) {
return canvasHeight;
} else {
return config.height;
}
},
create(config) {
this.ctx = wx.createCanvasContext('canvasid', this);
const height = this.getHeight(config);
this.initCanvas(config.width, height, config.debug)
.then(() => {
// 设置画布底色
if (config.backgroundColor) {
this.ctx.save();
this.ctx.setFillStyle(config.backgroundColor);
this.ctx.fillRect(0, 0, this.toPx(config.width), this.toPx(height));
this.ctx.restore();
}
const { texts = [], images = [], blocks = [], lines = [] } = config;
const queue = this.drawArr
.concat(texts.map((item) => {
item.type = 'text';
item.zIndex = item.zIndex || 0;
return item;
}))
.concat(blocks.map((item) => {
item.type = 'block';
item.zIndex = item.zIndex || 0;
return item;
}))
.concat(lines.map((item) => {
item.type = 'line';
item.zIndex = item.zIndex || 0;
return item;
}));
// 按照顺序排序
queue.sort((a, b) => a.zIndex - b.zIndex);
queue.forEach((item) => {
if (item.type === 'image') {
this.drawImage(item)
} else if (item.type === 'text') {
this.drawText(item)
} else if (item.type === 'block') {
this.drawBlock(item)
} else if (item.type === 'line') {
this.drawLine(item)
}
});
const res = wx.getSystemInfoSync();
const platform = res.platform;
let time = 0;
if (platform === 'android') {
// 在安卓平台,经测试发现如果海报过于复杂在转换时需要做延时,要不然样式会错乱
time = 300;
}
this.ctx.draw(false, () => {
setTimeout(() => {
wx.canvasToTempFilePath({
canvasId: 'canvasid',
success: (res) => {
this.triggerEvent('success', res.tempFilePath);
},
fail: (err) => {
this.triggerEvent('fail', err);
},
}, this);
}, time);
});
})
.catch((err) => {
wx.showToast({ icon: 'none', title: err.errMsg || '生成失败' });
console.error(err);
});
},
}, main, handle, helper),
});
{
"component": true
}
\ No newline at end of file
<!--index.wxml-->
<view class="container">
<canvas canvas-id='canvasid' class="canvas {{debug ? 'debug' : 'pro'}}" style='width: {{pxWidth}}px; height: {{pxHeight}}px;'></canvas>
</view>
.canvas {
width: 750rpx;
height: 750rpx;
}
.canvas.pro {
position: absolute;
bottom: 0;
left: 0;
transform: translate3d(-9999rpx, 0, 0);
}
.canvas.debug {
position: absolute;
bottom: 0;
left: 0;
border: 1rpx solid #ccc;
}
\ No newline at end of file
Component({
properties: {
config: {
type: Object,
value: {},
},
preload: { // 是否预下载图片资源
type: Boolean,
value: false,
},
hideLoading: { // 是否隐藏loading
type: Boolean,
value: false,
}
},
ready() {
if (this.data.preload) {
const poster = this.selectComponent('#poster');
this.downloadStatus = 'doing';
poster.downloadResource(this.data.config.images).then(() => {
this.downloadStatus = 'success';
this.trigger('downloadSuccess');
}).catch((e) => {
this.downloadStatus = 'fail';
this.trigger('downloadFail', e);
});
}
},
methods: {
trigger(event, data) {
if (this.listener && typeof this.listener[event] === 'function') {
this.listener[event](data);
}
},
once(event, fun) {
if (typeof this.listener === 'undefined') {
this.listener = {};
}
this.listener[event] = fun;
},
downloadResource(reset) {
return new Promise((resolve, reject) => {
if (reset) {
this.downloadStatus = null;
}
const poster = this.selectComponent('#poster');
if (this.downloadStatus && this.downloadStatus !== 'fail') {
if (this.downloadStatus === 'success') {
resolve();
} else {
this.once('downloadSuccess', () => resolve());
this.once('downloadFail', (e) => reject(e));
}
} else {
poster.downloadResource(this.data.config.images)
.then(() => {
this.downloadStatus = 'success';
resolve();
})
.catch((e) => reject(e));
}
})
},
onCreate(reset = false) {
!this.data.hideLoading && wx.showLoading({ mask: true, title: '生成中' });
return this.downloadResource(typeof reset === 'boolean' && reset).then(() => {
!this.data.hideLoading && wx.hideLoading();
const poster = this.selectComponent('#poster');
poster.create(this.data.config);
})
.catch((err) => {
!this.data.hideLoading && wx.hideLoading();
wx.showToast({ icon: 'none', title: err.errMsg || '生成失败' });
console.error(err);
this.triggerEvent('fail', err);
})
},
onCreateSuccess(e) {
const { detail } = e;
this.triggerEvent('success', detail);
},
onCreateFail(err) {
console.error(err);
this.triggerEvent('fail', err);
}
}
})
\ No newline at end of file
{
"component": true,
"usingComponents": {
"we-canvas": "../index/index"
}
}
\ No newline at end of file
<view bindtap='onCreate'>
<slot/>
</view>
<we-canvas id="poster" bind:success="onCreateSuccess" bind:fail="onCreateFail"/>
\ No newline at end of file
const defaultOptions = {
selector: '#poster'
};
function Poster(options = {}) {
options = {
...defaultOptions,
...options,
};
const pages = getCurrentPages();
const ctx = pages[pages.length - 1];
const poster = ctx.selectComponent(options.selector);
delete options.selector;
return poster;
};
Poster.create = (reset = false) => {
const poster = Poster();
if (!poster) {
console.error('请设置组件的id="poster"!!!');
} else {
return Poster().onCreate(reset);
}
}
export default Poster;
\ No newline at end of file
......@@ -4,6 +4,9 @@ Page({
tipsRegisterVisible: false,
tipsGroupMemberVisible: false,
tipsNewMemberVisible: false,
tipsWishVisible: false,
tipsShakeVisible: false,
tipsCreateCompleteVisible: true,
curStatus: 1, // 当前场景
candidate: [], // 心愿候选列表
myWishList: [], // 我的心愿列表
......@@ -16,7 +19,6 @@ Page({
app.queryIndex().then((result) => {
this.queryWishbillPrizeCandidate();
});
},
/**
* 点击提交心愿单按钮
......@@ -50,6 +52,7 @@ Page({
wishBillCode
} = indexInfo;
// 未登陆 出注册弹窗提示
// isCrmLogin = 1;
if (isCrmLogin == 0) {
this.setData({
tipsRegisterVisible: true
......@@ -67,7 +70,7 @@ Page({
}
// 新老会员
// isNewMember
hadAnswerQuestion = 1; //硬编码答题
// hadAnswerQuestion = 1; //硬编码答题
if (isNewMember == 1) {
// 新会员
if (hadAnswerQuestion) {
......@@ -75,7 +78,10 @@ Page({
// todo 校验选择
// 校验完成后显示提示
this.queryWishbillCreate();
this.setData({
tipsWishVisible: true
});
// this.queryWishbillCreate();
} else {
// 未答题,提示答题
this.setData({
......@@ -148,13 +154,24 @@ Page({
data
} = evt.detail;
switch (name) {
// 隐藏蒙层
case "_evt_hide_mask":
this.setData({
ruleTipsVisible: false,
tipsGroupMemberVisible: false,
tipsNewMemberVisible: false,
tipsWishVisible: false,
tipsWishVisible:false,
tipsCreateCompleteVisible:false,
})
break;
// 创建心愿单
case "_evt_create_wish":
this.setData({
tipsWishVisible: false
})
this.queryWishbillCreate();
break;
default:
......
......@@ -4,6 +4,9 @@
"tips-register-comp": "../../component/tips-register-comp/tips-register-comp",
"tips-group-member-comp": "../../component/tips-group-member-comp/tips-group-member-comp",
"tips-new-comp": "../../component/tips-new-comp/tips-new-comp",
"tips-wish-comp": "../../component/tips-wish-comp/tips-wish-comp",
"tips-shake-comp": "../../component/tips-shake-comp/tips-shake-comp",
"tips-create-complete-comp": "../../component/tips-create-complete-comp/tips-create-complete-comp",
"van-popup": "../../ui/vant-weapp/popup/index"
}
}
......
......@@ -9,7 +9,6 @@
background-color: #ffd5da;
}
.bg {
image {
position: absolute;
......
......@@ -66,3 +66,12 @@
<van-popup show="{{ tipsNewMemberVisible }}">
<tips-new-comp bind:evtcomp="evtcomp"></tips-new-comp>
</van-popup>
<van-popup show="{{ tipsWishVisible }}">
<tips-wish-comp bind:evtcomp="evtcomp"></tips-wish-comp>
</van-popup>
<van-popup show="{{ tipsShakeVisible }}">
<tips-shake-comp bind:evtcomp="evtcomp"></tips-shake-comp>
</van-popup>
<van-popup show="{{ tipsCreateCompleteVisible }}">
<tips-create-complete-comp bind:evtcomp="evtcomp"></tips-create-complete-comp>
</van-popup>
......
......@@ -35,7 +35,7 @@ Page({
} = evt.detail;
switch (name) {
case "_evt_hide_rule_tips":
case "_evt_hide_mask":
this.setData({
tipsRuleVisible: false
})
......
import Poster from '../../miniprogram_dist/poster/poster';
let app = getApp();
Page({
data: {},
onShareAppMessage() {},
onLoad(options) {},
data: {
imageUrl: "", // 海报图片
wxShareTitle: "", // 分享标题
wxCodePath: "", // 微信二维码参数地址,分享链接公用
wxCodeUrl: "", // 微信二维码图片地址
},
onShareAppMessage() {
if (res.from === 'button') {
// 来自页面内转发按钮
console.log(res.target)
}
let title = this.data.wxShareTitle;
let path = this.data.wxCodePath;
let imageUrl = this.data.imageUrl;
console.log("title:", title);
console.log("path:", path);
console.log("imageUrl:", imageUrl);
return {
title,
path,
imageUrl
}
},
onLoad(options) {
app.queryIndex().then((result) => {
console.log("result:", result);
wx.showLoading({
title: '生成中',
});
this.initData();
})
},
initData() {
// 设置 分享链接,分享文案
let nickname = app.globalData.userInfo && app.globalData.userInfo.nickname || "";
let billCode = app.globalData.indexInfo.wishBillCode;
let wxShareTitle = nickname + `正在参加丸美眼霜节心愿单活动,需要你的倾情相助!`;
let wxCodePath = `/pages/coop/coop?billCode=${billCode}&s=share`
this.setData({
wxCodePath: wxCodePath,
wxShareTitle: wxShareTitle
})
// 获取小程序码
app.post({
url: app.api.wxacodeGet,
data: {
path: encodeURIComponent(wxCodePath)
}
}).then((result) => {
this.setData({
wxCodeUrl: result
})
// 获取海报数据
let posterData = this.getPosterConfig();
// 绘制设置海报
this.onCreatePoster(posterData);
})
// // 获取海报数据
// let posterData = this.getPosterConfig();
// // 绘制设置海报
// this.onCreatePoster(posterData);
},
onPosterSuccess(e) {
console.log("onPosterSuccess");
wx.hideLoading();
const {
detail
} = e;
console.log("detail:", detail)
this.setData({
imageUrl: detail
})
},
onPosterFail(err) {
wx.hideLoading();
console.error(err);
},
/**
* 查看图片
*/
onPreviewImage() {
let imageUrl = this.data.imageUrl
console.log("imageUrl:", imageUrl);
wx.previewImage({
current: imageUrl,
urls: [imageUrl]
})
},
/**
* 保存图片到本地
*/
saveImageToPhotosAlbum() {
let _this = this;
wx.saveImageToPhotosAlbum({
filePath: _this.data.imageUrl,
success(res) {
wx.showToast({
title: '海报保存成功',
icon: 'success'
});
},
fail(err) {
wx.getSetting({
success: (res) => {
if (!res.authSetting['scope.writePhotosAlbum']) {
// 未授权
wx.showModal({
title: '提示',
content: '小程序请求访问相册权限',
confirmText: '前往授权',
success(res) {
if (res.confirm) {
wx.openSetting({
success(res) {}
})
} else if (res.cancel) {}
}
})
}
}
})
}
})
},
/**
* 异步生成海报
*/
onCreatePoster(posterConfig) {
console.log("posterConfig:", posterConfig);
this.setData({
posterConfig: posterConfig
}, () => {
Poster.create(true); // 入参:true为抹掉重新生成
});
},
// 获取海报数据
getPosterConfig() {
// 合成图片需要的数据
let {
userInfo
} = app.globalData;
let codeUrl = this.data.wxCodeUrl;
let posterData = {
width: 700,
height: 921,
debug: false,
blocks: [],
images: [
// 底图
{
width: 700,
height: 921,
x: 0,
y: 0,
url: '../../image/draw/draw-c1.png',
},
// // 头像
// {
// width: 102,
// height: 102,
// x: 35,
// y: 700,
// url: userInfo.avatar,
// },
// 小程序码
{
width: 118,
height: 118,
x: 560,
y: 780,
url: codeUrl,
zIndex: 14
}
],
lines: [],
texts: [{
x: 165,
y: 810,
width: 360,
lineHeight: 32,
fontSize: 26,
lineNum: 3,
baseLine: 'middle',
text: `${userInfo.nickname}正在参加丸美眼霜节心愿单活动,需要你的倾情相助!`,
color: '#666666',
zIndex: 111
}],
}
return posterData;
},
// 子组件事件
evtcomp(evt) {
let {
......
{
"navigationBarTitleText": "more"
"navigationBarTitleText": "心愿单海报",
"usingComponents": {
"poster": "/miniprogram_dist/poster/index"
}
}
......
......@@ -4,15 +4,55 @@
.page {
.bgc {}
.bg {}
.bg {
position: fixed;
width: 100%;
height: 100%;
}
.main {
position: relative;
.top-space {
height: 0px;
height: 24px;
}
.content {
position: relative;
.poster-wrap {
width: 700px;
height: 921px;
margin: 0 auto;
.poster {
width: 700px;
height: 921px;
}
.tips {
margin-top: 10px;
color: #ebc6ce;
font-size: 26px;
@extend .bb;
padding: 0 10px;
font-weight: 300;
line-height: 1.5;
}
.download-btn {
margin: 28px auto 0;
border-radius: 40px;
background-image: linear-gradient(to right, #ffdcd4, #fdf2f0 51%, #ffdcd4);
color: #a73136;
font-size: 32px;
@include btc(300px, 80px);
}
}
}
}
}
......
<poster id="poster" hide-loading="{{true}}" preload="{{false}}" config="{{posterConfig}}" bind:success="onPosterSuccess" bind:fail="onPosterFail"></poster>
<view class="page">
<view class="app__bgc bgc"></view>
<view class="app__bg bg"></view>
<!-- <view class="app__top-shadow"></view> -->
<!-- <view class="app__bg bg"></view> -->
<image class="bg" mode="scaleToFill" src="../../image/oss/poster/poster-bg.png" />
<view class="app__content main">
<view class="top-space"></view>
<view class="content"></view>
<view class="content">
<view class="poster-wrap" wx:if="{{imageUrl}}">
<image bindtap="onPreviewImage" class="poster" src="{{imageUrl}}" mode="widthFix" />
<view class="tips">*您可以一键保存本海报或者长按直接分享给好友,让更多
人来为您助力哦!</view>
<view bindtap="saveImageToPhotosAlbum" class="download-btn">一键保存</view>
</view>
</view>
</view>
</view>
......
......@@ -20,7 +20,7 @@ Page({
// "state": 0
// }]
// },
questionResult:{},
questionResult: {},
// 答题结果
questionNumList: ["A", "B", "C", "D"],
myAnswer: [], //我的答案
......
......@@ -34,7 +34,7 @@
<image class="d2" mode="widthFix" src="../../image/oss/question/question-d2.png" />
<view class="cont">
<view class="space1"></view>
<view class="tit">测验结果:答对1题,答错2题</view>
<view class="tit">测验结果:答对{{questionResult.right}}题,答错{{questionResult.wrong}}题</view>
<view class="ball">
<view class="t1">获得</view>
<view class="score">{{questionResult.elasticValue}}</view>
......
let app = getApp();
Page({
data: {},
data: {
tipsRuleVisible: false,
userInfo: {},
wishInfo: {},
helperInfo: {}
},
onShareAppMessage() {},
onLoad(options) {},
onLoad(options) {
this.initData();
},
initData() {
app.queryIndex().then((result) => {
this.setData({
userInfo: app.globalData.userInfo
})
this.queryWishbillDetail();
this.queryWishbillHelpers();
})
},
// 显示规则页面
onShowRuleHandler() {
this.setData({
tipsRuleVisible: true
})
},
// 显示海报图
onCreatePosterHandler() {
app.router.push({
path: "poster"
})
},
// 获取心愿单详情
queryWishbillDetail() {
return new Promise((resolve, reject) => {
app.post({
url: app.api.wishbillDetail,
data: {
billCode: app.globalData.indexInfo.wishBillCode
}
}).then((result) => {
this.setData({
wishInfo: result
})
})
});
},
// 获取助力列表
queryWishbillHelpers() {
return new Promise((resolve, reject) => {
app.post({
url: app.api.wishbillHelpers,
data: {
billCode: app.globalData.indexInfo.wishBillCode,
page: 1,
size: 50
}
}).then((result) => {
this.setData({
helperInfo: result
})
})
});
},
// 子组件事件
evtcomp(evt) {
let {
......@@ -11,7 +71,10 @@ Page({
} = evt.detail;
switch (name) {
case "_evt_hide":
case "_evt_hide_mask":
this.setData({
tipsRuleVisible: false
})
break;
default:
......
{
"navigationBarTitleText": "more"
"navigationBarTitleText": "我的心愿单",
"usingComponents": {
"authorize-comp": "../../component/authorize-comp/authorize-comp",
"tips-rule-comp": "../../component/tips-rule-comp/tips-rule-comp",
"van-popup": "../../ui/vant-weapp/popup/index"
}
}
......
......@@ -2,17 +2,192 @@
@import '../../assets/scss/utils';
.page {
font-weight: 300;
padding-bottom: $pageBottom;
.bgc {}
.bg {}
.bg {
.b1 {
position: absolute;
width: 750px;
height: 576px;
}
.b1 {
position: absolute;
width: 750px;
height: 576px;
}
}
.decoration {
position: relative;
.d1 {
position: absolute;
width: 532px;
height: 847px;
top: 290px;
right: 0;
}
}
.main {
.top-space {
height: 0px;
height: 152px;
}
.content {
position: relative;
// 我的信息框
.my {
position: relative;
margin: 0 auto 0;
width: 742px;
height: 957px;
.ebg {
position: absolute;
width: 742px;
height: 957px;
}
.portrait {
position: absolute;
width: 182px;
height: 182px;
border-radius: 91px;
background-color: wheat;
left: 0;
right: 0;
top: -82px;
margin: 0 auto;
}
// 内容
.cont {
position: relative;
text-align: center;
// 占位
.space1 {
height: 118px;
}
.nickname {
color: #ba3039;
font-size: 36px;
}
.number {
color: #999999;
font-size: 24px;
}
.mycard {
margin: 16px auto;
border-radius: 24px;
box-shadow: 0px 2px 9px 0 rgba(0, 0, 0, 0.1);
background-color: #ffffff;
color: #bb3039;
@include btc(160px, 48px);
font-size: 24px;
}
}
// 海报按钮
.poster-btn {
position: absolute;
left: 0;
right: 0;
bottom: 42px;
margin: 0 auto;
box-shadow: 0px 2px 9px 0 rgba(0, 0, 0, 0.2);
background-image: linear-gradient(to right, #b83138, #f2234a 51%, #b83138);
color: #ffffff;
font-size: 28px;
@include btc(200px, 56px);
@include border-top-radius(28px);
}
}
// 协作
.coop {
margin-top: 60px;
text-align: center;
.tit {
color: #a01635;
font-size: 40px;
}
.tips {
margin-top: 16px;
color: #333333;
font-size: 24px;
.t1 {
color: #ba3039;
}
}
.list {
margin: 32px auto 0;
width: 654px;
height: 331px;
background-color: #fffbf8;
padding: 30px 20px;
@extend .bb;
overflow-y: auto;
&-item {
font-size: 22px;
width: 100%;
// margin: 12px 0;
margin-bottom: 20px;
}
}
}
// 按钮容器
.btn-wrap {
position: relative;
margin: 72px auto 0;
width: 654px;
display: flex;
justify-content: space-between;
.btn {
@include cb(300px, 80px);
}
.btn2 {
border-radius: 40px;
border: solid 2px #b83138;
background: transparent;
color: #a21f3c;
}
}
}
.rule-btn {
position: absolute;
top: 32px;
right: 0;
@include border-left-radius(30px);
@include btc(162px, 60px);
font-size: 30px;
color: #bf0221;
box-shadow: 7.4px 8.2px 27px 0 rgba(228, 78, 96, 0.86);
background-image: linear-gradient(to right, #fbddd5, #f9efed 51%, #ffded9 99%), linear-gradient(to bottom, #000000, #000000);
.c1 {
padding-left: 12px;
}
}
}
}
......
<view class="page">
<view class="app__bgc bgc"></view>
<view class="app__bg bg"></view>
<view class="app__bg bg">
<image class="b1" mode="widthFix" src="../../image/oss/my-wish/my-wish-c1.png" />
</view>
<view class="decoration">
<image class="d1" src="../../image/oss/my-wish/my-wish-d1.png" mode="widthFix" />
</view>
<view class="app__content main">
<view class="top-space"></view>
<view class="content"></view>
<view class="content">
<!-- 我的信息框 -->
<view class="my">
<image class="ebg" src="../../image/oss/my-wish/my-wish-c2.png" mode="widthFix" />
<image class="portrait" src="{{wishInfo.member.avatar}}" />
<!-- 内容 -->
<view class="cont">
<view class="space1"></view>
<view class="nickname">{{wishInfo.member.nickname}}</view>
<view class="number">{{wishInfo.member.mobile}}</view>
<view class="mycard">我的卡券</view>
</view>
<view bindtap="onCreatePosterHandler" class="poster-btn">生成海报</view>
</view>
<!-- 协作 -->
<view class="coop">
<view class="tit">· 我的弹力帮帮团 ·</view>
<view class="tips">
积累
<span class="t1">5</span>
人助力,获得
<span class="t1">12100</span>
弹力值!
</view>
<scroll-view scroll-y="{{true}}" class="list">
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
<view class="list-item">·小丸子 刚刚使出吃奶的力气,帮你摇出了 140 弹力值!</view>
</scroll-view>
</view>
<view class="btn-wrap">
<view class="btn btn2">弹力girl榜单</view>
<view class="btn">弹弹好友</view>
</view>
</view>
<!-- 规则按钮 -->
<view class="rule-btn" bindtap="onShowRuleHandler">
<span class="c1">活动详情</span>
</view>
</view>
</view>
<van-popup show="{{ tipsRuleVisible }}">
<tips-rule-comp bind:evtcomp="evtcomp"></tips-rule-comp>
</van-popup>
......