обновлен reminders
This commit is contained in:
@@ -191,7 +191,7 @@ public sealed class ReminderService(
|
|||||||
reminders.Add(new ReminderDto(
|
reminders.Add(new ReminderDto(
|
||||||
row.ApproverEmail!,
|
row.ApproverEmail!,
|
||||||
(int)Math.Floor((now - deadline).TotalHours),
|
(int)Math.Floor((now - deadline).TotalHours),
|
||||||
BuildUrl(type, row),
|
BuildUrl(type, row, listId),
|
||||||
row.AskOverdueReason ?? type.AskOverdueReason ?? false,
|
row.AskOverdueReason ?? type.AskOverdueReason ?? false,
|
||||||
type.Id,
|
type.Id,
|
||||||
type.Name,
|
type.Name,
|
||||||
@@ -207,12 +207,17 @@ public sealed class ReminderService(
|
|||||||
/// Ссылка ведёт в тот раздел портала, которому принадлежит просроченный шаг:
|
/// Ссылка ведёт в тот раздел портала, которому принадлежит просроченный шаг:
|
||||||
/// исполнителя незачем высаживать в «На согласовании». Сама заявка всё равно
|
/// исполнителя незачем высаживать в «На согласовании». Сама заявка всё равно
|
||||||
/// откроется панелью поверх раздела (rpmode=approve).
|
/// откроется панелью поверх раздела (rpmode=approve).
|
||||||
|
///
|
||||||
|
/// listId — server-relative url партиции (см. shared/routing.ts в
|
||||||
|
/// request-portal, параметр rplist): без него архивная заявка открылась бы
|
||||||
|
/// так, будто лежит в ТЕКУЩЕЙ партиции типа, и портал не нашёл бы её.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private string BuildUrl(RequestType type, ApprovalRow row) =>
|
private string BuildUrl(RequestType type, ApprovalRow row, string listId) =>
|
||||||
options.Value.RequestUrlTemplate
|
options.Value.RequestUrlTemplate
|
||||||
.Replace("{siteUrl}", type.SiteUrl!.TrimEnd('/'))
|
.Replace("{siteUrl}", type.SiteUrl!.TrimEnd('/'))
|
||||||
.Replace("{pageUrl}", type.PageUrl)
|
.Replace("{pageUrl}", type.PageUrl)
|
||||||
.Replace("{requestId}", row.TicketId.ToString())
|
.Replace("{requestId}", row.TicketId.ToString())
|
||||||
|
.Replace("{listId}", Uri.EscapeDataString(listId))
|
||||||
.Replace("{nav}", row.Phase == ApprovalPhases.Execution ? "execution" : "approvals");
|
.Replace("{nav}", row.Phase == ApprovalPhases.Execution ? "execution" : "approvals");
|
||||||
|
|
||||||
/// <summary>«Заявка на приём — данные» → «Заявка на приём — согласование».</summary>
|
/// <summary>«Заявка на приём — данные» → «Заявка на приём — согласование».</summary>
|
||||||
|
|||||||
@@ -3,19 +3,25 @@ namespace Tnsu.ApprovalRoute.Application.Reminders;
|
|||||||
public sealed class RemindersOptions
|
public sealed class RemindersOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Шаблон ссылки на заявку. Подстановки: {siteUrl}, {pageUrl}, {requestId}, {nav}.
|
/// Шаблон ссылки на заявку. Подстановки: {siteUrl}, {pageUrl}, {requestId},
|
||||||
|
/// {listId}, {nav}.
|
||||||
///
|
///
|
||||||
/// Портал — одностраничный и живёт в КОРНЕ сайта, отдельного пути к странице
|
/// Портал — одностраничный и живёт в КОРНЕ сайта, отдельного пути к странице
|
||||||
/// нет; всё состояние передаётся параметрами запроса (см. shared/routing.ts
|
/// нет; всё состояние передаётся параметрами запроса (см. shared/routing.ts
|
||||||
/// в request-portal). Пример живой ссылки:
|
/// в request-portal). Пример живой ссылки:
|
||||||
/// https://tnsukz.sharepoint.com/sites/requests?rpnav=approvals&rpmode=approve&rptype=it-1c-ticket&rpid=11
|
/// https://tnsukz.sharepoint.com/sites/requests?rpnav=approvals&rpmode=approve&rptype=it-1c-ticket&rpid=11&rplist=%2Fsites%2Frequests%2FLists%2F...
|
||||||
///
|
///
|
||||||
/// {pageUrl} — это PageUrl типа заявки, то есть КЛЮЧ ФОРМЫ (it-1c-ticket), а
|
/// {pageUrl} — это PageUrl типа заявки, то есть КЛЮЧ ФОРМЫ (it-1c-ticket), а
|
||||||
/// не путь к странице: в портале он и подставляется в rptype.
|
/// не путь к странице: в портале он и подставляется в rptype.
|
||||||
///
|
///
|
||||||
|
/// {listId} — server-relative url КОНКРЕТНОЙ партиции, где лежит строка
|
||||||
|
/// согласования (параметр rplist). Без него портал открывал бы заявку так,
|
||||||
|
/// будто она лежит в ТЕКУЩЕЙ партиции типа, и архивная заявка не находилась
|
||||||
|
/// бы вовсе (см. IRoute.listId в request-portal/shared/routing.ts).
|
||||||
|
///
|
||||||
/// Вынесено в конфигурацию, чтобы смена разметки ссылок в портале правилась
|
/// Вынесено в конфигурацию, чтобы смена разметки ссылок в портале правилась
|
||||||
/// настройкой, а не пересборкой сервиса.
|
/// настройкой, а не пересборкой сервиса.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RequestUrlTemplate { get; set; } =
|
public string RequestUrlTemplate { get; set; } =
|
||||||
"{siteUrl}?rpnav={nav}&rpmode=approve&rptype={pageUrl}&rpid={requestId}";
|
"{siteUrl}?rpnav={nav}&rpmode=approve&rptype={pageUrl}&rpid={requestId}&rplist={listId}";
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -215,8 +215,8 @@ public sealed class ReminderServiceTests : IClassFixture<PostgresDatabaseFixture
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Портал — одностраничный и живёт в корне сайта; вид ссылки подтверждён
|
// Портал — одностраничный и живёт в корне сайта; вид ссылки подтверждён
|
||||||
// живым примером:
|
// живым примером (см. docs/routing.md в request-portal):
|
||||||
// https://tnsukz.sharepoint.com/sites/requests?rpnav=approvals&rpmode=approve&rptype=it-1c-ticket&rpid=11
|
// https://tnsukz.sharepoint.com/sites/requests?rpnav=approvals&rpmode=approve&rptype=it-1c-ticket&rpid=11&rplist=%2Fsites%2Frequests%2FLists%2Fit-1c-ticket
|
||||||
[Fact(DisplayName = "Ссылка на заявку собирается в том же виде, что и в портале")]
|
[Fact(DisplayName = "Ссылка на заявку собирается в том же виде, что и в портале")]
|
||||||
public async Task Url_MatchesPortalFormat()
|
public async Task Url_MatchesPortalFormat()
|
||||||
{
|
{
|
||||||
@@ -228,7 +228,8 @@ public sealed class ReminderServiceTests : IClassFixture<PostgresDatabaseFixture
|
|||||||
|
|
||||||
result.Value.ShouldHaveSingleItem().Url.ShouldBe(
|
result.Value.ShouldHaveSingleItem().Url.ShouldBe(
|
||||||
"https://tnsukz.sharepoint.com/sites/requests" +
|
"https://tnsukz.sharepoint.com/sites/requests" +
|
||||||
"?rpnav=approvals&rpmode=approve&rptype=/it-1c-ticket&rpid=11");
|
"?rpnav=approvals&rpmode=approve&rptype=/it-1c-ticket&rpid=11" +
|
||||||
|
"&rplist=%2Fsites%2Frequests%2FLists%2Fit-1c-ticket");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact(DisplayName = "Просроченный шаг исполнения ведёт в раздел «На исполнении», а не в согласование")]
|
[Fact(DisplayName = "Просроченный шаг исполнения ведёт в раздел «На исполнении», а не в согласование")]
|
||||||
|
|||||||
Reference in New Issue
Block a user