feat(M08-B): 补任务结算筛选

This commit is contained in:
Codex
2026-06-30 17:30:33 +08:00
parent dac353d184
commit e46d8c0f0a
13 changed files with 212 additions and 35 deletions
@@ -182,7 +182,9 @@ export class CleaningTaskRepository {
return this.listByWhere(where, params, input.page, input.pageSize, 't.updated_at DESC, t.id DESC');
}
async listManage(input: CleaningActor & { page: number; pageSize: number; status?: CleaningTaskStatus }) {
async listManage(input: CleaningActor & {
page: number; pageSize: number; status?: CleaningTaskStatus; storeId?: string; cleanerUserId?: string;
}) {
this.assertCleaner(input.access, 'read');
const where = [
't.tenant_id = ?',
@@ -194,6 +196,20 @@ export class CleaningTaskRepository {
where.push('t.status = ?');
params.push(input.status);
}
if (input.storeId) {
where.push('t.store_id = ?');
params.push(input.storeId);
}
if (input.cleanerUserId) {
where.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
))`);
params.push(input.cleanerUserId, input.cleanerUserId);
}
return this.listByWhere(where, params, input.page, input.pageSize, 't.updated_at DESC, t.id DESC');
}
@@ -374,7 +390,7 @@ export class CleaningTaskRepository {
}
async listSettlements(input: CleaningActor & {
page: number; pageSize: number; status?: CleaningSettlementStatus;
page: number; pageSize: number; status?: CleaningSettlementStatus; storeId?: string; cleanerUserId?: string;
}) {
this.assertSettlement(input.access, 'read');
const where = [
@@ -387,6 +403,14 @@ export class CleaningTaskRepository {
where.push('s.status = ?');
params.push(input.status);
}
if (input.storeId) {
where.push('s.store_id = ?');
params.push(input.storeId);
}
if (input.cleanerUserId) {
where.push('s.cleaner_user_id = ?');
params.push(input.cleanerUserId);
}
const whereSql = where.join(' AND ');
const offset = (input.page - 1) * input.pageSize;
const [counts] = await this.pool.execute<CountRow[]>(
+9 -3
View File
@@ -24,6 +24,10 @@ const listSchema = z.object({
pageSize: z.coerce.number().int().min(1).max(50).default(20),
status: z.enum(cleaningTaskStatuses).optional()
});
const managerTaskListSchema = listSchema.extend({
storeId: z.string().regex(/^[1-9]\d{0,19}$/).optional(),
cleanerUserId: z.string().regex(/^[1-9]\d{0,19}$/).optional()
}).strict();
const paramsSchema = z.object({ taskId: z.string().regex(/^[1-9]\d{0,19}$/) });
const submitSchema = z.object({
photoUrls: z.array(z.string().url()).max(9).default([]),
@@ -51,8 +55,10 @@ const settlementStatusSchema = z.enum(['DRAFT', 'CONFIRMED', 'PAID', 'CANCELLED'
const settlementListSchema = z.object({
page: z.coerce.number().int().min(1).default(1),
pageSize: z.coerce.number().int().min(1).max(50).default(20),
status: settlementStatusSchema.optional()
});
status: settlementStatusSchema.optional(),
storeId: z.string().regex(/^[1-9]\d{0,19}$/).optional(),
cleanerUserId: z.string().regex(/^[1-9]\d{0,19}$/).optional()
}).strict();
const settlementParamsSchema = z.object({ settlementId: z.string().regex(/^[1-9]\d{0,19}$/) });
const settlementGenerateSchema = z.object({
cleanerUserId: z.string().regex(/^[1-9]\d{0,19}$/),
@@ -155,7 +161,7 @@ export async function registerCleaningRoutes(
app.get('/admin-api/cleaning/tasks', async (request, reply) => {
const actor = await requireActor(request, reply, options, 'read');
if (!actor) return;
const query = listSchema.safeParse(request.query);
const query = managerTaskListSchema.safeParse(request.query);
if (!query.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,