feat(M08-B): 补统计保洁员筛选

This commit is contained in:
Codex
2026-06-30 17:56:35 +08:00
parent e6bb5e6dc6
commit 78fb6ed2d0
12 changed files with 95 additions and 23 deletions
@@ -773,7 +773,9 @@ export class CleaningTaskRepository {
};
}
async managerStatistics(input: CleaningActor & { from?: string; to?: string; storeId?: string }) {
async managerStatistics(input: CleaningActor & {
from?: string; to?: string; storeId?: string; cleanerUserId?: string;
}) {
this.assertCleaner(input.access, 'read');
this.assertSettlement(input.access, 'read');
const taskWhere = [
@@ -786,6 +788,16 @@ export class CleaningTaskRepository {
taskWhere.push('t.store_id = ?');
taskParams.push(input.storeId);
}
if (input.cleanerUserId) {
taskWhere.push(`(t.cleaner_user_id = ? OR EXISTS (
SELECT 1 FROM qipai_cleaning_task_members filter_member
WHERE filter_member.tenant_id = t.tenant_id
AND filter_member.task_id = t.id
AND filter_member.user_id = ?
AND filter_member.removed_at IS NULL
))`);
taskParams.push(input.cleanerUserId, input.cleanerUserId);
}
if (input.from) {
taskWhere.push('t.created_at >= ?');
taskParams.push(input.from);
@@ -829,6 +841,10 @@ export class CleaningTaskRepository {
settlementWhere.push('s.store_id = ?');
settlementParams.push(input.storeId);
}
if (input.cleanerUserId) {
settlementWhere.push('s.cleaner_user_id = ?');
settlementParams.push(input.cleanerUserId);
}
if (input.from) {
settlementWhere.push('s.created_at >= ?');
settlementParams.push(input.from);
@@ -879,13 +895,18 @@ export class CleaningTaskRepository {
AND DATE(s.paid_at) = DATE(t.created_at)
AND ${storeScopeSql(input.access, 'COALESCE(s.store_id, 0)')}
${input.storeId ? 'AND s.store_id = ?' : ''}
${input.cleanerUserId ? 'AND s.cleaner_user_id = ?' : ''}
), 0) AS paidSettlementCents
FROM qipai_cleaning_tasks t
WHERE ${taskWhereSql}
GROUP BY DATE(t.created_at), t.tenant_id
ORDER BY bucketDate ASC
LIMIT 62`,
input.storeId ? [input.storeId, ...taskParams] : taskParams
[
...(input.storeId ? [input.storeId] : []),
...(input.cleanerUserId ? [input.cleanerUserId] : []),
...taskParams
]
);
return publicManagerStatistics(statusRows, storeRows, settlementRows, memberRows, trendRows);
}
+2 -1
View File
@@ -89,7 +89,8 @@ const settlementWechatSyncSchema = z.object({
const statisticsSchema = z.object({
from: z.string().regex(/^\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}:\d{2})?$/).optional(),
to: z.string().regex(/^\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}:\d{2})?$/).optional(),
storeId: z.string().regex(/^[1-9]\d{0,19}$/).optional()
storeId: z.string().regex(/^[1-9]\d{0,19}$/).optional(),
cleanerUserId: z.string().regex(/^[1-9]\d{0,19}$/).optional()
}).strict();
const reclaimSchema = z.object({
olderThanMinutes: z.coerce.number().int().min(5).max(1440).default(60),