56 lines
2.6 KiB
JavaScript
56 lines
2.6 KiB
JavaScript
const api = require('../../../services/api')
|
|
Page({
|
|
data: { item: null, streak: 0, records: [], year: 0, month: 0, days: [], loading: true, showActions: false },
|
|
onLoad(options) {
|
|
const now = new Date()
|
|
this.setData({ id: options.id, year: now.getFullYear(), month: now.getMonth() + 1 })
|
|
this.loadData()
|
|
},
|
|
async loadData() {
|
|
const { id, year, month } = this.data
|
|
try {
|
|
const [item, streak, records] = await Promise.all([
|
|
api.get('/api/checkin/items/' + id),
|
|
api.get('/api/checkin/streak/' + id),
|
|
api.get('/api/checkin/records?itemId=' + id + '&start=' + year + '-' + String(month).padStart(2,'0') + '-01&end=' + year + '-' + String(month).padStart(2,'0') + '-31'),
|
|
])
|
|
const days = this.buildCalendar(year, month, records.map(r => r.checkDate.slice(0,10)))
|
|
this.setData({ item, streak: streak.streak, records, days, loading: false })
|
|
} catch(e) { wx.showToast({ title: '加载失败', icon: 'none' }); this.setData({ loading: false }) }
|
|
},
|
|
buildCalendar(y, m, recordDates) {
|
|
const daysInMonth = new Date(y, m, 0).getDate()
|
|
const firstDay = new Date(y, m - 1, 1).getDay()
|
|
const today = new Date().toISOString().slice(0, 10)
|
|
const days = []
|
|
for (let i = 0; i < firstDay; i++) days.push({ empty: true })
|
|
for (let d = 1; d <= daysInMonth; d++) {
|
|
const dateStr = y + '-' + String(m).padStart(2,'0') + '-' + String(d).padStart(2,'0')
|
|
days.push({ day: d, checked: recordDates.includes(dateStr), isToday: dateStr === today, dateStr })
|
|
}
|
|
return days
|
|
},
|
|
prevMonth() {
|
|
let { year, month } = this.data
|
|
if (month === 1) { year--; month = 12 } else month--
|
|
this.setData({ year, month, loading: true }); this.loadData()
|
|
},
|
|
nextMonth() {
|
|
let { year, month } = this.data
|
|
if (month === 12) { year++; month = 1 } else month++
|
|
this.setData({ year, month, loading: true }); this.loadData()
|
|
},
|
|
toggleActions() { this.setData({ showActions: !this.data.showActions }) },
|
|
async onDelete() {
|
|
wx.showModal({ title: '确认删除', content: '确定删除这个打卡项?历史记录将保留。', success: async (res) => {
|
|
if (res.confirm) { try { await api.del('/api/checkin/items/' + this.data.id); wx.navigateBack() } catch(e) { wx.showToast({ title: '删除失败', icon: 'none' }) } }
|
|
}})
|
|
},
|
|
async onTogglePause() {
|
|
const { id, item } = this.data
|
|
if (!item) return
|
|
try { await api.post('/api/checkin/items/' + id + '/' + (item.status==='active'?'pause':'resume')); this.loadData() }
|
|
catch(e) { wx.showToast({ title: '操作失败', icon: 'none' }) }
|
|
},
|
|
})
|