Files
sundynix-plant-mp/pages/tasks/index.js
T
2026-02-06 17:27:35 +08:00

219 lines
6.6 KiB
JavaScript

// pages/tasks/index.js
import request from '../../utils/request';
Page({
data: {
tasks: [],
groupedTasks: [],
progress: 0,
completingTask: null,
remark: ''
},
onLoad() {
this.fetchTodayTasks();
},
onShow() {
if (typeof this.getTabBar === 'function' &&
this.getTabBar()) {
this.getTabBar().setData({ selected: 1 });
}
// Refresh on show
this.fetchTodayTasks();
},
fetchTodayTasks() {
request.get('/plant/todayTask').then(res => {
// Check if res is array (list of PlantTaskVO)
const list = Array.isArray(res) ? res : (res.list || []);
this.processTaskData(list);
}).catch(err => {
console.error('Fetch tasks failed', err);
wx.stopPullDownRefresh();
});
},
processTaskData(plantTaskVOList) {
let totalPacketTasks = 0;
let completedPacketTasks = 0;
const groups = plantTaskVOList.map(vo => {
const plant = vo.MyPlant || vo.myPlant;
if (!plant) return null;
// Parse Image
let imageUrl = '';
if (plant.imgList && plant.imgList.length > 0) {
let url = plant.imgList[0].url;
if (url && !url.startsWith('http') && !url.startsWith('/') && !url.startsWith('wxfile')) {
imageUrl = '/assets/' + url;
} else {
imageUrl = url;
}
}
const plantGroup = {
plantName: plant.name,
plantImage: imageUrl,
tasks: [], // Placeholder, will fill below
hasOverdue: vo.hasExpired
};
const rawTasks = vo.tasks || [];
// 1. Update Global Counters
rawTasks.forEach(t => {
totalPacketTasks++;
if (t.status == 2 || t.status == 3) {
completedPacketTasks++;
}
});
// 2. Filter and Map Tasks for Display
const displayTasks = rawTasks
.filter(t => t.status == 1 || t.status == 2)
.map(t => {
// Status: 1 Pending, 2 Done
const isCompleted = t.status == 2;
// Parse Icon
let taskIcon = null;
if (t.icon && t.icon.startsWith('{')) {
try {
taskIcon = JSON.parse(t.icon);
} catch (e) { }
}
// Check overdue (only for pending tasks)
let isOverdue = false;
let overdueDays = 0;
if (!isCompleted && t.dueDate) {
const due = new Date(t.dueDate);
const today = new Date();
today.setHours(0, 0, 0, 0);
if (due < today) {
isOverdue = true;
const diffTime = Math.abs(today - due);
overdueDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
}
}
return {
id: t.id,
taskType: t.name,
taskIcon: taskIcon,
isOverdue: isOverdue,
overdueDays: overdueDays,
plantName: plant.name,
isCompleted: isCompleted,
original: t
};
});
// Sorting Removed: Tasks stay in original order
// displayTasks.sort((a, b) => {
// if (a.isCompleted === b.isCompleted) return 0;
// return a.isCompleted ? 1 : -1;
// });
plantGroup.tasks = displayTasks;
if (plantGroup.tasks.length === 0) return null;
return plantGroup;
}).filter(g => g !== null);
// Calculate Progress
let progress = 0;
if (totalPacketTasks > 0) {
progress = Math.round((completedPacketTasks / totalPacketTasks) * 100);
}
// Sorting Groups: Overdue first
groups.sort((a, b) => {
if (a.hasOverdue && !b.hasOverdue) return -1;
if (!a.hasOverdue && b.hasOverdue) return 1;
return 0;
});
this.setData({
groupedTasks: groups,
progress,
tasks: groups
});
wx.stopPullDownRefresh();
},
handleTaskClick(e) {
const task = e.currentTarget.dataset.task;
if (task.isCompleted) return;
this.setData({
completingTask: task,
remark: ''
});
},
onPopupVisibleChange(e) {
const visible = e.detail ? e.detail.visible : e.currentTarget.dataset.visible;
if (!visible) {
this.setData({ completingTask: null });
}
},
onRemarkInput(e) {
this.setData({ remark: e.detail.value });
},
handleConfirmComplete() {
if (!this.data.completingTask) return;
const taskId = this.data.completingTask.id;
const remark = this.data.remark || '';
wx.showLoading({ title: '提交中...' });
request.post('/plant/completeTask', {
taskId: taskId,
remark: remark
}).then(() => {
wx.hideLoading();
wx.showToast({ title: '已完成', icon: 'success' });
// Optimistic UI Update
const groups = this.data.groupedTasks;
let updated = false;
for (let g of groups) {
const t = g.tasks.find(x => x.id === taskId);
if (t) {
t.isCompleted = true;
t.isOverdue = false;
// Do NOT sort. Just update status.
updated = true;
break;
}
}
if (updated) {
this.setData({ groupedTasks: groups, tasks: groups, completingTask: null, remark: '' });
} else {
this.setData({ completingTask: null, remark: '' });
}
// Sync with backend
this.fetchTodayTasks();
}).catch(err => {
wx.hideLoading();
console.error('Complete task failed', err);
wx.showToast({ title: '操作失败', icon: 'none' });
});
},
gotoGarden() {
wx.switchTab({
url: '/pages/garden/index'
});
}
})