项目初始化
This commit is contained in:
王宏豪
2026-09-03 16:49:59 +08:00
commit d7fc8c8982
40 changed files with 2688 additions and 0 deletions

145
pages/plan/plan.js Normal file
View File

@@ -0,0 +1,145 @@
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.switchTab({ url: '/pages/profile/profile' });
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 });
}
});