最近七月天气王做了个运营活动,活动分为两个阶段。阶段一是射日活动,阶段二是转盘抽奖活动。
当用户每天射日集满10个太阳就可以参加最后的转盘抽大奖。
附上地址:http://tianqi.2345.com/api/activity/activity.php(现在估计活动下线已不可以访问)
首先说下,项目的难点,整个项目的难点是分享,分享给用户,成功后,用户的射日机会增加一次,但是由于这个客户端抓不到分享后的状态,前端和服务端也获取不到这一状态,故这个功能废弃掉了
这个要给以后做活动已提醒,在webview里做活动是获取不到分享后的状态的,在浏览器里做活动也需要调用微信的接口。
其次的难点就是防作弊,因为获取不到用户设备的唯一标识,所以没发货也能好的做限制,所以在用户第一次进入页面的时候,服务端就会给他一个唯一的字段用来代表用户标识,
同时我会将这个用户标识存在本地,当用户下次进入页面时,我会将这个字段从本地取出传给服务端,服务端从数据库查找这一用户标识,并返回相应的用户信息。
所以这可能带来的风险就是当用户清除缓存时,用户的唯一标识也被清除,下次进的时候他就是一个全新的用户了,他之前的中奖信息都将丢失(没有用户系统,不可避免)唯一当时没有调研清楚的是,
苹果手机的webview当退出APP时,用户的cookie就被清除了,所以用户每次进去都是全新的用户可以一直玩游戏但是信息却不会被保存。我们的补救措施是给用户添加了storage当用户没有cookie时就去取storage里的值。
用户标识只是第一层保护伞,第二层就是手机号,其实手机号是相对安全的,但是用户刚进来就让输入手机号,会极大影响用户玩游戏的积极性,所以这一步做在了只要用户想要领取奖品的时候就要输入手机号,
同时服务端会再给我一个唯一的和手机号对应的标识,当然也是存在本地,所以存在本地的好处就是不用服务端做处理,简单,但是很大的弊端就是不安全。
做移动端应用的时候很容易遇到的两个问题这里总结一下
1.当软键盘弹出时,输入框被遮住,这是个很神奇的问题,因为你的解决办法适用于这个项目不一定适应于另一个项目,这里把几种方法归纳下
a.让当前的元素滚动到浏览器窗口的可视区域内。
$('input[type="text"]').on('click', function () {
var target = this;
setTimeout(function(){
target.scrollIntoViewIfNeeded();
},400);
});
b.输入框获得焦点时上移,注意设置body的高度100%
$("input,.ui-textarea").focus(function () {
var t = navigator.userAgent;
if (t.indexOf("Android") > -1 || t.indexOf("Adr") > -1) {
var e = $(this).offset().top - 80;
$(window).scrollTop(e)
}
})
c.当输入框是弹窗定位在页面的元素时直接改变定位高度
$('input[type="text"]').on('click', function () {
var target = this;
setTimeout(function(){
LayerLogin.css({"top":"60px"}); },400);
});
});
2.就是苹果手机部分浏览器物理返回不刷新,这个代码也是不保证百分百解决
一种是监听pageshow 返回监听不到onload 但是可以监听到这个属性
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload();
}
};
window.addEventListener("popstate", function (e) {
console.log(document.referrer);
document.location.href = document.referrer;
}, false);
var state = {
title: "",
url: ""
};
3.就是防止用户点击按钮,就会出现连续发送请求的情况 这里可以加个定时器,点击之后加上disabled,再次点击判断是否是disabled,如果有则return,30秒内将disabled的移除。
4.点击空白处关闭弹窗,判断是不是原目标,是则移除
var $layer = $("#layer");
var $nav = $(".second-nav");
$layer.click(function(e){
if(e.target.className == 'layer'){
$layer.hide();
$nav.hide();
}
})
5.toast提示
var toast=function(){
var timer;
$('.pdName').css({
'display':'block'
})
timer = setTimeout(function(){
$('.pdName').css({
'display':'none'
})
},2000)
return false;
};
6.倒计时
function popShowSendCodeTime()
{
if (popSendCodeWait == 0)
{
popIsSendingCode = 0;
popSendCodeWait = 60;
}
else
{
popIsSendingCode = 1;
var value = popSendCodeWait + "秒后重新获取";
popSendCodeWait--;
setTimeout(function()
{
popShowSendCodeTime();
}, 1000);
}
}
7给页面添加无限循环的动画,除非加上disabled去除动画,动画移除属性 css('animation-play-state','paused');
var btnScale = setInterval(function() {
activityBtn.toggleClass('btn-scale');
}, 500);
if(activityBtn.hasClass('disabled')==true){
clearInterval(btnScale);
}
第二个阶段就是转盘抽奖,这个本来想自己写的,但是后来发现jquery不支持transfrom,后来就用了插件rotate.min.js
lottreyPan.rotate({
angle: 0,//起始角度
animateTo: data.a + 360*5,//服务端返回的角度+5圈
duration : 3000 //转动时间
});
最后就是测试并发抽奖了
这次活动做的比较仓促,从需求出来到正式上线用了八个工作日,其中有很多值得优化的点,希望下次做此类活动时,能多避免一些坑。