feat(M08-C): 补保洁与设备运营

This commit is contained in:
Codex
2026-08-10 10:52:06 +08:00
parent a95e8bf8c8
commit 65932a8000
17 changed files with 815 additions and 104 deletions
+95 -70
View File
@@ -164,29 +164,39 @@ 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 = managerTaskListSchema.safeParse(request.query);
if (!query.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.listManage({ ...actor, ...query.data }),
traceId: request.traceId
}));
});
for (const path of [
'/admin-api/cleaning/tasks',
'/app-api/management/cleaning/tasks'
]) {
app.get(path, async (request, reply) => {
const actor = await requireActor(request, reply, options, 'read');
if (!actor) return;
const query = managerTaskListSchema.safeParse(request.query);
if (!query.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.listManage({ ...actor, ...query.data }),
traceId: request.traceId
}));
});
}
app.get('/admin-api/cleaning/statistics', async (request, reply) => {
const actor = await requireActor(request, reply, options, 'read');
if (!actor) return;
const query = statisticsSchema.safeParse(request.query);
if (!query.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.managerStatistics({ ...actor, ...query.data }),
traceId: request.traceId
}));
});
for (const path of [
'/admin-api/cleaning/statistics',
'/app-api/management/cleaning/statistics'
]) {
app.get(path, async (request, reply) => {
const actor = await requireActor(request, reply, options, 'read');
if (!actor) return;
const query = statisticsSchema.safeParse(request.query);
if (!query.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.managerStatistics({ ...actor, ...query.data }),
traceId: request.traceId
}));
});
}
app.get('/admin-api/cleaning/settlement-candidates', async (request, reply) => {
const actor = await requireActor(request, reply, options, 'read');
@@ -385,56 +395,71 @@ export async function registerCleaningRoutes(
}));
});
app.post('/admin-api/cleaning/tasks/:taskId/complete', async (request, reply) => {
const actor = await requireActor(request, reply, options, 'write');
if (!actor) return;
const params = paramsSchema.safeParse(request.params);
const body = completeSchema.safeParse(request.body ?? {});
if (!params.success || !body.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.complete({
...actor,
taskId: params.data.taskId,
note: body.data.note
}),
traceId: request.traceId
}));
});
for (const path of [
'/admin-api/cleaning/tasks/:taskId/complete',
'/app-api/management/cleaning/tasks/:taskId/complete'
]) {
app.post(path, async (request, reply) => {
const actor = await requireActor(request, reply, options, 'write');
if (!actor) return;
const params = paramsSchema.safeParse(request.params);
const body = completeSchema.safeParse(request.body ?? {});
if (!params.success || !body.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.complete({
...actor,
taskId: params.data.taskId,
note: body.data.note
}),
traceId: request.traceId
}));
});
}
app.post('/admin-api/cleaning/tasks/:taskId/reject', async (request, reply) => {
const actor = await requireActor(request, reply, options, 'write');
if (!actor) return;
const params = paramsSchema.safeParse(request.params);
const body = rejectSchema.safeParse(request.body ?? {});
if (!params.success || !body.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.reject({
...actor,
taskId: params.data.taskId,
reason: body.data.reason
}),
traceId: request.traceId
}));
});
for (const path of [
'/admin-api/cleaning/tasks/:taskId/reject',
'/app-api/management/cleaning/tasks/:taskId/reject'
]) {
app.post(path, async (request, reply) => {
const actor = await requireActor(request, reply, options, 'write');
if (!actor) return;
const params = paramsSchema.safeParse(request.params);
const body = rejectSchema.safeParse(request.body ?? {});
if (!params.success || !body.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.reject({
...actor,
taskId: params.data.taskId,
reason: body.data.reason
}),
traceId: request.traceId
}));
});
}
app.post('/admin-api/cleaning/tasks/:taskId/exempt', async (request, reply) => {
const actor = await requireActor(request, reply, options, 'write');
if (!actor) return;
const params = paramsSchema.safeParse(request.params);
const body = exemptSchema.safeParse(request.body ?? {});
if (!params.success || !body.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.exempt({
...actor,
taskId: params.data.taskId,
note: body.data.note
}),
traceId: request.traceId
}));
});
for (const path of [
'/admin-api/cleaning/tasks/:taskId/exempt',
'/app-api/management/cleaning/tasks/:taskId/exempt'
]) {
app.post(path, async (request, reply) => {
const actor = await requireActor(request, reply, options, 'write');
if (!actor) return;
const params = paramsSchema.safeParse(request.params);
const body = exemptSchema.safeParse(request.body ?? {});
if (!params.success || !body.success) return invalid(reply, request.traceId);
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.repository.exempt({
...actor,
taskId: params.data.taskId,
note: body.data.note
}),
traceId: request.traceId
}));
});
}
app.post('/admin-api/cleaning/reclaim-timeouts', async (request, reply) => {
const actor = await requireActor(request, reply, options, 'write');