h5写的一个签到积分系统
实现一个七天签到功能,但不是展示七天然后进行签到,是后台根据日期只返回最近七天的签到情况。
html页面

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>签到</title> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="email=no"> <meta charset="UTF-8" /> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" /> <link href="../static/css/weixin/base.css?v=2017012401" rel="stylesheet" type="text/css"> <script src="../static/js/weixin/jquery.min.js?v=2017012401"></script> <script src="../static/js/md5.min.js"></script> <script src="../static/js/bootstrap.min.js"></script> <link href="../static/css/bootstrap.min.css" rel="stylesheet" type="text/css"> <link href="../static/css/css.css" rel="stylesheet" type="text/css"> <!-- <style> .page { padding: 0; } .page-form { height: 100%; padding: 20px; border-radius: 0; } .page-form .form-top { padding: 20% 0; border: none; } .page-form .form-top .form-item { padding: 8px 10px; border: 1px solid #ddd; border-radius: 8px; } .page-form .form-top .form-item + .form-item { margin-top: 20px; } </style> --> <style> html, body { font-family: "PingFang SC"; } * { padding: 0; margin: 0; box-sizing: border-box; } ul, ol { overflow: hidden; padding: 0; margin: 0; } li { list-style: none; } .main { background: #fff; border-radius: 8px; width: 100%; height: 60%; padding: 1rem; box-shadow: -5px 0px 5px 0px rgba(0, 0, 0, 0.5) } .title { /* color: #8d8ebb; */ color: #4093dd; font-size: 0.8pc; line-height: 26px; text-align: center; } .title h1 { font-weight: bolder; font-size: 0.8pc } .sign-head { /* width: 560px; */ overflow: hidden; margin: 10px auto; } .sign-head .sign-btn { /* width: 100%; */ /* border: 1px solid #4093dd; */ float: left; color: #fff; font-size: 14px; line-height: 36px; padding: 2px 25px; border-radius: 4px; cursor: pointer; background-color: #4093dd; text-align: center; } .sign-head .sign-btn.disabled { color: #bbb; background-color: #eee; } .sign-foot { /* width: 106px; */ overflow: hidden; margin: 10px auto; margin-top: 3rem; display: flex; justify-content: space-between; } .sign-foot .reward-btn { /* width: 100%; */ /* border: 1px solid #b25d06; */ /* float: left; */ color: #fff; float: right; font-size: 14px; line-height: 36px; padding: 2px 25px; border-radius: 4px; cursor: pointer; /* background-color: #b25d06; */ background-color: #4093dd; text-align: center; } .sign-foot .reward-btn div:active { background-color: red; } .sign-foot .reward-btn.disabled { color: #bbb; background-color: #eee; } .sign-head .sign-date { float: right; /* color: #333; */ color: #4093dd; font-size: 20px; line-height: 36px; padding: 2px 25px; } .sign-box { /* width: 560px; */ width: 100%; height: 50px; margin: 10px auto; } .mark { /* width: 560px; */ width: 100%; margin: 10px auto; color: grey; } .sign-box li { float: left; /* width: 14.285%; */ width: 13.285%; margin: 0.5%; text-align: center; cursor: pointer; -webkit-user-select: none; user-select: none; /* border-right: 1px solid #4093dd; border-bottom: 1px solid #4093dd; */ border: 1px solid #4093dd; box-shadow: -1px 0px 1px 0px ; /* transform: rotate(30deg); -ms-transform: rotate(30deg); -webkit-transform: rotate(30deg); */ } .sign-box ol { /* border-top: 1px solid #ccc; */ /* border-left: 1px solid #ccc; */ } .sign-box ol li { height: 40px; color: #4093dd; font-size: 24px; line-height: 40px; } .sign-box ul { /* border-left: 1px solid #4093dd; border-top: 1px solid #4093dd; border: 1px solid #4093dd; */ /* box-shadow: -5px 0px 5px 0px rgba(0,0,0,0.5) */ } .sign-box ul li { height: 80px; /* color: #333; */ color: #4093dd; font-size: 20px; /* line-height: 50px; */ position: relative; display: flex; flex-direction: column; justify-content: center; align-items: center; } /* .sign-box ul li .signDate { width: 50px; height: 40px; } */ .sign-box ul li .signDate { position: relative; width: 2rem; height: 2rem; margin-top: 0.5rem; border-radius: 1rem; background-color: rgba(0, 0, 0, 0.4); /* background-color: grey; */ z-index: 5; } .sign-box ul li .signDate::before { content: ''; position: absolute; width: 1rem; height: 1.5rem; color: black; border-bottom: 3px solid #fff; border-right: 3px solid #fff; left: 50%; top: 30%; transform-origin: center; transform: translate(-50%, -30%) rotate(45deg); -webkit-transform: translate(-50%, -30%) rotate(45deg); } .sign-box ul li .hasSignDate { position: relative; width: 2rem; height: 2rem; margin-top: 0.5rem; border-radius: 1rem; /* background-color: rgba(0, 0, 0, 0.4); */ background-color: #4093dd; z-index: 5; } .sign-box ul li .hasSignDate::before { content: ''; position: absolute; width: 1rem; height: 1.5rem; color: black; border-bottom: 3px solid #fff; border-right: 3px solid #fff; left: 50%; top: 30%; transform-origin: center; transform: translate(-50%, -30%) rotate(45deg); -webkit-transform: translate(-50%, -30%) rotate(45deg); } .sign-box li.seat { color: #ddd; } .sign-box li:active { background-color: #f2f2f2; } .sign-box li.current { color: #fff; background-color: #4093dd; } /* .sign-box li.checked { color: #999; background-color: #eee; } */ /* .sign-box li.checked { width: 8px; height: 16px; border-color: #009933; border-style: solid; border-width: 0 3px 5px 0; transform: rotate(45deg); } */ .sign-box li .checked { position: absolute; left: 1rem; top: 1rem; display: inline-block; font-weight: 700; margin: 0 10px; /* width: 8px; */ width: 1rem; height: 2rem; transform: rotate(45deg); border-style: solid; border-color: #4093dd; border-width: 0 4px 4px 0; } /* .sign-box li.today { background-color: #4093dd } */ .integral { /* color: #b25d06; */ color: #4093dd; /* color: #4093dd; */ font-size: 18px; font-family: KaiTi; line-height: 36px; } .footer { background: #fff; width: 100%; height: 35%; padding: 1rem; margin: 1rem auto; border-radius: 8px; box-shadow: -5px 0px 5px 0px rgba(0, 0, 0, 0.5) } .qiandao-rule-list { margin-bottom: 35px; /* color: #8d8ebb; */ color: #4093dd; font-size: 0.7pc; line-height: 26px } .qiandao-rule-list h4 { font-weight: bolder; font-size: 0.7pc } </style> <script src="../static/js/layer.2.0/layer.m.js"></script> </head> <body> <div class="main"> <div class="logo-wrap"> </div> <div class="title"> <h4>签到领积分</h4> <p>积分可兑换优惠券</p> </div> <div class="sign-head"> <span class="sign-btn">立即签到</span> <span class="sign-date">2017-04</span> </div> <div class="sign-box"></div> <!-- <div class="mark">只显示最近七天的签到情况</div> --> <!-- <div class="grandTotal">累计签到:5天</div> --> <div class="sign-foot"> <div class="integral">当前积分:6分</div> <div class="reward-btn">积分兑换</div> </div> </div> <div class="footer"> <!-- <div class="explanation"> 规则说明 </div> --> <div class="qiandao-rule-list"> <h4>签到规则</h4> <p>每次签到获得1个积分,如果中间有一天间断未签到的,重新开始计算连续签到时间。</p> <p>连续签到七天及其以上可以使用7个积分兑换一张优惠券</p> <p>连续签到不满七天的,可以使用10个积分兑换一张优惠券</p> </div> </div> <!-- <script src="../static/js/weixin/jquery.min.js"></script> --> <!-- <script src="./js//signInPage.js"></script> --> <!-- <script> document.write("<script src='./js//signInPage.js?t=" + new Date().getTime() + "'><\/script>"); </script> --> <script> document.write("<script src='../static/js/js.js?t=" + new Date().getTime() + "'><\/script>", "<script src='./js//signInPage.js?t=" + new Date().getTime() + "'><\/script>") </script> <script> $(function () { $('.sign-box').Sign({ signBtn: '.sign-btn', rewardBtn: '.reward-btn', current: '.sign-date', dateChecked: [1, 2, 3, 4, 5, 6, 8] }) }) </script> </body> </html>
js部分

(function ($, window, document, undefined) { // var rewardFlag = false // // 是否可以领奖判断,默认不可领取 var rewardFlag = false // // 是否可以领奖判断,默认不可领取 var signFlag = true // // 每天只可以签到一次 var integral = 0 // 拿到积分 var signDateArray = [] // 拿到日期数组 var point = 0; // 拿到乐停logo function getParkInfo(parkId, callback) { fnReq("/openapi/getParkInfo?parkId=" + parkId, function (type, data) { if (type == 1 && data) { callback && callback(data); } else { callback && callback(data || {}); } }); } // getQueryVariable('parkId') getParkInfo(getQueryVariable('parkId'), function (data) { if (data.logo) { $('.logo-wrap').empty(); var imgStr = '<img alt="企业logo" class="logo-img" src="' + data.logo + '">'; $('.logo-wrap').append(imgStr); } }); // 获取地址栏参数 function getQueryVariable(variable) { var query = window.location.search.substring(1); var vars = query.split("&"); for (var i = 0; i < vars.length; i++) { var pair = vars[i].split("="); if (pair[0] == variable) { return pair[1]; } } return (false); } var Sign = function (el, options) { this.el = el; this.defaults = { signBtn: '.signBtn', }; this.options = $.extend({}, this.defaults, options); // 获取用户最近七天签到信息 let reqParams = { parkId: getQueryVariable('parkId'), openId: getQueryVariable('openId') } function getUserSignList(params, callback) { var url = '/openapi/coupon/getUserSignList?t=' + new Date().getTime() // fnReq(url, params || {}, function (type, data, res) { // console.log('1231111') // console.log(data) // if (type === 1) { // callback && callback(data) // } else if (type === 2) { // valert(res.msg || '系统开了小差') // } // }) $.ajaxSettings.async = false; //设置为同步 $.get(url, params, function (result) { signDateArray = result.data.signDateArray integral = result.data.totalPoint // 进行初始化的处理 $('.integral').text(`当前积分:${integral}分`) //今天是否已签到 if ($.inArray(new Date().format("yyyy-MM-dd"), signDateArray) != -1) { // $(this.options.rewardBtn).addClass('disabled') $('.sign-btn').addClass('disabled') $('.sign-btn').text('已签到') signFlag = false } }); } getUserSignList(reqParams) // 点击签到 // this.el.on('click', '.current', $.proxy(this.signIn, this)) // $(this.options.signBtn).on('click', $.proxy(this.signIn, this)) let that = this this.el.on('click', '.current', $.proxy(this.signIn, this)) // $(this.options.signBtn).on('click', $.proxy(this.signIn, this)) $('.sign-head .sign-btn').click(function () { that.signIn() }) } Date.prototype.format = function (fmt) { var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小时 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); } for (var k in o) { if (new RegExp("(" + k + ")").test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); } } return fmt; } Sign.prototype = { // point: '', // 拿到日期数组 init: function () { // 拿到前七天的时间 function getDay(day) { var today = new Date(); var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day; today.setTime(targetday_milliseconds); //注意,这行是关键代码 var tYear = today.getFullYear(); var tMonth = today.getMonth(); var tDate = today.getDate(); tMonth = doHandleMonth(tMonth + 1); tDate = doHandleMonth(tDate).toString(); // return tYear + "-" + tMonth + "-" + tDate; if (tDate.substring(0, 1) == '0') { tDate = tDate.substring(tDate.length - 1) } return tDate; } function doHandleMonth(month) { var m = month; if (month.toString().length == 1) { m = "0" + month; } return m; } var h = k = '', c = new Date(), //当前时间 y = this.options.dateMonth ? this.options.dateMonth[0] : c.getFullYear(), m = this.options.dateMonth ? this.options.dateMonth[1] - 1 : c.getMonth(), d = m == c.getMonth() ? c.getDate() : null, w = new Date(y, m).getDay(), f = new Date(y, m, 1).getDay(), // 当前月份第一天的星期 p = new Date(y, m, 0).getDate(), // 前一月份天数(最后一天) t = new Date(y, [m + 1], 0).getDate(), // 当前月份天数(最后一天) l = new Date(y, m, t).getDay(); // 当前月份最后一天的星期 // 显示当前日期 if (this.options.current) { var ct = c.getFullYear() + '-' + [(c.getMonth() < 9) ? ('0' + (c.getMonth() + 1)) : (c.getMonth() + 1)] $(this.options.current).text(ct) } //ol => 星期 ul => 日期 this.el.append('<ol></ol><ul></ul>') // 只展示最近七天的日期 for (var i = -6; i <= 0; i++) { // 默认添加灰色对号 // h += '<li>' + getDay(i) + '<div class="signDate"></div></li>' } this.el.find('ul').append(h) // 已签到记录 // this.options.dateChecked = ['2020-06-17', '2020-06-18', '2020-06-19', '2020-06-20', '2020-06-21', '2020-06-22'] let dateArray = [] //重新定义一个日期数组 let singleDate; //单个日期 // 当返回数组为空时不进行处理 if (signDateArray.length == 0) { } else { signDateArray.forEach(element => { singleDate = element.substring(element.length - 2) if (singleDate.substring(0, 1) == '0') { singleDate = singleDate.substring(singleDate.length - 1) } // dateArray.push(Number(singleDate)) dateArray.push(singleDate) }); } $('ul').find('li').eq(6).addClass('current') // 给已签到的日期添加标记 for (let i = 0; i <= 7; i++) { // 如果li标签的日期存在于数组中,添加标记 if ($.inArray($('ul').find('li').eq(i).text(), dateArray) != -1) { $('ul').find('li').eq(i).removeClass('current') // 删除灰色对号 添加蓝色对号 // $('ul').find('li').eq(i).append('<div class="checked"></div>') $('ul li div').eq(i).remove('.signDate') $('ul').find('li').eq(i).append('<div class="hasSignDate"></div>') } } this.judgment(integral) $('ul').find('li') console.log($('ul li').find('.checked').length) }, signIn: function (e) { if (signFlag) { signFlag = false // 获取用户最近七天签到信息 let reqParams = { parkId: getQueryVariable('parkId'), openId: getQueryVariable('openId') } let that = this function userSign(params, callback) { var url = '/openapi/coupon/userSign?t=' + new Date().getTime() $.ajaxSettings.async = false; //设置为同步 fnReq(url, params || {}, function (type, data, res) {}) // let ss = 9 integral += 1 $('.sign-btn').addClass('disabled') $('.sign-btn').text('已签到') $('.reward-btn').text('积分兑换') // this.el.find('.current').addClass('checked') // $('ul').find('li').eq(6).addClass('checked') $('ul').find('li').eq(6).removeClass('current') // 删除当天灰色对号 添加蓝色对号 // $('ul').find('li').eq(6).append('<div class="checked"></div>') $('ul li div').eq(6).remove('.signDate') // $('ul li').find('.signDate').eq(6).remove() $('ul').find('li').eq(6).append('<div class="hasSignDate"></div>') $('.integral').text(`当前积分:${integral}分`) // $('.grandTotal').text(`累计签到:${ss+1}天`) // this.options.dateChecked.push(new Date().format("yyyy-MM-dd")) // console.log(new Date().format("yyyy-MM-dd")) // console.log(this.options) console.log($('ul li').find('.checked')) that.judgment(integral) } userSign(reqParams) } }, // 領獎按钮 rewardIn: function (e) { // if (rewardFlag) { // window.location.href="http://scantest.leting360.cn/2.0/bindplate.html"; var url = '/bindplate2.0.html?parkId=' + getQueryVariable('parkId') + '&openId=' + getQueryVariable('openId') + '&point=' + point + '&preferSchemeId=' + getQueryVariable('preferSchemeId'); toLink(host_ht + url); // 请求领取奖励接口 // let reqParams = { // parkId: getQueryVariable('parkId'), // openId: getQueryVariable('openId'), // point:integral, // preferSchemeId:getQueryVariable('preferSchemeId'), // plateNumber:'车牌号' // } // function pointExchange(params, callback) { // var url = '/openapi/coupon/pointExchange?t=' + new Date().getTime() // $.ajaxSettings.async = false; //设置为同步 // fnReq(url, params || {}, function (type, data, res) { // console.log('1231111') // console.log(data) // if (type === 1) { // callback && callback(data) // } else if (type === 2) { // valert(res.msg || '系统开了小差') // } // }) // // $.get(url, params, function (result) { // // console.log(result) // // signDateArray = result.data.signDateArray // // integral = result.data.totalPoint // // // 进行初始化的处理 // // $('.integral').text(`当前积分:${integral}分`) // // //今天是否已签到 // // console.log($.inArray(new Date().format("yyyy-MM-dd"), signDateArray) != -1) // // if ($.inArray(new Date().format("yyyy-MM-dd"), signDateArray) != -1) { // // // $(this.options.rewardBtn).addClass('disabled') // // $('.sign-btn').addClass('disabled') // // $('.sign-btn').text('已签到') // // signFlag = false // // } // // }); // } // pointExchange(reqParams) $(this.options.rewardBtn).addClass('disabled') $(this.options.rewardBtn).text('已领取') rewardFlag = false // } else { // // valert('已经领取了一张优惠券了', function () { // // }) // } }, //判断是否可以领取奖励 judgment: function () { // 如果已标记checked的li标签有七个 && 积分大于等于 7 领取奖励变亮 if (integral >= 7 && $('ul li').find('.hasSignDate').length == 7) { point = 7 rewardFlag = true } // 如果积分大于等于10 领取奖励变亮 if (integral >= 10 && $('ul li').find('.hasSignDate').length != 7) { point = 10 rewardFlag = true } if (!rewardFlag) { $(this.options.rewardBtn).addClass('disabled') } else { $(this.options.rewardBtn).removeClass('disabled') // 可以领取奖励 $(this.options.rewardBtn).on('click', $.proxy(this.rewardIn, this)) } }, } $.fn.Sign = function (options) { //在这里面,this指的是用jQuery选中的元素 var sign = new Sign(this, options); return sign.init() }; })(jQuery, window, document);
效果图
君不见,高堂明镜悲白发,朝如青丝暮成雪
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!