const { secure, toast } = require("../../utils/api"); const { localDate } = require("../../utils/date"); function dateLabel() { const now = new Date(); return `${now.getMonth() + 1}月${now.getDate()}日 周${"日一二三四五六"[now.getDay()]}`; } Page({ data: { locationName: "当前位置", headerSubtitle: dateLabel() + " · 轻触获取天气", pets: [], selected: [], tasks: [], walkCount: 0, name: "铲屎官", loading: true, }, onShow() { this.load(); this.updateEnvironmentLabel(); if (!this.environmentAt || Date.now() - this.environmentAt > 15 * 60 * 1000) { this.refreshEnvironment(); } }, updateEnvironmentLabel() { this.setData({ headerSubtitle: dateLabel() + " · " + (this.weatherLabel || "轻触获取天气") }); }, async refreshEnvironment(event) { if (this.environmentBusy) return; this.environmentBusy = true; const tapped = !!event; let positioned = false; try { const settings = await new Promise((resolve, reject) => wx.getSetting({ success: resolve, fail: reject })); if (settings.authSetting["scope.userLocation"] === false) { if (!tapped) throw new Error("location-denied"); const enabled = await new Promise((resolve, reject) => wx.openSetting({ success: resolve, fail: reject })); if (!enabled.authSetting["scope.userLocation"]) throw new Error("location-denied"); } this.weatherLabel = "正在获取天气"; this.updateEnvironmentLabel(); const point = await new Promise((resolve, reject) => wx.getLocation({ type: "gcj02", success: resolve, fail: reject, })); positioned = true; const result = await secure("/environment", "GET", { latitude: point.latitude, longitude: point.longitude }); this.setData({ locationName: result.location_name }); this.weatherLabel = result.weather ? `${result.weather.description} ${result.weather.temperature}°C` : "天气暂不可用"; this.environmentAt = result.weather ? Date.now() : 0; } catch (error) { const denied = /denied|deny|auth/.test(error.errMsg || error.message || ""); this.setData({ locationName: positioned ? "位置暂不可用" : denied ? "开启定位" : "定位暂不可用" }); this.weatherLabel = denied ? "轻触开启定位" : "轻触重试"; if (tapped && !denied) wx.showToast({ title: positioned ? "位置和天气获取失败,请重试" : "定位失败,请重试", icon: "none" }); } finally { this.environmentBusy = false; this.updateEnvironmentLabel(); } }, async load() { try { const [pets, tasks, walks, me] = await Promise.all([ secure("/pets"), secure("/tasks"), secure("/walks"), secure("/me"), ]); const chosen = wx.getStorageSync("walk_pet_ids") || [], month = localDate().slice(0, 7); this.setData({ pets, selected: chosen.filter((id) => pets.some((p) => p.id === id)), tasks: tasks.items, walkCount: walks.filter((w) => w.started_at.slice(0, 7) === month) .length, name: me.nickname || "铲屎官", loading: false, }); } catch (e) { this.setData({ loading: false }); toast(e); } }, pick(e) { this.setData({ selected: e.detail.selected }); wx.setStorageSync("walk_pet_ids", e.detail.selected); }, start() { if (!this.data.selected.length) { wx.showToast({ title: "先选择一起出门的狗狗", icon: "none" }); return; } wx.redirectTo({ url: "/pages/walk/walk" }); }, goTasks() { wx.redirectTo({ url: "/pages/tasks/tasks" }); }, goWalks() { wx.navigateTo({ url: "/pages/walk-records/walk-records" }); }, async complete(e) { const id = e.currentTarget.dataset.id, task = this.data.tasks.find((t) => t.id === id); try { await secure("/tasks/" + id + "/completion", "PUT", { date: localDate(), completed: !task.completed, }); await this.load(); } catch (err) { toast(err); } }, });