<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了小程式實現日曆打卡功能的具體程式碼,供大家參考,具體內容如下
老慣例,先上效果圖
1、日曆展示
例如下圖中:
2021月7月打卡日曆頁面,共35個日期資料,上月殘餘4天+本月31天;
2021月6月打卡日曆頁面,共35個日期資料,上月殘餘2天+本月30天+下月殘餘3天;
2021月5月打卡日曆頁面,共42個日期資料,上月殘餘6天+本月31天+下月殘餘5天。
【結論】打卡日曆頁面存在展示35個或42個日期資料的情況,35個或42個日期資料=當前顯示月所有日期資料+上月殘餘尾部日期+下月殘餘頭部日期。
計算出每個月的日期天數,獲取本月1號是周幾,上月殘餘天數=本月1號的星期X的X數(比如,2021年7月1日是星期四,則上月殘餘4天),假設 a=35-本月天數-上月殘餘天數。如果a>=0,則下月殘餘天數=a;如果a<0,則下月殘餘天數=7+a (比如2021年5月,35-37=-2;7+(-2)=5)
2、打卡功能
打卡實現的功能:可打卡的日期為今日日期或今日日期之前未打卡過的日期。
如圖:今日日期為綠色圓形背景,當前點選日期為橙色圓形背景;可打卡時,打卡按鈕背景為藍色,不可打卡時,打卡背景為灰色;√ 代表已打卡。
通過資料庫查詢當前已打卡的資料,已打卡的資料需要設定打卡按鈕禁用標誌。打卡按鈕禁用的情況(1)頁面初始化時,未點選任何日期(2)當前點選的日期在今天之後(3)當前日期在今天之前但已打卡。
點選打卡,記錄打卡日期並儲存至資料庫。
1、資料庫資料
2、日曆元件
【calendar.wxml】
程式碼裡使用了WXS頁內指令碼,渲染“已打卡”的標誌(√)
<view class="calendar"> <view class='tit'> <view class='pre' bindtap='gotoPreMonth'>{{'《'}}</view> <view class='current'>{{currentYear}}年{{currentMonth}}月</view> <view class='next' bindtap='gotoNextMonth'>{{'》'}}</view> </view> <view class='w100P showData'> <view class="week" style='color: #999'>日</view> <view class="week">一</view> <view class="week">二</view> <view class="week">三</view> <view class="week">四</view> <view class="week">五</view> <view class="week" style='color: #999'>六</view> </view> <view class='content'> <view wx:for="{{allArr}}" wx:key="index" class='itemData' data-current="{{item.month == 'current' ? '1' : '0'}}" data-day='{{item.date}}' bindtap='clickDate'> <view class="{{item.month == 'current' ? '' : 'gray'}}" style="height:44px;width:44px;line-height:30px;{{nowYear==currentYear&¤tMonth==nowMonth&&item.date==nowDate?'color:#fff;background:#33D4C5;border-radius:100px':''}};{{item.month == 'current'&&selectedYear==currentYear&&selectedMonth==currentMonth&&item.date==selectedDate?'color:#fff;background:orange;border-radius:100px':''}} "> {{item.date}} <view> <icon wx:if="{{item.month == 'current'&&dataProcess.filterDate(currentPunchCardDate,item.date)}}" class="icon" color="#F44336" type="success_no_circle" size="15"></icon> </view> </view> </view> </view> <view class="btn-wrapper" bindtap="gotoToday"> <button class="btn">回今天</button> </view> <!-- wxs頁面內指令碼,在渲染層做資料處理 --> <wxs module="dataProcess"> function filterDate(currentPunchCardDate,date){ if(currentPunchCardDate.indexOf(date)!==-1){ return true } } module.exports={ filterDate:filterDate } </wxs> </view>
【calendar.wxss】
.calendar { width: 100%; background: #fff; } .pre, .next { color: #33D4C5; text-align: center; line-height: 20px; } .calendar .tit { display: flex; justify-content: center; align-items: center; padding: 40rpx 0; } .current { font-size: 32rpx; color: #2A2A2A; } .calendar .tit .current { margin: 0 60rpx; } .showData { display: flex; justify-content: center; align-items: center; box-sizing: border-box; padding-left: 25rpx; padding-right: 25rpx; } .showData .week { width: 14%; height: 70rpx; line-height: 70rpx; text-align: center; flex-shrink: 0; font-size: 30rpx; color: #2A2A2A; } .calendar .content { display: flex; flex-wrap: wrap; box-sizing: border-box; padding-left: 25rpx; padding-right: 25rpx; } .calendar .content .itemData { width: 14.2%; height: 90rpx; line-height: 90rpx; flex-shrink: 0; font-size: 30rpx; color: #2A2A2A; text-align: center; display: flex; align-items: center; justify-content: center; } .calendar .content .icon { position: relative; top: -25rpx; } .calendar .content .gray { color: #999; } .currentSelected { color: #fff; background: #1CA2FC; border-radius: 100px; } .calendar .btn-wrapper { text-align: right; background-color: #fff; width: 100%; padding-bottom: 10rpx; } .calendar .btn-wrapper .btn { border: 1px solid #33D4C5; padding: 5rpx; width: 95rpx; font-size: 21rpx; color: #33D4C5; border-radius: 20rpx; margin-bottom: 15rpx; position: relative; left: calc(50% - 100rpx); }
【calendar.js】
Component({ /** * 元件的屬性列表 */ properties: { currentPunchCardDate: { type: Array, value: [] }, currentYear: { // 當前頁面顯示的年 type: Number, value: new Date().getFullYear() }, currentMonth: { // 當前頁面顯示的年月 type: Number, value: new Date().getMonth() + 1 }, nowYear: { // 當前年 type: Number, value: new Date().getFullYear() }, nowMonth: { // 當前月 type: Number, value: new Date().getMonth() + 1 }, nowDate: { // 當前日 type: Number, value: new Date().getDate() }, }, /** * 元件的初始資料 */ data: { currentMonthDateLen: 0, // 當月天數 preMonthDateLen: 0, // 當月中,上月多餘天數 allArr: [], // 35個或42個日期資料=當前顯示月所有日期資料+上月殘餘尾部日期+下月殘餘頭部日期 nowDate: null, selectedDate: null, //當前選擇日期 selectedMonth: null, //當前選擇月 selectedYear: null, //當前選擇年 }, // 用observers監聽properties的屬性值 observers: { 'currentPunchCardDate': function (val) { console.log(val) } }, // 在元件範例剛剛被建立時執行 created() {}, // 在元件範例進入頁面節點樹時執行 ready() { this.getAllArr() }, /** * 元件的方法列表 */ methods: { // 獲取某年某月天數:下個月1日-本月1日 getDateLen(year, month) { let actualMonth = month - 1; let timeDistance = new Date(year, month) - new Date(year, actualMonth); return timeDistance / (1000 * 60 * 60 * 24); }, // 獲取某月1號是周幾 getFirstDateWeek(year, month) { // 0-6,0代表周天 return new Date(year, month - 1, 1).getDay() }, // 上月 preMonth(year, month) { if (month == 1) { return { year: --year, month: 12 } } else { return { year: year, month: --month } } }, // 下月 nextMonth(year, month) { if (month == 12) { return { year: ++year, month: 1 } } else { return { year: year, month: ++month } } }, // 獲取當月資料,返回陣列 getCurrentArr() { let currentMonthDateLen = this.getDateLen(this.data.currentYear, this.data.currentMonth) // 獲取當月天數 let currentMonthDateArr = [] // 定義空陣列 if (currentMonthDateLen > 0) { for (let i = 1; i <= currentMonthDateLen; i++) { currentMonthDateArr.push({ month: 'current', // 只是為了增加標識,區分上下月 date: i }) } } this.setData({ currentMonthDateLen }) return currentMonthDateArr }, // 獲取當月中,上月多餘的日期資料,返回陣列 getPreArr() { let preMonthDateLen = this.getFirstDateWeek(this.data.currentYear, this.data.currentMonth) // 當月1號是周幾 == 上月殘餘天數) console.log("preMonthDateLen=", preMonthDateLen); let preMonthDateArr = [] // 定義空陣列 if (preMonthDateLen > 0) { let { year, month } = this.preMonth(this.data.currentYear, this.data.currentMonth) // 獲取上月 年、月 let date = this.getDateLen(year, month) // 獲取上月天數 for (let i = 0; i < preMonthDateLen; i++) { preMonthDateArr.unshift({ // 尾部追加 month: 'pre', // 只是為了增加標識,區分當、下月 date: date }) date-- } } this.setData({ preMonthDateLen }) return preMonthDateArr }, // 獲取當月中,下月多餘的日期資料,返回陣列 getNextArr() { let nextMonthDateLen = 35 - this.data.preMonthDateLen - this.data.currentMonthDateLen // 下月多餘天數 console.log(" nextMonthDateLen=", nextMonthDateLen); let nextMonthDateArr = [] // 定義空陣列 if (nextMonthDateLen > 0) { for (let i = 1; i <= nextMonthDateLen; i++) { nextMonthDateArr.push({ month: 'next', // 只是為了增加標識,區分當、上月 date: i }) } } else if (nextMonthDateLen < 0) { for (let i = 1; i <= (7 + nextMonthDateLen); i++) { nextMonthDateArr.push({ month: 'next', // 只是為了增加標識,區分當、上月 date: i }) } } return nextMonthDateArr }, // 整合當月所有日期資料=上月殘餘+本月+下月多餘 getAllArr() { let preArr = this.getPreArr() let currentArr = this.getCurrentArr() let nextArr = this.getNextArr() let allArr = [...preArr, ...currentArr, ...nextArr] this.setData({ allArr }) let sendObj = { currentYear: this.data.currentYear, currentMonth: this.data.currentMonth, currentDate: this.data.selectedDate, allArr: this.data.allArr, } // 向父元件傳送資料 this.triggerEvent('sendObj', sendObj) }, // 點選 上月 gotoPreMonth() { let { year, month } = this.preMonth(this.data.currentYear, this.data.currentMonth) this.setData({ currentYear: year, currentMonth: month, }) this.getAllArr() }, // 點選 下月 gotoNextMonth() { let { year, month } = this.nextMonth(this.data.currentYear, this.data.currentMonth) this.setData({ currentYear: year, currentMonth: month, }) this.getAllArr() }, // 點選日期 clickDate(e) { var date = e.currentTarget.dataset.day; var current = e.currentTarget.dataset.current; if (current == 0) { if (date > 6) { // 點選上月日期--去上個月 var { year, month } = this.preMonth(this.data.currentYear, this.data.currentMonth) this.gotoPreMonth() } else { // 點選下月 var { year, month } = this.nextMonth(this.data.currentYear, this.data.currentMonth) this.gotoNextMonth() } } else { var year = this.data.currentYear; var month = this.data.currentMonth; } this.setData({ selectedYear: year, selectedMonth: month, selectedDate: date, }) console.log("當前選擇日期", year, "-", month, "-", date); console.log(this.data.selectedDate); wx.nextTick(() => { this.getAllArr() }) }, // 回今天 gotoToday() { this.setData({ currentYear: this.data.nowYear, currentMonth: this.data.nowMonth, }) this.getAllArr() } } })
3、打卡及統計
【calendarCard.wxml】
<view class="page-wrapper"> <top-title toptitle="打卡日曆" backImgFlag="true"></top-title> <calendar bind:sendObj="getObj" currentPunchCardDate="{{punchCardDateArr}}"></calendar> <view class="btn-wrapper"> <button class="btn" type="primary" disabled="{{ disabledFlag}}" bindtap="punchCard">打 卡</button> </view> <view class="record-wrapper"> <view class="title"> <image class="img" src="{{icon}}"></image> {{name}}打卡統計 </view> <view class="record"> <view class="record-item"> <view class="top"><text class="num">{{monthDays}}</text> 天</view> <view class="bottom">本月堅持天數</view> </view> <view class="record-item"> <view class="top"><text class="num"> {{totalDays}}</text> 天</view> <view class="bottom">總共堅持天數</view> </view> </view> </view> </view>
【calendarCard.wxss】
.page-wrapper { background-color: #fff; height: 100vh; } .page-wrapper .btn-wrapper .btn { width: 95vw; border-radius: 40rpx; height: 80rpx; font-size: 30rpx; background-color: #27d6f5; padding: 20rpx; } .page-wrapper .btn-wrapper .btn[disabled] { background-color: #e7e5e5; } .page-wrapper .record-wrapper { padding: 20rpx; } .page-wrapper .record-wrapper .title { color: #444; font-weight: bold; } .page-wrapper .record-wrapper .title .img { width: 60rpx; height: 60rpx; position: relative; top: 18rpx; } .page-wrapper .record-wrapper .record { display: flex; justify-content: space-around; margin-top: 20rpx; } .page-wrapper .record-wrapper .record .record-item { text-align: center; font-size: 24rpx; color: #a3a3a3; } .page-wrapper .record-wrapper .record .record-item .top { height: 80rpx; line-height: 80rpx; border-bottom: 1px solid #ececec; color: #333; } .page-wrapper .record-wrapper .record .record-item .top .num { font-size: 44rpx; font-weight: bold; color: #F44336; }
【calendarCard.js】
// miniprogram/pages/punchCard/calendarCard/calendarCard.js Page({ /** * 頁面的初始資料 */ data: { id: null, name: "", icon: "", disabledFlag: true, totalDays:0, monthDays:0, habitInfo: {}, currentDate: null, currentMonth: null, currentYear: null, nowYear: new Date().getFullYear(), nowMonth: new Date().getMonth(), nowDate:new Date().getDate(), punchCardDateArr: [] //用於存放當月打卡日期-日 }, /** * 生命週期函數--監聽頁面載入 */ onLoad: function (options) { console.log(options); this.setData({ id: options.id, name: options.name, icon: options.icon }) var nowYear = new Date().getFullYear() var nowMonth = new Date().getMonth() wx.nextTick(() => { this.getHabitInfo(nowYear, nowMonth) }) }, // 獲取子元件的資料 getObj(e) { console.log("獲取子元件的資料", e); this.setData({ currentDate: e.detail.currentDate, currentMonth: e.detail.currentMonth, currentYear: e.detail.currentYear, }) this.getHabitInfo(e.detail.currentYear, e.detail.currentMonth - 1) }, // 獲取當月的打卡資料 getHabitInfo(year, month) { // 注意month範圍 0-11,0代表1月 const db = wx.cloud.database() db.collection('habitList').where({ _id:this.data.id, }).get().then(res => { // console.log("從資料庫獲取資料[res]===", res); var dateTimeArr = res.data[0].dateTime var dateArr = [] dateTimeArr.forEach((item) => { if (item.getFullYear() == year && item.getMonth() == month) { dateArr.push(item.getDate()) } }) console.log(year, month,this.data.currentDate); if (!this.data.currentDate ||(year==this.data.nowYear && month>this.data.nowMonth)||(year==this.data.nowYear && month==this.data.nowMonth &&this.data.currentDate>this.data.nowDate) ) { // 打卡按鈕禁用的情況(1)頁面初始化時,未點選任何日期(2)當前點選的日期在今天之後 var flag = true } else { // 打卡按鈕禁用的情況 (3)當前日期已打卡 var flag = dateArr.indexOf(this.data.currentDate) == -1 ? false : true } this.setData({ habitInfo: res.data[0], punchCardDateArr: dateArr, disabledFlag: flag, totalDays:dateTimeArr.length, monthDays:dateArr.length }) }).catch(err => { console.log(err); }) }, // 點選打卡按鈕-打卡 punchCard() { console.log(this.data.currentYear, this.data.currentMonth - 1, this.data.currentDate); var currentTime = new Date(this.data.currentYear, this.data.currentMonth - 1, this.data.currentDate) const db = wx.cloud.database() db.collection('habitList').doc(this.data.id).update({ data: { dateTime:db.command.push(currentTime) }, success: res => { wx.showToast({ title: '打卡成功', }) this.getHabitInfo(this.data.currentYear, this.data.currentMonth - 1) }, fail: err => { wx.showToast({ icon: 'none', title: '新增記錄失敗' }) console.error('[資料庫] [新增記錄] 失敗:', err) } }) } })
【calendarCard.json】
{ "usingComponents": { "top-title":"../../../components/topTitle/topTitle", "calendar":"../components/calendar/calendar" } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45