2026-06-04 13:43:07 +03:30
|
|
|
using JobsMedical.Web.Data;
|
2026-06-03 17:41:02 +03:30
|
|
|
using JobsMedical.Web.Models;
|
2026-06-04 13:19:20 +03:30
|
|
|
using JobsMedical.Web.Services;
|
2026-06-03 17:41:02 +03:30
|
|
|
using JobsMedical.Web.Services.Scraping;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
|
|
|
|
|
|
|
|
namespace JobsMedical.Web.Pages.Admin;
|
|
|
|
|
|
|
|
|
|
[Authorize(Roles = "Admin")]
|
|
|
|
|
public class SettingsModel : PageModel
|
|
|
|
|
{
|
|
|
|
|
private readonly SettingsService _settings;
|
2026-06-04 13:19:20 +03:30
|
|
|
private readonly ISmsSender _sms;
|
2026-06-04 13:43:07 +03:30
|
|
|
private readonly AppDbContext _db;
|
|
|
|
|
public SettingsModel(SettingsService settings, ISmsSender sms, AppDbContext db)
|
2026-06-04 13:19:20 +03:30
|
|
|
{
|
|
|
|
|
_settings = settings;
|
|
|
|
|
_sms = sms;
|
2026-06-04 13:43:07 +03:30
|
|
|
_db = db;
|
2026-06-04 13:19:20 +03:30
|
|
|
}
|
2026-06-03 17:41:02 +03:30
|
|
|
|
|
|
|
|
[BindProperty] public IngestionMode Mode { get; set; }
|
|
|
|
|
[BindProperty] public int AutoPublishMinConfidence { get; set; }
|
|
|
|
|
[BindProperty] public bool AiEnabled { get; set; }
|
|
|
|
|
[BindProperty] public string? AiEndpoint { get; set; }
|
|
|
|
|
[BindProperty] public string? AiApiKey { get; set; }
|
|
|
|
|
[BindProperty] public string? AiModel { get; set; }
|
|
|
|
|
[BindProperty] public string AiSystemPrompt { get; set; } = "";
|
|
|
|
|
[BindProperty] public bool AiAutoApprove { get; set; }
|
2026-06-04 00:44:11 +03:30
|
|
|
// Channel scraping sources
|
|
|
|
|
[BindProperty] public bool AutoIngestEnabled { get; set; }
|
|
|
|
|
[BindProperty] public int IngestIntervalMinutes { get; set; } = 30;
|
|
|
|
|
[BindProperty] public bool TelegramEnabled { get; set; }
|
|
|
|
|
[BindProperty] public string? TelegramChannels { get; set; }
|
|
|
|
|
[BindProperty] public bool BaleEnabled { get; set; }
|
|
|
|
|
[BindProperty] public string? BaleBotToken { get; set; }
|
|
|
|
|
[BindProperty] public bool DivarEnabled { get; set; }
|
|
|
|
|
[BindProperty] public string? DivarCity { get; set; }
|
|
|
|
|
[BindProperty] public string? DivarQueries { get; set; }
|
2026-06-04 06:12:10 +03:30
|
|
|
[BindProperty] public bool MedjobsEnabled { get; set; }
|
|
|
|
|
[BindProperty] public int MedjobsMaxAds { get; set; } = 40;
|
2026-06-04 10:27:21 +03:30
|
|
|
[BindProperty] public bool SmsEnabled { get; set; }
|
|
|
|
|
[BindProperty] public string? SmsApiKey { get; set; }
|
|
|
|
|
[BindProperty] public string? SmsTemplate { get; set; }
|
|
|
|
|
[BindProperty] public string? SmsSender { get; set; }
|
2026-06-04 10:47:33 +03:30
|
|
|
[BindProperty] public string? NeshanMapKey { get; set; }
|
2026-06-04 15:56:40 +03:30
|
|
|
[BindProperty] public bool WebNotificationsEnabled { get; set; }
|
2026-06-04 11:23:13 +03:30
|
|
|
[BindProperty] public bool PushEnabled { get; set; }
|
|
|
|
|
[BindProperty] public string? VapidPublicKey { get; set; }
|
|
|
|
|
[BindProperty] public string? VapidPrivateKey { get; set; }
|
|
|
|
|
[BindProperty] public string? VapidSubject { get; set; }
|
2026-06-04 13:19:20 +03:30
|
|
|
[BindProperty] public string? TestPhone { get; set; }
|
2026-06-04 13:43:07 +03:30
|
|
|
[BindProperty] public bool DemoMode { get; set; }
|
|
|
|
|
[BindProperty] public bool WebsitesEnabled { get; set; }
|
|
|
|
|
[BindProperty] public string? WebsiteUrls { get; set; }
|
2026-06-04 17:53:17 +03:30
|
|
|
[BindProperty] public bool IngestProxyEnabled { get; set; }
|
|
|
|
|
[BindProperty] public string? IngestProxyUrl { get; set; }
|
2026-06-03 17:41:02 +03:30
|
|
|
[TempData] public string? Saved { get; set; }
|
2026-06-04 13:19:20 +03:30
|
|
|
[TempData] public string? SmsTest { get; set; }
|
2026-06-04 13:43:07 +03:30
|
|
|
[TempData] public string? DemoMsg { get; set; }
|
2026-06-03 17:41:02 +03:30
|
|
|
|
|
|
|
|
public async Task OnGetAsync()
|
|
|
|
|
{
|
|
|
|
|
var s = await _settings.GetAsync();
|
|
|
|
|
Mode = s.Mode;
|
|
|
|
|
AutoPublishMinConfidence = s.AutoPublishMinConfidence;
|
|
|
|
|
AiEnabled = s.AiEnabled;
|
|
|
|
|
AiEndpoint = s.AiEndpoint;
|
|
|
|
|
AiApiKey = s.AiApiKey;
|
|
|
|
|
AiModel = s.AiModel;
|
|
|
|
|
AiSystemPrompt = s.AiSystemPrompt;
|
|
|
|
|
AiAutoApprove = s.AiAutoApprove;
|
2026-06-04 00:44:11 +03:30
|
|
|
AutoIngestEnabled = s.AutoIngestEnabled;
|
|
|
|
|
IngestIntervalMinutes = s.IngestIntervalMinutes;
|
|
|
|
|
TelegramEnabled = s.TelegramEnabled;
|
|
|
|
|
TelegramChannels = s.TelegramChannels;
|
|
|
|
|
BaleEnabled = s.BaleEnabled;
|
|
|
|
|
BaleBotToken = s.BaleBotToken;
|
|
|
|
|
DivarEnabled = s.DivarEnabled;
|
|
|
|
|
DivarCity = s.DivarCity;
|
|
|
|
|
DivarQueries = s.DivarQueries;
|
2026-06-04 06:12:10 +03:30
|
|
|
MedjobsEnabled = s.MedjobsEnabled;
|
|
|
|
|
MedjobsMaxAds = s.MedjobsMaxAds;
|
2026-06-04 10:27:21 +03:30
|
|
|
SmsEnabled = s.SmsEnabled;
|
|
|
|
|
SmsApiKey = s.SmsApiKey;
|
|
|
|
|
SmsTemplate = s.SmsTemplate;
|
|
|
|
|
SmsSender = s.SmsSender;
|
2026-06-04 10:47:33 +03:30
|
|
|
NeshanMapKey = s.NeshanMapKey;
|
2026-06-04 13:43:07 +03:30
|
|
|
DemoMode = s.DemoMode;
|
|
|
|
|
WebsitesEnabled = s.WebsitesEnabled;
|
|
|
|
|
WebsiteUrls = s.WebsiteUrls;
|
2026-06-04 17:53:17 +03:30
|
|
|
IngestProxyEnabled = s.IngestProxyEnabled;
|
|
|
|
|
IngestProxyUrl = s.IngestProxyUrl;
|
2026-06-04 15:56:40 +03:30
|
|
|
WebNotificationsEnabled = s.WebNotificationsEnabled;
|
2026-06-04 11:23:13 +03:30
|
|
|
PushEnabled = s.PushEnabled;
|
|
|
|
|
VapidPublicKey = s.VapidPublicKey;
|
|
|
|
|
VapidPrivateKey = s.VapidPrivateKey;
|
|
|
|
|
VapidSubject = s.VapidSubject;
|
2026-06-03 17:41:02 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<IActionResult> OnPostAsync()
|
|
|
|
|
{
|
|
|
|
|
await _settings.SaveAsync(new AppSetting
|
|
|
|
|
{
|
|
|
|
|
Mode = Mode,
|
|
|
|
|
AutoPublishMinConfidence = AutoPublishMinConfidence,
|
|
|
|
|
AiEnabled = AiEnabled,
|
|
|
|
|
AiEndpoint = AiEndpoint,
|
|
|
|
|
AiApiKey = AiApiKey,
|
|
|
|
|
AiModel = AiModel,
|
|
|
|
|
AiSystemPrompt = AiSystemPrompt,
|
|
|
|
|
AiAutoApprove = AiAutoApprove,
|
2026-06-04 00:44:11 +03:30
|
|
|
AutoIngestEnabled = AutoIngestEnabled,
|
|
|
|
|
IngestIntervalMinutes = IngestIntervalMinutes,
|
|
|
|
|
TelegramEnabled = TelegramEnabled,
|
|
|
|
|
TelegramChannels = TelegramChannels,
|
|
|
|
|
BaleEnabled = BaleEnabled,
|
|
|
|
|
BaleBotToken = BaleBotToken,
|
|
|
|
|
DivarEnabled = DivarEnabled,
|
|
|
|
|
DivarCity = DivarCity,
|
|
|
|
|
DivarQueries = DivarQueries,
|
2026-06-04 06:12:10 +03:30
|
|
|
MedjobsEnabled = MedjobsEnabled,
|
|
|
|
|
MedjobsMaxAds = MedjobsMaxAds,
|
2026-06-04 10:27:21 +03:30
|
|
|
SmsEnabled = SmsEnabled,
|
|
|
|
|
SmsApiKey = SmsApiKey,
|
|
|
|
|
SmsTemplate = SmsTemplate,
|
|
|
|
|
SmsSender = SmsSender,
|
2026-06-04 10:47:33 +03:30
|
|
|
NeshanMapKey = NeshanMapKey,
|
2026-06-04 13:43:07 +03:30
|
|
|
DemoMode = DemoMode,
|
|
|
|
|
WebsitesEnabled = WebsitesEnabled,
|
|
|
|
|
WebsiteUrls = WebsiteUrls,
|
2026-06-04 17:53:17 +03:30
|
|
|
IngestProxyEnabled = IngestProxyEnabled,
|
|
|
|
|
IngestProxyUrl = IngestProxyUrl,
|
2026-06-04 15:56:40 +03:30
|
|
|
WebNotificationsEnabled = WebNotificationsEnabled,
|
2026-06-04 11:23:13 +03:30
|
|
|
PushEnabled = PushEnabled,
|
|
|
|
|
VapidPublicKey = VapidPublicKey,
|
|
|
|
|
VapidPrivateKey = VapidPrivateKey,
|
|
|
|
|
VapidSubject = VapidSubject,
|
2026-06-03 17:41:02 +03:30
|
|
|
});
|
|
|
|
|
Saved = "تنظیمات ذخیره شد.";
|
|
|
|
|
return RedirectToPage();
|
|
|
|
|
}
|
2026-06-04 13:19:20 +03:30
|
|
|
|
2026-06-04 13:43:07 +03:30
|
|
|
public async Task<IActionResult> OnPostSeedDemoAsync()
|
|
|
|
|
{
|
|
|
|
|
var n = await SeedData.SeedDemoAsync(_db);
|
|
|
|
|
DemoMsg = n > 0 ? $"دادههای نمونه ثبت شد ({n} مرکز + شیفت/استخدام)." : "دادههای نمونه از قبل موجود است.";
|
|
|
|
|
return RedirectToPage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<IActionResult> OnPostClearDemoAsync()
|
|
|
|
|
{
|
|
|
|
|
var n = await SeedData.ClearDemoAsync(_db);
|
|
|
|
|
DemoMsg = $"دادههای نمونه حذف شد ({n} مرکز و آگهیهای وابسته).";
|
|
|
|
|
return RedirectToPage();
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-04 13:19:20 +03:30
|
|
|
public async Task<IActionResult> OnPostTestSmsAsync()
|
|
|
|
|
{
|
|
|
|
|
var s = await _settings.GetAsync();
|
|
|
|
|
var phone = OtpService.Normalize(TestPhone ?? "");
|
|
|
|
|
if (phone.Length < 10) { SmsTest = "شماره معتبر وارد کنید."; return RedirectToPage(); }
|
|
|
|
|
if (!s.SmsEnabled) { SmsTest = "ابتدا SMS را فعال و ذخیره کنید."; return RedirectToPage(); }
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var ok = await _sms.SendOtpAsync(phone, Random.Shared.Next(10000, 100000).ToString(), s);
|
|
|
|
|
SmsTest = ok ? $"پیامک آزمایشی به {phone} ارسال شد." : "ارسال ناموفق بود (پاسخ منفی از سرویس).";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex) { SmsTest = "خطا در ارسال: " + ex.Message; }
|
|
|
|
|
return RedirectToPage();
|
|
|
|
|
}
|
2026-06-03 17:41:02 +03:30
|
|
|
}
|