rebrand: письма и серверные строки ALL MARKET
- EmailTemplates (invite/low-stock/weekly-summary): шапка с текстовым вордмарком «all market» (бренд-цвета, всегда рендерится — без внешних картинок и привязки к домену) + подпись «ALL MARKET — система учёта торговли». - Имя отправителя по умолчанию, темы/тела системных писем, экспорт-README, дневная сводка, тест SMTP → ALL MARKET. - Цвета писем и домены не менялись. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
57f36d8dee
commit
03bdf4d4f1
|
|
@ -115,7 +115,7 @@ public async Task RunAsync(Guid exportId, CancellationToken ct = default)
|
|||
_db.OrgAuditLogs.IgnoreQueryFilters().Where(x => x.OrganizationId == orgId), jsonOpts, ct);
|
||||
|
||||
// README для пользователя.
|
||||
var readme = $@"# Экспорт данных Food Market
|
||||
var readme = $@"# Экспорт данных ALL MARKET
|
||||
|
||||
Экспорт запрошен: {rec.CreatedAt:O}
|
||||
Организация: {orgId}
|
||||
|
|
@ -152,14 +152,14 @@ await using (var s = rEntry.Open())
|
|||
{
|
||||
var publicBase = _cfg["App:PublicBaseUrl"]?.TrimEnd('/') ?? "https://admin.food-market.kz";
|
||||
var link = $"{publicBase}/api/org/export/download/{token}";
|
||||
var body = $@"<p>Ваш экспорт данных Food Market готов.</p>
|
||||
var body = $@"<p>Ваш экспорт данных ALL MARKET готов.</p>
|
||||
<p>Скачать (действительно 24 часа):</p>
|
||||
<p><a href=""{link}"">{link}</a></p>
|
||||
<p>Размер архива: {ms.Length / 1024:N0} KB</p>
|
||||
<p>Если вы не запрашивали экспорт — сообщите администратору организации.</p>";
|
||||
try
|
||||
{
|
||||
await _email.SendAsync(rec.NotifyEmail, "Ваш экспорт данных Food Market готов", body, ct);
|
||||
await _email.SendAsync(rec.NotifyEmail, "Ваш экспорт данных ALL MARKET готов", body, ct);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ select new
|
|||
string Money(decimal d) => $"{d:N0} ₸";
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.Append($"<b>Food Market — сводка за {yStart:dd.MM}</b>\n");
|
||||
sb.Append($"<b>ALL MARKET — сводка за {yStart:dd.MM}</b>\n");
|
||||
sb.Append($"<i>{Esc(orgName)}</i>\n\n");
|
||||
sb.Append($"💰 Выручка: <b>{Money(revenue)}</b>\n");
|
||||
sb.Append($"🧾 Чеков: <b>{count}</b>\n");
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ private async Task<CheckResult> CheckSmtp(bool sendEmail, CancellationToken ct)
|
|||
$"конфиг есть ({s.SmtpHost}); тестовое письмо не отправлялось (sendTestEmail=false)");
|
||||
}
|
||||
// Живой тест — отправляем письмо на FromEmail (сам себе).
|
||||
await _email.SendAsync(s.FromEmail!, "Food Market — diagnostic ping",
|
||||
await _email.SendAsync(s.FromEmail!, "ALL MARKET — diagnostic ping",
|
||||
"Это тест из /admin/diagnostic. Игнорируйте.", ct);
|
||||
sw.Stop();
|
||||
return new("SMTP", CheckStatus.Ok, sw.ElapsedMilliseconds,
|
||||
|
|
|
|||
|
|
@ -84,13 +84,13 @@ public async Task<IActionResult> Forgot([FromBody] ForgotInput input, Cancellati
|
|||
var resetUrl = BuildResetUrl(user.Email!, token);
|
||||
var body =
|
||||
$"Здравствуйте.\n\n" +
|
||||
$"Кто-то запросил восстановление пароля для вашего аккаунта Food Market ({user.Email}).\n" +
|
||||
$"Кто-то запросил восстановление пароля для вашего аккаунта ALL MARKET ({user.Email}).\n" +
|
||||
$"Если это были вы — перейдите по ссылке (действительна 1 час):\n\n" +
|
||||
$"{resetUrl}\n\n" +
|
||||
$"Если вы не запрашивали восстановление — просто игнорируйте это письмо.\n";
|
||||
try
|
||||
{
|
||||
await _email.SendAsync(user.Email!, "Food Market — восстановление пароля", body, ct);
|
||||
await _email.SendAsync(user.Email!, "ALL MARKET — восстановление пароля", body, ct);
|
||||
_logger.LogInformation("Forgot-password email sent to {Email}", user.Email);
|
||||
}
|
||||
catch (EmailNotConfiguredException ex)
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ public async Task<IActionResult> Submit([FromBody] FeedbackInput input, Cancella
|
|||
var ua = HttpContext.Request.Headers["User-Agent"].ToString();
|
||||
var ip = HttpContext.Connection.RemoteIpAddress?.ToString();
|
||||
|
||||
var subject = $"Food Market feedback [{input.Category}] — {org}";
|
||||
var subject = $"ALL MARKET feedback [{input.Category}] — {org}";
|
||||
var body =
|
||||
$"Категория: {input.Category}\n" +
|
||||
$"Организация: {org}\n" +
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ public async Task<ActionResult<EmployeeCreateResult>> Create([FromBody] Employee
|
|||
try
|
||||
{
|
||||
var orgName = await _db.Organizations.Where(o => o.Id == orgId)
|
||||
.Select(o => o.Name).FirstOrDefaultAsync(ct) ?? "Food Market";
|
||||
.Select(o => o.Name).FirstOrDefaultAsync(ct) ?? "ALL MARKET";
|
||||
var loginUrl = (Request.Scheme + "://" + Request.Host.Value + "/login");
|
||||
var (subject, html, text) = _templates.Render("invite", new Dictionary<string, string?>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@ public async Task<IActionResult> TestSend([FromBody] TestSendInput input, Cancel
|
|||
try
|
||||
{
|
||||
await _email.SendAsync(input.ToEmail.Trim(),
|
||||
string.IsNullOrWhiteSpace(input.Subject) ? "Food Market — тестовое сообщение" : input.Subject,
|
||||
string.IsNullOrWhiteSpace(input.Body) ? "Тестовое письмо от Food Market." : input.Body,
|
||||
string.IsNullOrWhiteSpace(input.Subject) ? "ALL MARKET — тестовое сообщение" : input.Subject,
|
||||
string.IsNullOrWhiteSpace(input.Body) ? "Тестовое письмо от ALL MARKET." : input.Body,
|
||||
ct);
|
||||
return Ok(new { ok = true, sentTo = input.ToEmail });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ Subject: Приглашение в {{organizationName}}
|
|||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Приглашение в Food Market</title>
|
||||
<title>Приглашение в ALL MARKET</title>
|
||||
</head>
|
||||
<body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 600px; margin: 0 auto; padding: 24px; color: #1f2937;">
|
||||
<div style="padding-bottom: 16px; border-bottom: 1px solid #e5e7eb; margin-bottom: 20px;">
|
||||
<span style="font-size: 22px; font-weight: 600; color: #0DB70D; letter-spacing: -0.5px;">all</span><span style="font-size: 22px; font-weight: 300; color: #4C4F54;"> market</span>
|
||||
</div>
|
||||
<h2 style="color: #0f766e;">Добро пожаловать в {{organizationName}}</h2>
|
||||
<p>Здравствуйте, {{employeeName}}.</p>
|
||||
<p>Для вас создан доступ к системе Food Market. Войдите по адресу:</p>
|
||||
<p>Для вас создан доступ к системе ALL MARKET. Войдите по адресу:</p>
|
||||
<p style="margin: 20px 0;">
|
||||
<a href="{{loginUrl}}" style="background: #0f766e; color: white; padding: 10px 24px; text-decoration: none; border-radius: 6px; display: inline-block;">Открыть Food Market</a>
|
||||
<a href="{{loginUrl}}" style="background: #0f766e; color: white; padding: 10px 24px; text-decoration: none; border-radius: 6px; display: inline-block;">Открыть ALL MARKET</a>
|
||||
</p>
|
||||
<table style="border-collapse: collapse; background: #f9fafb; padding: 16px; border-radius: 6px;">
|
||||
<tr><td style="padding: 4px 12px;"><strong>Логин</strong></td><td style="padding: 4px 12px;"><code>{{email}}</code></td></tr>
|
||||
|
|
@ -20,5 +23,8 @@ Subject: Приглашение в {{organizationName}}
|
|||
<p style="margin-top: 16px; color: #6b7280; font-size: 13px;">
|
||||
После первого входа смените пароль в личном кабинете. Если вы не ожидали это письмо — просто игнорируйте его, доступ без первого входа не активируется.
|
||||
</p>
|
||||
<p style="margin-top: 28px; padding-top: 16px; border-top: 1px solid #e5e7eb; color: #9ca3af; font-size: 12px;">
|
||||
<strong style="color: #4C4F54;">ALL MARKET</strong> — система учёта торговли
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ Subject: Низкие остатки · {{organizationName}}
|
|||
<title>Низкие остатки</title>
|
||||
</head>
|
||||
<body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 640px; margin: 0 auto; padding: 24px; color: #1f2937;">
|
||||
<div style="padding-bottom: 16px; border-bottom: 1px solid #e5e7eb; margin-bottom: 20px;">
|
||||
<span style="font-size: 22px; font-weight: 600; color: #0DB70D; letter-spacing: -0.5px;">all</span><span style="font-size: 22px; font-weight: 300; color: #4C4F54;"> market</span>
|
||||
</div>
|
||||
<h2 style="color: #b91c1c;">Низкие остатки</h2>
|
||||
<p>{{productCount}} товаров опустились ниже MinStock. Время сделать заказ.</p>
|
||||
|
||||
|
|
@ -15,5 +18,8 @@ Subject: Низкие остатки · {{organizationName}}
|
|||
Полный список — в разделе <a href="{{stockUrl}}">Остатки</a>.
|
||||
Отключить уведомления можно в настройках организации.
|
||||
</p>
|
||||
<p style="margin-top: 28px; padding-top: 16px; border-top: 1px solid #e5e7eb; color: #9ca3af; font-size: 12px;">
|
||||
<strong style="color: #4C4F54;">ALL MARKET</strong> — система учёта торговли
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ Subject: Итоги недели · {{organizationName}}
|
|||
<title>Еженедельная сводка</title>
|
||||
</head>
|
||||
<body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 640px; margin: 0 auto; padding: 24px; color: #1f2937;">
|
||||
<div style="padding-bottom: 16px; border-bottom: 1px solid #e5e7eb; margin-bottom: 20px;">
|
||||
<span style="font-size: 22px; font-weight: 600; color: #0DB70D; letter-spacing: -0.5px;">all</span><span style="font-size: 22px; font-weight: 300; color: #4C4F54;"> market</span>
|
||||
</div>
|
||||
<h2 style="color: #0f766e;">Итоги недели</h2>
|
||||
<p>{{periodFrom}} — {{periodTo}}</p>
|
||||
|
||||
|
|
@ -32,5 +35,8 @@ Subject: Итоги недели · {{organizationName}}
|
|||
<p style="margin-top: 32px; color: #6b7280; font-size: 13px;">
|
||||
Подробная аналитика — в разделе <a href="{{reportsUrl}}">Отчёты</a>.
|
||||
</p>
|
||||
<p style="margin-top: 28px; padding-top: 16px; border-top: 1px solid #e5e7eb; color: #9ca3af; font-size: 12px;">
|
||||
<strong style="color: #4C4F54;">ALL MARKET</strong> — система учёта торговли
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public Task SendAsync(string toEmail, string subject, string body, CancellationT
|
|||
}
|
||||
|
||||
var msg = new MimeMessage();
|
||||
msg.From.Add(new MailboxAddress(s.FromName ?? "Food Market", s.FromEmail));
|
||||
msg.From.Add(new MailboxAddress(s.FromName ?? "ALL MARKET", s.FromEmail));
|
||||
msg.To.Add(MailboxAddress.Parse(toEmail));
|
||||
msg.Subject = subject;
|
||||
if (htmlBody is not null)
|
||||
|
|
|
|||
Loading…
Reference in a new issue