| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- <template>
- <view class="section" v-if="displayTasks && displayTasks.length > 0">
- <view class="section-header">
- <text class="section-title">📋 今日任务</text>
- <text class="section-more" @click="$emit('moreTasks')">全部 ›</text>
- </view>
- <view class="task-list">
- <view class="task-card" v-for="task in displayTasks" :key="task.id" @click="$emit('taskClick', task)">
- <view class="task-left">
- <view class="task-check" :class="{ 'checked': task.status === 'completed' }">
- <text class="task-check-icon" v-if="task.status === 'completed'">✓</text>
- </view>
- </view>
- <view class="task-content">
- <text class="task-name" :class="{ 'done': task.status === 'completed' }">{{ task.title }}</text>
- <view class="task-meta">
- <text class="task-points" v-if="task.points">+{{ task.points }}分</text>
- <text class="task-penalty" v-if="task.penalty">-{{ task.penalty }}分</text>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import api from '@/utils/api.js'
- export default {
- props: {
- dimensionCode: { type: String, required: true },
- tasks: { type: Array, default: function() { return [] } },
- memberId: { type: Number, default: null }
- },
- data: function() {
- return {
- tasksData: []
- }
- },
- computed: {
- displayTasks: function() {
- return this.tasksData.length > 0 ? this.tasksData : this.tasks
- }
- },
- created: function() {
- this.loadTasks()
- },
- methods: {
- loadTasks: function() {
- var self = this
- if (!self.memberId) return
- api.getTodayTasksByCategory(self.memberId, self.dimensionCode).then(function(res) {
- self.tasksData = res.data || []
- }).catch(function() {
- // silently fail
- })
- }
- }
- }
- </script>
- <style scoped>
- .section {
- margin: 20rpx 20rpx;
- }
- .section-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20rpx;
- }
- .section-title {
- font-size: 30rpx;
- font-weight: bold;
- color: #333;
- }
- .section-more {
- font-size: 24rpx;
- color: #999;
- }
- .task-list {
- display: flex;
- flex-direction: column;
- }
- .task-card {
- display: flex;
- flex-direction: row;
- align-items: center;
- background: #fff;
- border-radius: 16rpx;
- padding: 24rpx 20rpx;
- box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
- margin-bottom: 16rpx;
- }
- .task-card:active { opacity: 0.8; }
- .task-left {
- margin-right: 20rpx;
- }
- .task-check {
- width: 44rpx;
- height: 44rpx;
- border-radius: 50%;
- border: 3rpx solid #ddd;
- display: flex;
- align-items: center;
- justify-content: center;
- background: #f9f9f9;
- }
- .task-check.checked {
- background: #22C55E;
- border-color: #22C55E;
- }
- .task-check-icon {
- font-size: 24rpx;
- color: #fff;
- font-weight: bold;
- }
- .task-content {
- flex: 1;
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- }
- .task-name {
- font-size: 28rpx;
- color: #333;
- }
- .task-name.done {
- text-decoration: line-through;
- color: #999;
- }
- .task-meta {
- display: flex;
- flex-direction: row;
- align-items: center;
- }
- .task-points {
- font-size: 24rpx;
- color: #22C55E;
- margin-right: 12rpx;
- }
- .task-penalty {
- font-size: 24rpx;
- color: #EF4444;
- }
- </style>
|