|
|
@@ -130,30 +130,8 @@
|
|
|
|
|
|
<view class="form-item">
|
|
|
<view class="form-label">分配给 <text class="required">*</text></view>
|
|
|
- <view class="assignee-tabs">
|
|
|
- <view class="assignee-tab" :class="{ active: newTask.executorType === 'child' }" @click="newTask.executorType = 'child'">
|
|
|
- <text>孩子</text>
|
|
|
- </view>
|
|
|
- <view class="assignee-tab" :class="{ active: newTask.executorType === 'member' }" @click="newTask.executorType = 'member'">
|
|
|
- <text>家庭成员</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <view class="form-item" v-if="newTask.executorType === 'child'">
|
|
|
- <view class="form-label">选择孩子 <text class="required">*</text></view>
|
|
|
- <checkbox-group @change="onChildSelectChange">
|
|
|
- <label v-for="child in children" :key="child.id">
|
|
|
- <checkbox :value="String(child.id)" :checked="newTask.memberIds.includes(String(child.id))" />
|
|
|
- <text>{{ child.nickname }}</text>
|
|
|
- </label>
|
|
|
- </checkbox-group>
|
|
|
- </view>
|
|
|
-
|
|
|
- <view class="form-item" v-if="newTask.executorType === 'member'">
|
|
|
- <view class="form-label">选择家庭成员 <text class="required">*</text></view>
|
|
|
- <checkbox-group @change="onMemberSelectChange">
|
|
|
- <label v-for="member in familyMembers" :key="member.id">
|
|
|
+ <checkbox-group @change="onFamilyMemberSelectChange">
|
|
|
+ <label v-for="member in familyMembers" :key="member.id" :class="{ 'label-checked': newTask.memberIds.includes(String(member.id)) }">
|
|
|
<checkbox :value="String(member.id)" :checked="newTask.memberIds.includes(String(member.id))" />
|
|
|
<text>{{ member.nickname }}</text>
|
|
|
</label>
|
|
|
@@ -170,7 +148,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { getMyPendingTasks, acceptTask as acceptTaskApi, rejectTask as rejectTaskApi, getTodayTasks, completeTask as completeTaskApi, createTask as createTaskApi, getChildren, getVisibleFamilyMembers } from '../../utils/api.js'
|
|
|
+import { getMyPendingTasks, acceptTask as acceptTaskApi, rejectTask as rejectTaskApi, getTodayTasks, completeTask as completeTaskApi, createTask as createTaskApi, getVisibleFamilyMembers } from '../../utils/api.js'
|
|
|
import { parseDate } from '../../utils/format.js'
|
|
|
|
|
|
export default {
|
|
|
@@ -184,7 +162,6 @@ export default {
|
|
|
isParent: false,
|
|
|
currentMemberId: null,
|
|
|
currentUserId: null,
|
|
|
- children: [],
|
|
|
familyMembers: [],
|
|
|
showAddModal: false,
|
|
|
showRejectModalFlag: false,
|
|
|
@@ -195,7 +172,6 @@ export default {
|
|
|
category: '',
|
|
|
points: 2,
|
|
|
deadline: '',
|
|
|
- executorType: 'child',
|
|
|
memberIds: []
|
|
|
},
|
|
|
categories: ['学习类', '生活类', '运动类', '其他']
|
|
|
@@ -218,11 +194,7 @@ export default {
|
|
|
async loadInitialData() {
|
|
|
this.loading = true
|
|
|
try {
|
|
|
- const [childrenRes, membersRes] = await Promise.all([
|
|
|
- getChildren(),
|
|
|
- getVisibleFamilyMembers()
|
|
|
- ])
|
|
|
- this.children = childrenRes.data || []
|
|
|
+ const membersRes = await getVisibleFamilyMembers()
|
|
|
this.familyMembers = membersRes.data || []
|
|
|
this.loadTodayTasks()
|
|
|
this.loadPendingTasks()
|
|
|
@@ -322,10 +294,8 @@ export default {
|
|
|
category: this.newTask.category,
|
|
|
points: parseInt(this.newTask.points) || 2,
|
|
|
deadline: this.newTask.deadline ? new Date(this.newTask.deadline).getTime() : null,
|
|
|
- executorType: this.newTask.executorType,
|
|
|
- executorId: this.newTask.executorType === 'member' ? Number(this.newTask.memberIds[0]) : null,
|
|
|
- memberId: this.newTask.executorType === 'child' ? Number(this.newTask.memberIds[0]) : null,
|
|
|
- memberIds: this.newTask.executorType === 'child' ? this.newTask.memberIds.map(id => Number(id)) : []
|
|
|
+ executorType: 'member',
|
|
|
+ memberIds: this.newTask.memberIds.map(id => Number(id))
|
|
|
})
|
|
|
uni.showToast({ title: '创建成功', icon: 'success' })
|
|
|
this.showAddModal = false
|
|
|
@@ -344,7 +314,6 @@ export default {
|
|
|
category: '',
|
|
|
points: 2,
|
|
|
deadline: '',
|
|
|
- executorType: 'child',
|
|
|
memberIds: []
|
|
|
}
|
|
|
},
|
|
|
@@ -354,10 +323,7 @@ export default {
|
|
|
onDeadlineChange(e) {
|
|
|
this.newTask.deadline = e.detail.value
|
|
|
},
|
|
|
- onChildSelectChange(e) {
|
|
|
- this.newTask.memberIds = e.detail.value
|
|
|
- },
|
|
|
- onMemberSelectChange(e) {
|
|
|
+ onFamilyMemberSelectChange(e) {
|
|
|
this.newTask.memberIds = e.detail.value
|
|
|
},
|
|
|
formatTime(dateStr) {
|
|
|
@@ -591,11 +557,12 @@ export default {
|
|
|
|
|
|
.modal {
|
|
|
background: #fff;
|
|
|
- border-radius: 20rpx;
|
|
|
+ border-radius: 28rpx;
|
|
|
padding: 40rpx;
|
|
|
width: 85%;
|
|
|
max-height: 80vh;
|
|
|
overflow-y: auto;
|
|
|
+ box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.12);
|
|
|
}
|
|
|
|
|
|
.modal-large {
|
|
|
@@ -603,9 +570,9 @@ export default {
|
|
|
}
|
|
|
|
|
|
.modal-title {
|
|
|
- font-size: 32rpx;
|
|
|
+ font-size: 34rpx;
|
|
|
font-weight: bold;
|
|
|
- margin-bottom: 30rpx;
|
|
|
+ margin-bottom: 32rpx;
|
|
|
text-align: center;
|
|
|
color: #333;
|
|
|
}
|
|
|
@@ -626,11 +593,12 @@ export default {
|
|
|
|
|
|
.modal-btns button {
|
|
|
flex: 1;
|
|
|
- height: 80rpx;
|
|
|
- line-height: 80rpx;
|
|
|
- border-radius: 40rpx;
|
|
|
+ height: 88rpx;
|
|
|
+ line-height: 88rpx;
|
|
|
+ border-radius: 44rpx;
|
|
|
font-size: 28rpx;
|
|
|
border: none;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.06);
|
|
|
}
|
|
|
|
|
|
.modal-btns button:first-child {
|
|
|
@@ -639,13 +607,13 @@ export default {
|
|
|
}
|
|
|
|
|
|
.form-item {
|
|
|
- margin-bottom: 24rpx;
|
|
|
+ margin-bottom: 28rpx;
|
|
|
}
|
|
|
|
|
|
.form-label {
|
|
|
font-size: 28rpx;
|
|
|
color: #333;
|
|
|
- margin-bottom: 12rpx;
|
|
|
+ margin-bottom: 14rpx;
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
|
|
|
@@ -653,69 +621,68 @@ export default {
|
|
|
color: #F97316;
|
|
|
}
|
|
|
|
|
|
-.form-item input, .form-item .picker {
|
|
|
- border: 1rpx solid #ddd;
|
|
|
- border-radius: 10rpx;
|
|
|
- padding: 20rpx;
|
|
|
- font-size: 28rpx;
|
|
|
- width: 100%;
|
|
|
- box-sizing: border-box;
|
|
|
- background: #fafafa;
|
|
|
-}
|
|
|
-
|
|
|
-.form-item .picker {
|
|
|
- color: #333;
|
|
|
+.form-item checkbox-group {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 16rpx;
|
|
|
}
|
|
|
|
|
|
-.textarea {
|
|
|
- min-height: 120rpx;
|
|
|
- width: 100%;
|
|
|
- box-sizing: border-box;
|
|
|
+.form-item label {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10rpx;
|
|
|
font-size: 28rpx;
|
|
|
- padding: 20rpx;
|
|
|
+ color: #333;
|
|
|
+ padding: 18rpx 28rpx;
|
|
|
border: 1rpx solid #ddd;
|
|
|
- border-radius: 10rpx;
|
|
|
+ border-radius: 16rpx;
|
|
|
background: #fafafa;
|
|
|
+ transition: all 0.25s ease;
|
|
|
}
|
|
|
|
|
|
-.assignee-tabs {
|
|
|
- display: flex;
|
|
|
- gap: 20rpx;
|
|
|
+.form-item label.label-checked {
|
|
|
+ border-color: #F97316;
|
|
|
+ background: #FFF7ED;
|
|
|
+ color: #F97316;
|
|
|
}
|
|
|
|
|
|
-.assignee-tab {
|
|
|
- flex: 1;
|
|
|
- padding: 20rpx;
|
|
|
- text-align: center;
|
|
|
- border-radius: 10rpx;
|
|
|
- border: 2rpx solid #ddd;
|
|
|
+.form-item label:active {
|
|
|
+ transform: scale(0.97);
|
|
|
+}
|
|
|
+
|
|
|
+.form-item input, .form-item .picker {
|
|
|
+ border: 1rpx solid #ddd;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 24rpx 28rpx;
|
|
|
font-size: 28rpx;
|
|
|
- color: #666;
|
|
|
+ width: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
background: #fafafa;
|
|
|
+ min-height: 88rpx;
|
|
|
+ transition: all 0.25s ease;
|
|
|
}
|
|
|
|
|
|
-.assignee-tab.active {
|
|
|
+.form-item input:focus {
|
|
|
border-color: #F97316;
|
|
|
- background: #FFF7ED;
|
|
|
- color: #F97316;
|
|
|
- font-weight: bold;
|
|
|
+ background: #fff;
|
|
|
+ box-shadow: 0 0 0 4rpx rgba(249, 115, 22, 0.1);
|
|
|
}
|
|
|
|
|
|
-.form-item checkbox-group {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- gap: 20rpx;
|
|
|
+.form-item .picker {
|
|
|
+ color: #333;
|
|
|
}
|
|
|
|
|
|
-.form-item label {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 10rpx;
|
|
|
+.textarea {
|
|
|
+ min-height: 160rpx;
|
|
|
+ width: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
- padding: 16rpx 24rpx;
|
|
|
+ padding: 24rpx 28rpx;
|
|
|
border: 1rpx solid #ddd;
|
|
|
- border-radius: 10rpx;
|
|
|
+ border-radius: 16rpx;
|
|
|
background: #fafafa;
|
|
|
+ transition: all 0.25s ease;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
</style>
|