const api = require('../../utils/api'); const auth = require('../../utils/auth'); const TYPES = ['weekly', 'monthly', 'yearly']; const TYPE_LABELS = ['周计划', '月计划', '年计划']; Page({ data: { types: TYPE_LABELS, typeIndex: 0, view: 'overview', // overview | detail loading: false, refreshing: false, periodKey: '', canSubmit: false, message: '', myChecked: false, myStatus: '', myRecord: null, myThumbs: [], unassignedCount: 0, groups: [], selectedGroupName: '', members: [] }, onShow() { auth.ensureLogin().then((token) => { if (!token) { wx.showToast({ title: '请先登录', icon: 'none' }); setTimeout(() => wx.switchTab({ url: '/pages/profile/profile' }), 500); return; } wx.removeStorageSync('plan_overview_dirty'); this.setData({ view: 'overview' }); this.loadOverview(); }).catch(() => {}); }, onTypeChange(e) { const typeIndex = Number(e.currentTarget.dataset.index); if (typeIndex === this.data.typeIndex) { return; } this.setData({ typeIndex, view: 'overview', selectedGroupName: '', members: [] }); this.loadOverview(); }, onRefresh() { this.setData({ refreshing: true }); this.loadOverview(); }, loadOverview() { const type = TYPES[this.data.typeIndex]; this.setData({ loading: true }); api.request({ url: '/api/v1/plan/groups', data: { type } }) .then((res) => { const groups = (res.groups || []).map((g) => ({ ...g, percent: g.total ? Math.round(((g.checked_count || 0) / g.total) * 100) : 0 })); this.setData({ loading: false, refreshing: false, periodKey: res.period_key || '', canSubmit: !!res.can_submit, message: res.message || '', myChecked: !!res.my_checked, myStatus: res.my_status || '', myRecord: res.my_record || null, myThumbs: ((res.my_record && res.my_record.attachments) || []).map((p) => this.planFileUrl(p)), unassignedCount: res.unassigned_count || 0, groups }); }) .catch(() => { this.setData({ loading: false, refreshing: false }); wx.showToast({ title: '加载小组失败', icon: 'none' }); }); }, openGroup(e) { const groupName = e.currentTarget.dataset.group; if (!groupName) { return; } this.setData({ selectedGroupName: groupName, view: 'detail', members: [] }); this.loadDetail(); }, loadDetail() { const type = TYPES[this.data.typeIndex]; this.setData({ loading: true }); api.request({ url: '/api/v1/plan/group', data: { type, group_name: this.data.selectedGroupName, period_key: this.data.periodKey } }).then((res) => { this.setData({ loading: false, periodKey: res.period_key || this.data.periodKey, canSubmit: !!res.can_submit, message: res.message || '', members: res.members || [] }); }).catch(() => { this.setData({ loading: false }); wx.showToast({ title: '加载成员失败', icon: 'none' }); }); }, backToOverview() { this.setData({ view: 'overview', selectedGroupName: '', members: [] }); this.loadOverview(); }, planFileUrl(path) { if (!path) return ''; if (/^https?:\/\//i.test(path)) return path; const parts = String(path).replace(/^attachments\//, '').split('/'); if (parts.length < 4) return ''; return api.STATIC_BASE_URL + '/clock/static/plan/' + parts.slice(0, 4).map(encodeURIComponent).join('/'); }, previewMyImage(e) { const index = Number(e.currentTarget.dataset.index); const urls = this.data.myThumbs; const src = urls[index]; if (!src) return; wx.previewImage({ current: src, urls }); }, goSubmit() { const type = TYPES[this.data.typeIndex]; if (type === 'weekly' && !this.data.canSubmit) { wx.showToast({ title: this.data.message || '当前不可打卡', icon: 'none' }); return; } const params = [ 'plan_type=' + type, 'period_key=' + encodeURIComponent(this.data.periodKey), 'group_name=' ].join('&'); wx.navigateTo({ url: '/pages/plan-submit/plan-submit?' + params }); } });