From 0f88a23ad1f0a9d9a9590566386b10a555af510b Mon Sep 17 00:00:00 2001 From: "gorbenko.pavel" Date: Wed, 7 Oct 2026 15:10:33 +0500 Subject: [PATCH] =?UTF-8?q?fix:=20=D1=81=D0=BC=D0=B5=D0=BD=D0=B0=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B3=D0=BB=D0=B0=D1=81=D1=83=D1=8E=D1=89=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=B2=20=D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D0=BA=D0=B5=20?= =?UTF-8?q?=C2=AB=D1=82=D1=80=D0=BE=D0=B3=D0=B0=D0=B5=D1=82=C2=BB=20=D0=B7?= =?UTF-8?q?=D0=B0=D1=8F=D0=B2=D0=BA=D1=83,=20=D1=87=D1=82=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=87=D0=B5=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D0=BA=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Права на заявку выдаёт бэкенд по вебхуку на изменение элемента списка данных. Массовая и одиночная замена писали только в список согласования, вебхук не приходил, и новый человек видел «Элемент не найден». Теперь после смены (и добавления шага) в заявку пишется её текущий RequestStatus — появляется новая версия элемента. Co-Authored-By: Claude Sonnet 5.5 --- .../components/screens/ManageByUserScreen.tsx | 6 +++- .../screens/ManageRequestsScreen.tsx | 7 +++-- .../services/requestManageService.ts | 28 +++++++++++++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/frontend/src/webparts/approvalAdmin/components/screens/ManageByUserScreen.tsx b/frontend/src/webparts/approvalAdmin/components/screens/ManageByUserScreen.tsx index fb61df3..2cf5b80 100644 --- a/frontend/src/webparts/approvalAdmin/components/screens/ManageByUserScreen.tsx +++ b/frontend/src/webparts/approvalAdmin/components/screens/ManageByUserScreen.tsx @@ -265,7 +265,11 @@ export const ManageByUserScreen: React.FC = ({ api, di // Фаза 2: «чистые» строки — параллельно, друг от друга не зависят. const replaced = await mapWithLimit( clean, - row => requestManage.reassignApprover(row, row.id, email, position), + row => + requestManage.reassignApprover(row, row.id, email, position, { + ticketId: row.ticketId, + dataListId: row.listId + }), { onSettled: advanceProgress } ); replaced.forEach(result => { diff --git a/frontend/src/webparts/approvalAdmin/components/screens/ManageRequestsScreen.tsx b/frontend/src/webparts/approvalAdmin/components/screens/ManageRequestsScreen.tsx index 0300a92..4c9fda1 100644 --- a/frontend/src/webparts/approvalAdmin/components/screens/ManageRequestsScreen.tsx +++ b/frontend/src/webparts/approvalAdmin/components/screens/ManageRequestsScreen.tsx @@ -433,7 +433,10 @@ export const ManageRequestsScreen: React.FC = ({ api // SharePoint, и параллельные update по одному элементу списка могут // затереть друг друга (последний выигрывает). return requestManage - .reassignApprover(matrix, rowId, email, position) + .reassignApprover(matrix, rowId, email, position, { + ticketId: matrix.request.id, + dataListId: matrix.request.listId + }) .then(() => requestManage.updateRowSla(matrix, rowId, slaHours, askOverdueReason)) .then(() => { const found = findEmployeeByEmail(employees.items, email); @@ -507,7 +510,7 @@ export const ManageRequestsScreen: React.FC = ({ api setMatrix({ ...matrix, rows: [...matrix.rows, ghostRow] }); requestManage - .addRow(matrix, matrix.request.id, phase, order, initialStatus, email, position, false) + .addRow(matrix, matrix.request.id, phase, order, initialStatus, email, position, false, matrix.request.listId) .then(() => reloadMatrix(true)) .catch((e: Error) => { setMatrix(previous); diff --git a/frontend/src/webparts/approvalAdmin/services/requestManageService.ts b/frontend/src/webparts/approvalAdmin/services/requestManageService.ts index 28f4cd7..cb8cb05 100644 --- a/frontend/src/webparts/approvalAdmin/services/requestManageService.ts +++ b/frontend/src/webparts/approvalAdmin/services/requestManageService.ts @@ -87,13 +87,32 @@ export class RequestManageService { }); } + /** + * Права на заявку новому человеку в маршруте выдаёт бэкенд портала по вебхуку + * на изменение элемента СПИСКА ДАННЫХ. Правка одного лишь списка согласования + * вебхук не вызывает — новый человек видел бы «Элемент не найден». Поэтому + * после смены/добавления человека пишем в заявку её текущий RequestStatus как + * есть: значение то же, но у элемента появляется новая версия и приходит + * вебхук (то же делает request-portal, ApproverService.touchRequest). + * + * dataListId — серверный относительный url списка данных (партиции), где лежит + * заявка (ManagedRequestSummary.listId / UserApprovalRow.listId). + */ + private async touchRequest(siteUrl: string, dataListId: string, ticketId: number): Promise { + const item = this.clientFor(siteUrl).web.getList(dataListId).items.getById(ticketId); + const current = (await item.select('RequestStatus')()) as { RequestStatus?: string }; + await item.update({ RequestStatus: current.RequestStatus || '' }); + } + /** Переназначить согласующего/исполнителя строки. Вызывающая сторона обязана - * проверить isEditableRowStatus(row.status) — сервис это не перепроверяет. */ + * проверить isEditableRowStatus(row.status) — сервис это не перепроверяет. + * request — заявка строки: по ней «трогается» элемент списка данных, см. touchRequest. */ public async reassignApprover( matrix: Pick, rowId: number, email: string, - position: string + position: string, + request: { ticketId: number; dataListId: string } ): Promise { const sp = this.clientFor(matrix.siteUrl); const approverId = await this.resolveUserId(sp, email); @@ -101,6 +120,7 @@ export class RequestManageService { Title: position, [`${FIELDS.approver}Id`]: approverId }); + await this.touchRequest(matrix.siteUrl, request.dataListId, request.ticketId); } /** @@ -148,7 +168,8 @@ export class RequestManageService { status: string, email: string, position: string, - allowReassign: boolean + allowReassign: boolean, + dataListId: string ): Promise { const sp = this.clientFor(matrix.siteUrl); const approverId = await this.resolveUserId(sp, email); @@ -161,6 +182,7 @@ export class RequestManageService { AllowReassignToOtherApprovers: allowReassign, [FIELDS.phase]: phase }); + await this.touchRequest(matrix.siteUrl, dataListId, ticketId); } /** -- 2.34.1