const completion = require("../../utils/task-completion"); const { secure, toast } = require("../../utils/api"); const { localDate, shiftDate } = require("../../utils/date"); Page({ data: { pets: [], tasks: [], taskBusyIds: [], completingAll: false, undoneCount: 0, date: localDate(), showForm: false, editingId: "", saving: false, title: "", petIndex: 0, category: "food", time_of_day: "08:30", repeat_rule: "daily", done: 0, }, onShow() { this.load(); }, async load() { const date = this.data.date; try { const [pets, result] = await Promise.all([ secure("/pets"), secure("/tasks?date=" + date), ]); if (date !== this.data.date) return; const tasks = result.items.map((t) => ({ ...t, petName: (pets.find((p) => p.id === t.pet_id) || {}).name || "宠物", })); this.setData({ pets, tasks, undoneCount: tasks.filter((t) => !t.completed).length, done: tasks.filter((t) => t.completed).length, }); } catch (e) { toast(e); } }, toggle(e) { return completion.complete( this, this.data.tasks[e.currentTarget.dataset.index], ); }, completeAll() { return completion.completeAll(this); }, open() { if (!this.data.pets.length) { wx.showToast({ title: "请先添加宠物", icon: "none" }); return; } this.setData({ showForm: true, editingId: "", title: "", petIndex: 0, category: "food", time_of_day: "08:30", repeat_rule: "daily", }); }, close() { this.setData({ showForm: false }); }, edit(e) { const task = this.data.tasks[e.currentTarget.dataset.index]; const petIndex = this.data.pets.findIndex((pet) => pet.id === task.pet_id); this.setData({ showForm: true, editingId: task.id, title: task.title, petIndex: Math.max(petIndex, 0), category: task.category, time_of_day: task.time_of_day, repeat_rule: task.repeat_rule, }); }, changeDay(e) { if (this.data.completingAll || this.data.taskBusyIds.length) return; this.setData({ date: shiftDate(this.data.date, Number(e.currentTarget.dataset.days)), }); this.load(); }, showToday() { if (this.data.completingAll || this.data.taskBusyIds.length) return; const today = localDate(); if (this.data.date === today) return; this.setData({ date: today }); this.load(); }, field(e) { this.setData({ [e.currentTarget.dataset.key]: e.detail.value }); }, petChange(e) { this.setData({ petIndex: Number(e.detail.value) }); }, timeChange(e) { this.setData({ time_of_day: e.detail.value }); }, categoryChange(e) { this.setData({ category: e.detail.value }); }, repeatChange(e) { this.setData({ repeat_rule: e.detail.value }); }, async save() { if (this.data.saving) return; if (!this.data.pets.length || !this.data.title.trim()) { wx.showToast({ title: "请选择宠物并填写任务名", icon: "none" }); return; } this.setData({ saving: true }); try { await secure( this.data.editingId ? "/tasks/" + this.data.editingId : "/tasks", this.data.editingId ? "PUT" : "POST", { pet_id: this.data.pets[this.data.petIndex].id, title: this.data.title.trim(), category: this.data.category, time_of_day: this.data.time_of_day, repeat_rule: this.data.repeat_rule, }, ); this.setData({ showForm: false, editingId: "" }); await this.load(); } catch (e) { toast(e); } finally { this.setData({ saving: false }); } }, async remove(e) { const t = this.data.tasks[e.currentTarget.dataset.index]; const result = await wx.showModal({ title: "删除任务", content: "确定删除「" + t.title + "」吗?", }); if (!result.confirm) return; try { await secure("/tasks/" + t.id, "DELETE"); this.load(); } catch (err) { toast(err); } }, });