feat(M08-B): 补任务免清洁

This commit is contained in:
Codex
2026-07-07 15:08:32 +08:00
parent 2a4db54b94
commit 8ffb940bdb
12 changed files with 145 additions and 17 deletions
+9
View File
@@ -137,6 +137,7 @@
@complete-many="handleCompleteMany"
@reject="handleReject"
@reject-many="handleRejectMany"
@exempt="handleExempt"
@reclaim="handleReclaim"
/>
</el-tab-pane>
@@ -227,6 +228,7 @@ import {
completeCleaningTask,
confirmCleaningSettlement,
createStaffUser,
exemptCleaningTask,
executeWechatTransfer,
generateCleaningSettlement,
getCleaningStatistics,
@@ -532,6 +534,13 @@ async function handleRejectMany(input: { taskIds: string[]; reason: string }) {
}, `已批量驳回 ${input.taskIds.length} 个任务`);
}
async function handleExempt(input: { taskId: string; note?: string }) {
await runAction(async () => {
await exemptCleaningTask(session.value, input.taskId, input.note);
await Promise.all([loadTasks(), loadStatistics()]);
}, '宸叉爣璁板厤娓呮磥');
}
async function handleReclaim(input: { olderThanMinutes: number; limit: number }) {
await runAction(async () => {
await reclaimCleaningTimeouts(session.value, input);
+7
View File
@@ -165,6 +165,13 @@ export function rejectCleaningTask(session: ApiSession, taskId: string, reason:
});
}
export function exemptCleaningTask(session: ApiSession, taskId: string, note?: string) {
return request<CleaningTask>(session, `/cleaning/tasks/${encodeURIComponent(taskId)}/exempt`, {
method: 'POST',
body: JSON.stringify({ note })
});
}
export function listCleaningTaskMembers(session: ApiSession, taskId: string) {
return request<CleaningTaskMember[]>(
session,
+18 -2
View File
@@ -113,7 +113,7 @@
</el-badge>
</template>
</el-table-column>
<el-table-column label="操作" width="270" fixed="right">
<el-table-column label="操作" width="340" fixed="right">
<template #default="{ row }">
<div class="row-actions">
<el-button size="small" :icon="ListChecks" @click="openDetail(row)">详情</el-button>
@@ -137,6 +137,15 @@
>
驳回
</el-button>
<el-button
size="small"
type="warning"
:icon="Ban"
:disabled="!canExempt(row.status)"
@click="$emit('exempt', { taskId: row.id, note: '\u540e\u53f0\u6807\u8bb0\u514d\u6e05\u6d01' })"
>
{{ '\u514d\u6e05\u6d01' }}
</el-button>
</div>
</template>
</el-table-column>
@@ -416,6 +425,7 @@
import { computed, reactive, ref, watch } from 'vue';
import {
BadgeCheck,
Ban,
Check,
Download,
Image,
@@ -467,6 +477,7 @@ const emit = defineEmits<{
'complete-many': [{ taskIds: string[]; note?: string }];
reject: [{ taskId: string; reason: string }];
'reject-many': [{ taskIds: string[]; reason: string }];
exempt: [{ taskId: string; note?: string }];
reclaim: [{ olderThanMinutes: number; limit: number }];
}>();
@@ -477,7 +488,8 @@ const statusOptions = [
{ label: '进行', value: 'STARTED' },
{ label: '待验', value: 'SUBMITTED' },
{ label: '完成', value: 'COMPLETED' },
{ label: '驳回', value: 'REJECTED' }
{ label: '\u9a73\u56de', value: 'REJECTED' },
{ label: '\u514d\u6e05\u6d01', value: 'EXEMPT' }
];
const filterDraft = reactive({ storeId: props.filters.storeId, cleanerUserId: props.filters.cleanerUserId });
const reclaimForm = reactive({ olderThanMinutes: 60, limit: 20 });
@@ -532,6 +544,10 @@ function canSelectTask(row: CleaningTask) {
return row.status === 'SUBMITTED';
}
function canExempt(status: TaskStatus) {
return ['WAITING', 'CLAIMED', 'STARTED', 'SUBMITTED', 'REJECTED'].includes(status);
}
function handleSelectionChange(rows: CleaningTask[]) {
selectedTasks.value = rows;
}