一、需求痛点
目的:实现快速上活动转化利益
目标:实现无代码开发活,降低开发成本。解放开发人员\
痛点:实现多平台投放
需求:落地页实现分享功能、分享海报、支付、 多渠道平台跳转\
二、设计原型
用九牛二虎之力终于画成了自己想要的样子,不过还是有点丑。产品之路慢慢兮,其修远~
三、代码撸起来。各位小伙们重点来了,代码有点烂希望多多指教~~~
代码设计这块分为两部分,其一是后台管理系统模块,一管理活动列表,二是管理具体活动的创建和维护;其二是ToC端,实现从后台读取活动数据在移动终端进行展示,根据不同的配置数据进行调用不同的功能插件(这里插件是经过我经年累月沉淀已经封装好的,在这里直接调用即可。部分插件的封装可以参考我上一篇文章《从0到1学习云闪付开发,冷门小众云闪付小程序崛起之玩转云闪付小程序——屌丝开发惊心动魄的总结》
(1)搭建拖拽区域的模板(这里我使用了avue框架,之前手写的html拖拽太繁琐了)
<!-- 活动界面配置 -->
<div style="position: relative; height: auto">
<div class="avue-grid"></div>
<img class="show_input_image left" :src="imgSrc" v-if="imgSrc" />
<div v-else class="wubeijing">暂无活动效果图</div>
<div class="optionsDome">
<div v-for="(obj, i) in list" :key="i" class="draggableBox">
<avue-draggable
class="draggable"
:width="obj.width"
:height="obj.height"
:left="obj.left"
:top="obj.top"
id="draggable"
ref="draggable"
@focus="handleFocus(obj.id)"
@blur="handleBlur">
<div class="deleteBtn" v-on:click="deleteNode(i)">
<img src="删除按钮" alt="" />
</div>
</avue-draggable>
</div>
</div>
</div>
(2)图片上传咱们这里不做介绍,都是常用的功能组件直接使用即可
(3)实现动态生成按钮标签,并且实现按钮的定位、按钮数据的配置、按钮大小
主要根据点击按钮的来确定是什么功能的动态写在代码里面了路径和参数,原始的初衷是这里只是一个按钮,随便运维人员怎么配置代码逻辑自己动识别。但是多方面考虑,运维成本大大提高、开发维护成本也会提高,主要是运维同学要去了解代码逻辑、路由表等开发层面的点点滴滴,所以就出现了下面的设计情况了。
//动态添加操作按钮
addNode(data) {
this.btnStatus = data;
let ids = 0;
if (this.list.length == 0) {
ids = 0;
} else {
ids = this.list.length;
}
console.log("formData=====", this.formData);
if (this.formData) {
this.list.forEach((item) => {
if (item.id == this.formData.id) {
item = {};
item = this.formData;
}
});
}
this.formData = {};
switch (data) {
case 1:
this.merchant = true;
this.coupon = false;
this.list.push({
id: ids,
width: 50,
height: 50,
left: 360,
top: 570,
productId: "",
page: "productionDetail",
});
this.formData = this.list[this.list.length - 1];
break;
case 1:
this.merchant = true;
this.coupon = false;
this.list.push({
id: ids,
width: 50,
height: 50,
left: 360,
top: 570,
productId: "",
page: "shareUrl",
});
this.formData = this.list[this.list.length - 1];
break;
default:
this.list.push({
id: ids,
width: 50,
height: 50,
left: 360,
top: 570,
productId:'',
page: "pay",
});
this.formData = this.list[this.list.length - 1];
break;
}
},
以上所有基础工作全部准备完成,接下来做的就是实现拖动和数据采集(组装拖拽生成的数据)
(4)拖拽功能控件数据动态生成
获取焦点:主要目的有两个,一是为了获取改按钮的绑定数据(坐标、尺寸、绑定的路由、产品的id);二是用来进行编辑使用
//获取焦点
handleFocus(id) {
this.checkoutDragId = id;
console.log("模块id===", id);
},
失去焦点:获取最终拖拽的位置数据写回原始对象中
//失去焦点
handleBlur({ left, top, width, height }) {
console.log("选中模块===", left, top, width, height);
this.list.forEach((item) => {
if (item.id == this.checkoutDragId) {
this.formData = {};
item.width = width;
item.height = height;
item.top = top;
item.left = left;
this.formData = item;
}
});
},
//删除按钮
deleteNode: function (i) {
this.list.splice(i, 1); //删除index为i,位置的数组元素
},
调用后台接口把所有工具生成的数据提交给后台
// 生成加密侯得数据
encryption() {
let that = this;
if(this.AppId == ''){
this.$message({
message: '请选择小程序!',
type: 'warning'
});
return
}
if(this.activityName == ''){
this.$message({
message: '请输入活动名称!',
type: 'warning'
});
return
}
// let shareUrl = window.location.href + "&colde=" + numboer // 重写分享的时候再加上客户自定义的参数
//匹配选择的小程序名称、生产域名地址 用于C动态切换不同平台的服务器(有点傻逼的设计,这里可以在优化,不过不是一个人说的算的)
this.UpData.forEach((item) => {
if (item.value == that.AppId) {
that.upName = item.label;
that.url = item.realmName;
}
});
console.log(that.AppId, that.url);
let herf = that.url + "publickPage?activityId=" + this.activityName;
this.ciommitData = {
upName: this.upName, // 小程序名称
AppId: this.AppId,
activityId: this.activityName, //活动id
bgImage: this.imgSrc, //活动图片
dataList: this.dragBtnlist,// 拖拽按钮对象
};
console.log(JSON.stringify(this.ciommitData), "参数");
that.urlCode1 = herf;
let params = {
toLink: encodeURIComponent(herf)
encryptAppId: that.AppId,
};
let paramsData = JSON.stringify(params);
let str = CryptoJS.enc.Utf8.parse(paramsData);
let base64 = CryptoJS.enc.Base64.stringify(str);
that.shareUrlEn = encodeURIComponent(herf);
that.shareUrl = "<https:Help.html?params=>" + base64
that.urlCode2 =
"[upwallet://applet?encryptAppId=]()" + that.AppId +"&toLink=" +encodeURIComponent(herf);
if (this.czType == "edit") {
this.editTemplateInfo();//调用后台接口把所有工具生成的数据提交给后台
} else {
this.addTemplateInfo();
}
}
ok~~~~~到目前位置B端的管理平台所有事情全部结束了,
接下来要做的就是C通过接口去获取B端拖拽生成的活动数据。习惯性的先价绍一下实现的方式和原理
1、搭建一个容器主要用来展示活动图片
2、计算每一个按钮的定位的位置
3、根据不同按钮的属性来调用不同的功能组件(支付、分享、海报)
看上去是不是很简单~~~~~~
直接上代码(^_^)
页面搭建:
(1)页面只有一个img和一堆按钮
(2)全部使用定位来做锚点
(3)计算按钮的尺寸、位置,因为B端上传的图片是750设计图,而手机为了做兼容做一个换算rem
<div class='toppage' >
<img :src="locationList.bgImage" alt="">
<div class="clickEvent"
v-for="(item,index) in locationList.dataList " :key="index"
:style="{width: item.width/100 + 0.1 + 'rem',height:item.height/100 +0.1 + 'rem',left:item.left/100 + 0.1 + 'rem',top:item.top/100 + 0.1+'rem'}"
@click="handerclick(item)" >
</div>
</div>
这里css的展示部分:
.toppage{
width: 100%;
position: relative;
}
.toppage img{
display: block;
width: 100%;
}
.clickEvent{
position: absolute;
}
如此简洁轻便岂不快哉,哈哈哈哈~~~~~~
有点飘了,还是要落地,
接下来就是各个功能组件的调用
handerclick(item){
if(item.page.indexOf('http') == -1){//这里主要是区分内部路由还是外部http链接
this.$router.push({path:"/"+item.page,query:{productId:item.productId},});
} if(item.page.indexOf('pay') != -1){//调支付方法
pay();
}if(item.page.indexOf('shareUrl') != -1){//调分享方法
share();
}if(item.page.indexOf('shareImage') != -1){//调分享海报方法
shareImage();
}else{
jumpFuntion(item.page)//根据业务封装好的处理跳转弟三方链接,这里可以根据自己的实际业定
}
}
~~完美 到此整个活动工具全介绍完毕~~~~ 关注我,学习更多冷门小知识