🧱 Localization infrastructure
This commit is contained in:
parent
ee7dc31b20
commit
891dbfb255
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
|
using NodaTime.Extensions;
|
||||||
|
|
||||||
namespace DysonNetwork.Sphere.Account;
|
namespace DysonNetwork.Sphere.Account;
|
||||||
|
|
||||||
@ -261,6 +262,46 @@ public class AccountController(
|
|||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("me/check-in")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult<CheckInResult>> GetCheckInResult()
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
||||||
|
var userId = currentUser.Id;
|
||||||
|
|
||||||
|
var today = SystemClock.Instance.GetCurrentInstant().InUtc().Date;
|
||||||
|
var localTime = new TimeOnly(0, 0);
|
||||||
|
var startOfDay = today.ToDateOnly().ToDateTime(localTime).ToInstant();
|
||||||
|
var endOfDay = today.PlusDays(1).ToDateOnly().ToDateTime(localTime).ToInstant();
|
||||||
|
|
||||||
|
var result = await db.AccountCheckInResults
|
||||||
|
.Where(x => x.AccountId == userId)
|
||||||
|
.Where(x => x.CreatedAt >= startOfDay && x.CreatedAt < endOfDay)
|
||||||
|
.OrderByDescending(x => x.CreatedAt)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
return result is null ? NotFound() : Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("me/check-in")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult<CheckInResult>> DoCheckIn([FromBody] string? captchaToken)
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
||||||
|
|
||||||
|
var isAvailable = await events.CheckInDailyIsAvailable(currentUser);
|
||||||
|
if (!isAvailable)
|
||||||
|
return BadRequest("Check-in is not available for today.");
|
||||||
|
|
||||||
|
var needsCaptcha = events.CheckInDailyDoAskCaptcha(currentUser);
|
||||||
|
if (needsCaptcha && string.IsNullOrWhiteSpace(captchaToken))
|
||||||
|
return StatusCode(423, "Captcha is required for this check-in.");
|
||||||
|
if (!await auth.ValidateCaptcha(captchaToken!))
|
||||||
|
return BadRequest("Invalid captcha token.");
|
||||||
|
|
||||||
|
return await events.CheckInDaily(currentUser);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("search")]
|
[HttpGet("search")]
|
||||||
public async Task<List<Account>> Search([FromQuery] string query, [FromQuery] int take = 20)
|
public async Task<List<Account>> Search([FromQuery] string query, [FromQuery] int take = 20)
|
||||||
{
|
{
|
||||||
|
@ -1,14 +1,23 @@
|
|||||||
using DysonNetwork.Sphere.Activity;
|
using DysonNetwork.Sphere.Activity;
|
||||||
using DysonNetwork.Sphere.Connection;
|
using DysonNetwork.Sphere.Connection;
|
||||||
|
using DysonNetwork.Sphere.Resources;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
|
|
||||||
namespace DysonNetwork.Sphere.Account;
|
namespace DysonNetwork.Sphere.Account;
|
||||||
|
|
||||||
public class AccountEventService(AppDatabase db, ActivityService act, WebSocketService ws, IMemoryCache cache)
|
public class AccountEventService(
|
||||||
|
AppDatabase db,
|
||||||
|
AccountService acc,
|
||||||
|
ActivityService act,
|
||||||
|
WebSocketService ws,
|
||||||
|
IMemoryCache cache
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
private static readonly Random Random = new();
|
||||||
private const string StatusCacheKey = "account_status_";
|
private const string StatusCacheKey = "account_status_";
|
||||||
|
|
||||||
public async Task<Status> GetStatus(long userId)
|
public async Task<Status> GetStatus(long userId)
|
||||||
@ -76,4 +85,84 @@ public class AccountEventService(AppDatabase db, ActivityService act, WebSocketS
|
|||||||
db.Update(status);
|
db.Update(status);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const int FortuneTipCount = 7; // This will be the max index for each type (positive/negative)
|
||||||
|
private const string CaptchaCacheKey = "checkin_captcha_";
|
||||||
|
private const int CaptchaProbabilityPercent = 20;
|
||||||
|
|
||||||
|
public bool CheckInDailyDoAskCaptcha(Account user)
|
||||||
|
{
|
||||||
|
var cacheKey = $"{CaptchaCacheKey}{user.Id}";
|
||||||
|
if (cache.TryGetValue(cacheKey, out bool? needsCaptcha))
|
||||||
|
return needsCaptcha!.Value;
|
||||||
|
|
||||||
|
var result = Random.Next(100) < CaptchaProbabilityPercent;
|
||||||
|
cache.Set(cacheKey, result, TimeSpan.FromHours(24));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> CheckInDailyIsAvailable(Account user)
|
||||||
|
{
|
||||||
|
var now = SystemClock.Instance.GetCurrentInstant();
|
||||||
|
var lastCheckIn = await db.AccountCheckInResults
|
||||||
|
.Where(x => x.AccountId == user.Id)
|
||||||
|
.OrderByDescending(x => x.CreatedAt)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
if (lastCheckIn == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var lastDate = lastCheckIn.CreatedAt.InUtc().Date;
|
||||||
|
var currentDate = now.InUtc().Date;
|
||||||
|
|
||||||
|
return lastDate < currentDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CheckInResult> CheckInDaily(Account user)
|
||||||
|
{
|
||||||
|
if (await CheckInDailyIsAvailable(user)) throw new InvalidOperationException("Check-in is not available");
|
||||||
|
|
||||||
|
var localizer = acc.GetEventLocalizer(user.Language);
|
||||||
|
|
||||||
|
// Generate 2 positive tips
|
||||||
|
var positiveIndices = Enumerable.Range(1, FortuneTipCount)
|
||||||
|
.OrderBy(_ => Random.Next())
|
||||||
|
.Take(2)
|
||||||
|
.ToList();
|
||||||
|
var tips = positiveIndices.Select(index => new FortuneTip
|
||||||
|
{
|
||||||
|
IsPositive = true, Title = localizer[$"FortuneTipPositiveTitle_{index}"].Value,
|
||||||
|
Content = localizer[$"FortuneTipPositiveContent_{index}"].Value
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
// Generate 2 negative tips
|
||||||
|
var negativeIndices = Enumerable.Range(1, FortuneTipCount)
|
||||||
|
.OrderBy(_ => Random.Next())
|
||||||
|
.Take(2)
|
||||||
|
.ToList();
|
||||||
|
tips.AddRange(negativeIndices.Select(index => new FortuneTip
|
||||||
|
{
|
||||||
|
IsPositive = false, Title = localizer[$"FortuneTipNegativeTitle_{index}"].Value,
|
||||||
|
Content = localizer[$"FortuneTipNegativeContent_{index}"].Value
|
||||||
|
}));
|
||||||
|
|
||||||
|
var result = new CheckInResult
|
||||||
|
{
|
||||||
|
Tips = tips,
|
||||||
|
Level = (CheckInResultLevel)Random.Next(Enum.GetValues<CheckInResultLevel>().Length),
|
||||||
|
AccountId = user.Id
|
||||||
|
};
|
||||||
|
|
||||||
|
db.AccountCheckInResults.Add(result);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
await act.CreateActivity(
|
||||||
|
user,
|
||||||
|
"accounts.check-in",
|
||||||
|
$"account.check-in/{result.Id}",
|
||||||
|
ActivityVisibility.Friends
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,10 +1,13 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using DysonNetwork.Sphere.Localization;
|
||||||
using DysonNetwork.Sphere.Permission;
|
using DysonNetwork.Sphere.Permission;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
namespace DysonNetwork.Sphere.Account;
|
namespace DysonNetwork.Sphere.Account;
|
||||||
|
|
||||||
public class AccountService(AppDatabase db, PermissionService pm, IMemoryCache cache)
|
public class AccountService(AppDatabase db, PermissionService pm, IMemoryCache cache, IStringLocalizerFactory localizerFactory)
|
||||||
{
|
{
|
||||||
public async Task PurgeAccountCache(Account account)
|
public async Task PurgeAccountCache(Account account)
|
||||||
{
|
{
|
||||||
@ -31,4 +34,9 @@ public class AccountService(AppDatabase db, PermissionService pm, IMemoryCache c
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IStringLocalizer GetEventLocalizer(string language)
|
||||||
|
{
|
||||||
|
return localizerFactory.Create(language, nameof(AccountEventResource));
|
||||||
|
}
|
||||||
}
|
}
|
@ -23,4 +23,30 @@ public class Status : ModelBase
|
|||||||
|
|
||||||
public long AccountId { get; set; }
|
public long AccountId { get; set; }
|
||||||
public Account Account { get; set; } = null!;
|
public Account Account { get; set; } = null!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CheckInResultLevel
|
||||||
|
{
|
||||||
|
Worst,
|
||||||
|
Worse,
|
||||||
|
Normal,
|
||||||
|
Better,
|
||||||
|
Best
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CheckInResult : ModelBase
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
public CheckInResultLevel Level { get; set; }
|
||||||
|
[Column(TypeName = "jsonb")] public ICollection<FortuneTip> Tips { get; set; } = new List<FortuneTip>();
|
||||||
|
|
||||||
|
public long AccountId { get; set; }
|
||||||
|
public Account Account { get; set; } = null!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FortuneTip
|
||||||
|
{
|
||||||
|
public bool IsPositive { get; set; }
|
||||||
|
public string Title { get; set; } = null!;
|
||||||
|
public string Content { get; set; } = null!;
|
||||||
}
|
}
|
@ -16,7 +16,6 @@ public class ActivityService(AppDatabase db)
|
|||||||
.Select(e => long.Parse(e.ResourceIdentifier.Split("/").Last()))
|
.Select(e => long.Parse(e.ResourceIdentifier.Split("/").Last()))
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (postsId.Count > 0)
|
if (postsId.Count > 0)
|
||||||
{
|
{
|
||||||
var posts = await db.Posts.Where(e => postsId.Contains(e.Id))
|
var posts = await db.Posts.Where(e => postsId.Contains(e.Id))
|
||||||
@ -32,18 +31,68 @@ public class ActivityService(AppDatabase db)
|
|||||||
|
|
||||||
var postsDict = posts.ToDictionary(p => p.Id);
|
var postsDict = posts.ToDictionary(p => p.Id);
|
||||||
|
|
||||||
for (var idx = 0; idx < input.Count; idx++)
|
foreach (var item in input)
|
||||||
{
|
{
|
||||||
var resourceIdentifier = input[idx].ResourceIdentifier;
|
var resourceIdentifier = item.ResourceIdentifier;
|
||||||
if (!resourceIdentifier.StartsWith("posts/")) continue;
|
if (!resourceIdentifier.StartsWith("posts/")) continue;
|
||||||
var postId = long.Parse(resourceIdentifier.Split("/").Last());
|
var postId = long.Parse(resourceIdentifier.Split("/").Last());
|
||||||
if (postsDict.TryGetValue(postId, out var post) && input[idx].Data is null)
|
if (postsDict.TryGetValue(postId, out var post) && item.Data is null)
|
||||||
{
|
{
|
||||||
input[idx].Data = post;
|
item.Data = post;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var statusesId = input
|
||||||
|
.Where(e => e.ResourceIdentifier.StartsWith("account.statuses/"))
|
||||||
|
.Select(e => Guid.Parse(e.ResourceIdentifier.Split("/").Last()))
|
||||||
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
if (statusesId.Count > 0)
|
||||||
|
{
|
||||||
|
var statuses = await db.AccountStatuses.Where(e => statusesId.Contains(e.Id))
|
||||||
|
.Include(e => e.Account)
|
||||||
|
.Include(e => e.Account.Profile)
|
||||||
|
.ToListAsync();
|
||||||
|
var statusesDict = statuses.ToDictionary(p => p.Id);
|
||||||
|
|
||||||
|
foreach (var item in input)
|
||||||
|
{
|
||||||
|
var resourceIdentifier = item.ResourceIdentifier;
|
||||||
|
if (!resourceIdentifier.StartsWith("account.statuses/")) continue;
|
||||||
|
var statusId = Guid.Parse(resourceIdentifier.Split("/").Last());
|
||||||
|
if (statusesDict.TryGetValue(statusId, out var status) && item.Data is null)
|
||||||
|
{
|
||||||
|
item.Data = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkInId = input
|
||||||
|
.Where(e => e.ResourceIdentifier.StartsWith("account.check-in/"))
|
||||||
|
.Select(e => Guid.Parse(e.ResourceIdentifier.Split("/").Last()))
|
||||||
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
if (checkInId.Count > 0)
|
||||||
|
{
|
||||||
|
var checkIns = await db.AccountCheckInResults.Where(e => checkInId.Contains(e.Id))
|
||||||
|
.Include(e => e.Account)
|
||||||
|
.Include(e => e.Account.Profile)
|
||||||
|
.ToListAsync();
|
||||||
|
var checkInsDict = checkIns.ToDictionary(p => p.Id);
|
||||||
|
|
||||||
|
foreach (var item in input)
|
||||||
|
{
|
||||||
|
var resourceIdentifier = item.ResourceIdentifier;
|
||||||
|
if (!resourceIdentifier.StartsWith("account.check-in/")) continue;
|
||||||
|
var checkInResultId = Guid.Parse(resourceIdentifier.Split("/").Last());
|
||||||
|
if (checkInsDict.TryGetValue(checkInResultId, out var checkIn) && item.Data is null)
|
||||||
|
{
|
||||||
|
item.Data = checkIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ public class AppDatabase(
|
|||||||
public DbSet<Account.AccountAuthFactor> AccountAuthFactors { get; set; }
|
public DbSet<Account.AccountAuthFactor> AccountAuthFactors { get; set; }
|
||||||
public DbSet<Account.Relationship> AccountRelationships { get; set; }
|
public DbSet<Account.Relationship> AccountRelationships { get; set; }
|
||||||
public DbSet<Account.Status> AccountStatuses { get; set; }
|
public DbSet<Account.Status> AccountStatuses { get; set; }
|
||||||
|
public DbSet<Account.CheckInResult> AccountCheckInResults { get; set; }
|
||||||
public DbSet<Account.Notification> Notifications { get; set; }
|
public DbSet<Account.Notification> Notifications { get; set; }
|
||||||
public DbSet<Account.NotificationPushSubscription> NotificationPushSubscriptions { get; set; }
|
public DbSet<Account.NotificationPushSubscription> NotificationPushSubscriptions { get; set; }
|
||||||
|
|
||||||
|
@ -59,4 +59,46 @@
|
|||||||
<Folder Include="Uploads\" />
|
<Folder Include="Uploads\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="Resources\SharedResource.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>SharedResource.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Update="Resources\SharedResource.zh-CN.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>SharedResource-zh-CN.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Update="Resources\AccountEventResource.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>AccountEventResource.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Update="Resources\AccountEventResource.zh-CN.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>AccountEventResource.zh-CN.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="Resources\SharedResource.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>SharedResource.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="Resources\SharedResource.zh-CN.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>SharedResource.zh-CN.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="Resources\AccountEventResource.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>AccountEventResource.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="Resources\AccountEventResource.zh-CN.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>AccountEventResource.zh-CN.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
6
DysonNetwork.Sphere/Localization/AccountEventResource.cs
Normal file
6
DysonNetwork.Sphere/Localization/AccountEventResource.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace DysonNetwork.Sphere.Localization;
|
||||||
|
|
||||||
|
public class AccountEventResource
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
6
DysonNetwork.Sphere/Localization/SharedResource.cs
Normal file
6
DysonNetwork.Sphere/Localization/SharedResource.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace DysonNetwork.Sphere.Localization;
|
||||||
|
|
||||||
|
public class SharedResource
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Globalization;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -10,11 +11,13 @@ using DysonNetwork.Sphere.Auth;
|
|||||||
using DysonNetwork.Sphere.Chat;
|
using DysonNetwork.Sphere.Chat;
|
||||||
using DysonNetwork.Sphere.Connection;
|
using DysonNetwork.Sphere.Connection;
|
||||||
using DysonNetwork.Sphere.Connection.Handlers;
|
using DysonNetwork.Sphere.Connection.Handlers;
|
||||||
|
using DysonNetwork.Sphere.Localization;
|
||||||
using DysonNetwork.Sphere.Permission;
|
using DysonNetwork.Sphere.Permission;
|
||||||
using DysonNetwork.Sphere.Post;
|
using DysonNetwork.Sphere.Post;
|
||||||
using DysonNetwork.Sphere.Realm;
|
using DysonNetwork.Sphere.Realm;
|
||||||
using DysonNetwork.Sphere.Storage;
|
using DysonNetwork.Sphere.Storage;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
using Microsoft.AspNetCore.Localization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.RateLimiting;
|
using Microsoft.AspNetCore.RateLimiting;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -25,7 +28,6 @@ using NodaTime;
|
|||||||
using NodaTime.Serialization.SystemTextJson;
|
using NodaTime.Serialization.SystemTextJson;
|
||||||
using Quartz;
|
using Quartz;
|
||||||
using tusdotnet;
|
using tusdotnet;
|
||||||
using tusdotnet.Interfaces;
|
|
||||||
using tusdotnet.Models;
|
using tusdotnet.Models;
|
||||||
using tusdotnet.Models.Configuration;
|
using tusdotnet.Models.Configuration;
|
||||||
using tusdotnet.Stores;
|
using tusdotnet.Stores;
|
||||||
@ -38,6 +40,8 @@ builder.WebHost.ConfigureKestrel(options => options.Limits.MaxRequestBodySize =
|
|||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
|
|
||||||
|
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
|
||||||
|
|
||||||
builder.Services.AddDbContext<AppDatabase>();
|
builder.Services.AddDbContext<AppDatabase>();
|
||||||
|
|
||||||
builder.Services.AddHttpClient();
|
builder.Services.AddHttpClient();
|
||||||
@ -47,9 +51,24 @@ builder.Services.AddControllers().AddJsonOptions(options =>
|
|||||||
options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower;
|
options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower;
|
||||||
|
|
||||||
options.JsonSerializerOptions.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
options.JsonSerializerOptions.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
||||||
|
}).AddDataAnnotationsLocalization(options => {
|
||||||
|
options.DataAnnotationLocalizerProvider = (type, factory) =>
|
||||||
|
factory.Create(typeof(SharedResource));
|
||||||
});
|
});
|
||||||
builder.Services.AddRazorPages();
|
builder.Services.AddRazorPages();
|
||||||
|
|
||||||
|
builder.Services.Configure<RequestLocalizationOptions>(options => {
|
||||||
|
var supportedCultures = new[]
|
||||||
|
{
|
||||||
|
new CultureInfo("en-US"),
|
||||||
|
new CultureInfo("zh-CN"),
|
||||||
|
};
|
||||||
|
|
||||||
|
options.DefaultRequestCulture = new RequestCulture("en-US");
|
||||||
|
options.SupportedCultures = supportedCultures;
|
||||||
|
options.SupportedUICultures = supportedCultures;
|
||||||
|
});
|
||||||
|
|
||||||
// Other pipelines
|
// Other pipelines
|
||||||
|
|
||||||
builder.Services.AddRateLimiter(o => o.AddFixedWindowLimiter(policyName: "fixed", opts =>
|
builder.Services.AddRateLimiter(o => o.AddFixedWindowLimiter(policyName: "fixed", opts =>
|
||||||
@ -179,6 +198,8 @@ app.MapOpenApi();
|
|||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI();
|
app.UseSwaggerUI();
|
||||||
|
|
||||||
|
app.UseRequestLocalization();
|
||||||
|
|
||||||
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||||
{
|
{
|
||||||
ForwardedHeaders = ForwardedHeaders.All
|
ForwardedHeaders = ForwardedHeaders.All
|
||||||
|
48
DysonNetwork.Sphere/Resources/AccountEventResource.Designer.cs
generated
Normal file
48
DysonNetwork.Sphere/Resources/AccountEventResource.Designer.cs
generated
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Resources {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
public class AccountEventResource {
|
||||||
|
|
||||||
|
private static System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal AccountEventResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.Equals(null, resourceMan)) {
|
||||||
|
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("DysonNetwork.Sphere.Resources.AccountEventResource", typeof(AccountEventResource).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
DysonNetwork.Sphere/Resources/AccountEventResource.resx
Normal file
21
DysonNetwork.Sphere/Resources/AccountEventResource.resx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>1.3</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
204
DysonNetwork.Sphere/Resources/AccountEventResource.zh-CN.Designer.cs
generated
Normal file
204
DysonNetwork.Sphere/Resources/AccountEventResource.zh-CN.Designer.cs
generated
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Resources {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class AccountEventResource_zh_CN {
|
||||||
|
|
||||||
|
private static System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal AccountEventResource_zh_CN() {
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.Equals(null, resourceMan)) {
|
||||||
|
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("DysonNetwork.Sphere.Resources.AccountEventResource_zh_CN", typeof(AccountEventResource_zh_CN).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveTitle_1 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveTitle_1", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveContent_1 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveContent_1", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeTitle_1_ {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeTitle_1 ", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveTitle_2 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveTitle_2", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveContent_2 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveContent_2", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeTitle_2 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeTitle_2", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeContent_2 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeContent_2", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveTitle_3 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveTitle_3", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveContent_3 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveContent_3", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeTitle_3 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeTitle_3", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeContent_3 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeContent_3", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveTitle_4 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveTitle_4", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveContent_4 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveContent_4", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeTitle_4 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeTitle_4", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveTitle_5 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveTitle_5", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveContent_5 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveContent_5", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeTitle_5 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeTitle_5", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeContent_5 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeContent_5", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveTitle_6 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveTitle_6", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveContent_6 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveContent_6", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeTitle_6 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeTitle_6", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeContent_6 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeContent_6", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveTitle_7 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveTitle_7", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipPositiveContent_7 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipPositiveContent_7", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeTitle_7 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeTitle_7", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string FortuneTipNegativeContent_7 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FortuneTipNegativeContent_7", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>1.3</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="FortuneTipPositiveTitle_1" xml:space="preserve">
|
||||||
|
<value>抽卡</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveContent_1" xml:space="preserve">
|
||||||
|
<value>次次出金</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeTitle_1 " xml:space="preserve">
|
||||||
|
<value>抽卡</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveTitle_2" xml:space="preserve">
|
||||||
|
<value>游戏</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveContent_2" xml:space="preserve">
|
||||||
|
<value>升段如破竹</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeTitle_2" xml:space="preserve">
|
||||||
|
<value>游戏</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeContent_2" xml:space="preserve">
|
||||||
|
<value>掉分如山崩</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveTitle_3" xml:space="preserve">
|
||||||
|
<value>抽奖</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveContent_3" xml:space="preserve">
|
||||||
|
<value>欧气加身</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeTitle_3" xml:space="preserve">
|
||||||
|
<value>抽奖</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeContent_3" xml:space="preserve">
|
||||||
|
<value>十连皆寂</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveTitle_4" xml:space="preserve">
|
||||||
|
<value>演讲</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveContent_4" xml:space="preserve">
|
||||||
|
<value>妙语连珠</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeTitle_4" xml:space="preserve">
|
||||||
|
<value>演讲</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveTitle_5" xml:space="preserve">
|
||||||
|
<value>绘图</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveContent_5" xml:space="preserve">
|
||||||
|
<value>灵感如泉涌</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeTitle_5" xml:space="preserve">
|
||||||
|
<value>绘图</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeContent_5" xml:space="preserve">
|
||||||
|
<value>下笔如千斤</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveTitle_6" xml:space="preserve">
|
||||||
|
<value>编程</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveContent_6" xml:space="preserve">
|
||||||
|
<value>0 error(s), 0 warning(s)</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeTitle_6" xml:space="preserve">
|
||||||
|
<value>编程</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeContent_6" xml:space="preserve">
|
||||||
|
<value>114 error(s), 514 warning(s)</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveTitle_7" xml:space="preserve">
|
||||||
|
<value>购物</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipPositiveContent_7" xml:space="preserve">
|
||||||
|
<value>汇率低谷</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeTitle_7" xml:space="preserve">
|
||||||
|
<value>开箱</value>
|
||||||
|
</data>
|
||||||
|
<data name="FortuneTipNegativeContent_7" xml:space="preserve">
|
||||||
|
<value>225% 关税</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
48
DysonNetwork.Sphere/Resources/SharedResource.Designer.cs
generated
Normal file
48
DysonNetwork.Sphere/Resources/SharedResource.Designer.cs
generated
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Resources {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class SharedResource {
|
||||||
|
|
||||||
|
private static System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal SharedResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.Equals(null, resourceMan)) {
|
||||||
|
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("DysonNetwork.Sphere.Resources.SharedResource", typeof(SharedResource).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
DysonNetwork.Sphere/Resources/SharedResource.resx
Normal file
21
DysonNetwork.Sphere/Resources/SharedResource.resx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>1.3</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
48
DysonNetwork.Sphere/Resources/SharedResource.zh-CN.Designer.cs
generated
Normal file
48
DysonNetwork.Sphere/Resources/SharedResource.zh-CN.Designer.cs
generated
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Resources {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class SharedResource_zh_CN {
|
||||||
|
|
||||||
|
private static System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal SharedResource_zh_CN() {
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.Equals(null, resourceMan)) {
|
||||||
|
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("DysonNetwork.Sphere.Resources.SharedResource_zh_CN", typeof(SharedResource_zh_CN).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
DysonNetwork.Sphere/Resources/SharedResource.zh-CN.resx
Normal file
21
DysonNetwork.Sphere/Resources/SharedResource.zh-CN.resx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>1.3</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
@ -32,6 +32,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIntentType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fbf_003Ffcb84131_003FIntentType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIntentType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fbf_003Ffcb84131_003FIntentType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInternalServerError_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F01d30b32e2ff422cb80129ca2a441c4242600_003Fb5_003Fc55acdd2_003FInternalServerError_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInternalServerError_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F01d30b32e2ff422cb80129ca2a441c4242600_003Fb5_003Fc55acdd2_003FInternalServerError_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIServiceCollectionQuartzConfigurator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1edbd6e24d7b430fabce72177269baa19200_003F67_003Faee36f5b_003FIServiceCollectionQuartzConfigurator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIServiceCollectionQuartzConfigurator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1edbd6e24d7b430fabce72177269baa19200_003F67_003Faee36f5b_003FIServiceCollectionQuartzConfigurator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIStringLocalizerFactory_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6aa8ac544afb487082402c1fa422910f2e00_003F7f_003F8e728ed6_003FIStringLocalizerFactory_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AITusStore_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fb1_003F7e861de5_003FITusStore_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AITusStore_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fb1_003F7e861de5_003FITusStore_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJsonSerializerOptions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5703920a18f94462b4354fab05326e6519a200_003F35_003F8536fc49_003FJsonSerializerOptions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJsonSerializerOptions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5703920a18f94462b4354fab05326e6519a200_003F35_003F8536fc49_003FJsonSerializerOptions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKestrelServerLimits_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1e2e5dfcafad4407b569dd5df56a2fbf274e00_003Fa4_003F39445f62_003FKestrelServerLimits_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKestrelServerLimits_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1e2e5dfcafad4407b569dd5df56a2fbf274e00_003Fa4_003F39445f62_003FKestrelServerLimits_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
@ -60,4 +61,10 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATusDiskStore_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fe1_003Fefd9af34_003FTusDiskStore_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATusDiskStore_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fe1_003Fefd9af34_003FTusDiskStore_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATusDiskStore_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003F1c_003F21999acd_003FTusDiskStore_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATusDiskStore_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003F1c_003F21999acd_003FTusDiskStore_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUri_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5d2c480da9be415dab9be535bb6d08713cc00_003Fd0_003Fffc36a51_003FUri_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUri_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5d2c480da9be415dab9be535bb6d08713cc00_003Fd0_003Fffc36a51_003FUri_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AValidationContext_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003F6b_003F741ceebe_003FValidationContext_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AValidationContext_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003F6b_003F741ceebe_003FValidationContext_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=DysonNetwork_002ESphere_002FResources_002FAccountEventResource/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=DysonNetwork_002ESphere_002FResources_002FAccountEventResource_002Ezh_002DCN/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=DysonNetwork_002ESphere_002FResources_002FSharedResource/@EntryIndexedValue">False</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=DysonNetwork_002ESphere_002FResources_002FSharedResource_002Ezh_002DCN/@EntryIndexedValue">False</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/ResxEditorPersonal/Initialized/@EntryValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/ResxEditorPersonal/ShowOnlyErrors/@EntryValue">False</s:Boolean></wpf:ResourceDictionary>
|
Loading…
x
Reference in New Issue
Block a user