Skip to content

Commit e8b8540

Browse files
committed
✨ 优化图像加载逻辑
1 parent 345bfb8 commit e8b8540

27 files changed

+332
-390
lines changed

.gitignore

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ src/North/.vs
1212
src/North/bin
1313
src/North/obj
1414
src/North/.config
15-
# src/North/appsettings.json
15+
src/North/appsettings.json
1616
# North End
1717

1818
# North.Core Start
@@ -32,7 +32,6 @@ src/North.Nsfw/.vs
3232
src/North.Nsfw/bin
3333
src/North.Nsfw/obj
3434
src/North.Nsfw/Properties
35-
src/North.Nsfw/appsettings.json
3635
# North.Nsfw End
3736

3837
# North.RCL Start
@@ -59,4 +58,11 @@ src/North.PluginTest/*
5958
src/North.Plugin.NetVips/.vs
6059
src/North.Plugin.NetVips/bin
6160
src/North.Plugin.NetVips/obj
62-
# North.Plugin.NetVips End
61+
# North.Plugin.NetVips End
62+
/src/North/appsettings.json
63+
/src/North/Properties/PublishProfiles/linux-arm64.pubxml
64+
/src/North/Properties/PublishProfiles/linux-arm64.pubxml.user
65+
/src/North/Properties/PublishProfiles/win-x64-v2.4.15.pubxml
66+
/src/North/Properties/PublishProfiles/win-x64-v2.4.15.pubxml.user
67+
/src/North/Properties/PublishProfiles/win-x64.pubxml
68+
/src/North/Properties/PublishProfiles/win-x64.pubxml.user

src/North.Core/Common/AppSetting.cs

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,23 @@
11
using Microsoft.Data.SqlClient;
2-
using North.Core.Entities;
32
using North.Core.Services.Logger;
43
using SqlSugar;
4+
using System.Reflection;
55
using System.Text.Json;
66
using System.Text.Json.Serialization;
77

88
namespace North.Core.Common
99
{
1010
public class AppSetting
1111
{
12+
public WelcomeSetting Welcome { get; set; }
1213
public GeneralSetting General { get; set; }
13-
public AppearanceSetting Appearance { get; set; }
14+
public AppearanceSetting Appearance { get; set; }
1415
public RegisterSetting Register { get; set; }
1516
public NotifySetting Notify { get; set; }
1617
public AuthSetting Auth { get; set; }
1718
public LogSetting Log { get; set; }
1819
public PluginSetting Plugin { get; set; }
1920

20-
public AppSetting(GeneralSetting general, AppearanceSetting appearance, RegisterSetting register, NotifySetting notify, AuthSetting auth, LogSetting log, PluginSetting plugin)
21-
{
22-
General = general;
23-
Appearance = appearance;
24-
Register = register;
25-
Notify = notify;
26-
Auth = auth;
27-
Log = log;
28-
Plugin = plugin;
29-
}
30-
3121

3222
/// <summary>
3323
/// 加载设置
@@ -36,21 +26,56 @@ public AppSetting(GeneralSetting general, AppearanceSetting appearance, Register
3626
/// <returns></returns>
3727
public static AppSetting Load(string path = "appsettings.json") => JsonSerializer.Deserialize<AppSetting>(File.ReadAllText(path)) ?? throw new Exception($"Load {path} failed");
3828

39-
4029
/// <summary>
4130
/// 保存设置
4231
/// </summary>
4332
/// <param name="path"></param>
4433
public void Save(string path = "appsettings.json") => File.WriteAllText(path, ToString());
4534

46-
public AppSetting Clone() => new(General.Clone(), Appearance.Clone(), Register.Clone(), Notify.Clone(), Auth.Clone(), Log.Clone(), Plugin.Clone());
35+
/// <summary>
36+
/// 深拷贝设置对象
37+
/// </summary>
38+
/// <returns></returns>
39+
public AppSetting Clone() => new()
40+
{
41+
General = General.Clone(),
42+
Appearance = Appearance.Clone(),
43+
Register = Register.Clone(),
44+
Notify = Notify.Clone(),
45+
Auth = Auth.Clone(),
46+
Log = Log.Clone(),
47+
Plugin = Plugin.Clone()
48+
};
4749

50+
/// <summary>
51+
/// 序列化对象
52+
/// </summary>
53+
/// <returns></returns>
4854
public override string ToString() => JsonSerializer.Serialize(this, new JsonSerializerOptions()
4955
{
5056
WriteIndented = true
5157
});
5258
}
5359

60+
#region 欢迎设置
61+
public class WelcomeSetting
62+
{
63+
/// <summary>
64+
/// 应用版本
65+
/// </summary>
66+
private string? _version = null;
67+
68+
[JsonIgnore]
69+
public string Version
70+
{
71+
get
72+
{
73+
return _version ??= Assembly.GetEntryAssembly()?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "*";
74+
}
75+
}
76+
}
77+
#endregion
78+
5479
#region 通用设置
5580

5681
/// <summary>
@@ -77,7 +102,6 @@ public GeneralSetting(DataBaseSetting dataBase, string applicationUrl)
77102
public GeneralSetting Clone() => new(DataBase.Clone(), ApplicationUrl);
78103
}
79104

80-
81105
/// <summary>
82106
/// 数据库设置
83107
/// </summary>

src/North.Core/Entities/UserEntity.cs

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ public class UserEntity : Entity
148148
public double UploadRemainedCapacityByte => UploadRemainedCapacity * 1024 * 1024;
149149
#endregion
150150

151+
#region 图片存储策略(重命名、冲突)
152+
/// <summary>
153+
/// 图片重命名策略
154+
/// </summary>
155+
public ImageRenamePolicy ImageRenamePolicy { get; set; }
156+
157+
/// <summary>
158+
/// 图片重命名冲突策略
159+
/// </summary>
160+
public ImageRenameConflictPolicy ImageRenameConflictPolicy { get; set;}
161+
#endregion
162+
151163
#region 导航属性
152164
/// <summary>
153165
/// 用户图片
@@ -179,20 +191,22 @@ public class UserEntity : Entity
179191
MaxUploadNums = MaxUploadNums,
180192
MaxUploadCapacity = MaxUploadSize,
181193
SingleMaxUploadNums = SingleMaxUploadNums,
182-
SingleMaxUploadSize = SingleMaxUploadSize
194+
SingleMaxUploadSize = SingleMaxUploadSize,
195+
ImageRenamePolicy = ImageRenamePolicy,
196+
ImageRenameConflictPolicy = ImageRenameConflictPolicy
183197
};
184198

185199

186200
/// <summary>
187201
/// 用户 Claims 认证对象
188202
/// </summary>
189203
[SugarColumn(IsIgnore = true)]
190-
public ClaimsIdentity ClaimsIdentify => new(new Claim[]
191-
{
192-
new Claim(ClaimTypes.Role, Role),
193-
new Claim(ClaimTypes.SerialNumber, Id.ToString()),
194-
new Claim("LastModifyTime", LastModifyTime.ToString("G"))
195-
}, CookieAuthenticationDefaults.AuthenticationScheme);
204+
public ClaimsIdentity ClaimsIdentify => new(
205+
[
206+
new(ClaimTypes.Role, Role),
207+
new(ClaimTypes.SerialNumber, Id.ToString()),
208+
new("LastModifyTime", LastModifyTime.ToString("G"))
209+
], CookieAuthenticationDefaults.AuthenticationScheme);
196210

197211

198212
/// <summary>
@@ -321,6 +335,18 @@ public class UserDTOEntity : Entity
321335
/// </summary>
322336
public double UploadRemainedCapacityByte => UploadRemainedCapacity * 1024 * 1024;
323337
#endregion
338+
339+
#region 图片存储策略(重命名、冲突)
340+
/// <summary>
341+
/// 图片重命名策略
342+
/// </summary>
343+
public ImageRenamePolicy ImageRenamePolicy { get; init; }
344+
345+
/// <summary>
346+
/// 图片重命名冲突策略
347+
/// </summary>
348+
public ImageRenameConflictPolicy ImageRenameConflictPolicy { get; init;}
349+
#endregion
324350
}
325351

326352

@@ -343,4 +369,27 @@ public enum UserState
343369
Normal, // 正常
344370
Forbidden // 封禁中
345371
}
346-
}
372+
373+
374+
/// <summary>
375+
/// 图片存储策略
376+
/// </summary>
377+
public enum ImageRenamePolicy
378+
{
379+
Origin = 0, // 保持源名城
380+
Timestamp, // 时间戳重命名
381+
RandomString // 随机字符串重命名
382+
}
383+
384+
385+
/// <summary>
386+
/// 图片存储冲突策略
387+
/// </summary>
388+
public enum ImageRenameConflictPolicy
389+
{
390+
Override = 0, // 覆写原图片
391+
Abort, // 放弃保存当前图片
392+
RandomPrefix, // 随机字符串前缀
393+
RandomSuffix // 随机字符串后缀
394+
}
395+
}

src/North.Core/Helpers/AuthorizationHelper.cs

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Microsoft.AspNetCore.Http;
2+
3+
namespace North.Core.Services.AuthService
4+
{
5+
public interface IAuthService<UserDto> where UserDto : class
6+
{
7+
ValueTask<bool> AuthAsync(HttpContext context, string? relativeUri = null);
8+
9+
ValueTask<UserDto?> AuthAndQueryAsync(HttpContext context);
10+
}
11+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using Microsoft.AspNetCore.Components;
2+
using Microsoft.AspNetCore.Http;
3+
using North.Core.Entities;
4+
using North.Core.Helpers;
5+
using North.Core.Repository;
6+
using System.Security.Claims;
7+
8+
namespace North.Core.Services.AuthService
9+
{
10+
public class NorthAuthService : IAuthService<UserDTOEntity>
11+
{
12+
private readonly UserRepository _repository;
13+
private readonly string[] _withoutAuthenticationPages;
14+
15+
public NorthAuthService(UserRepository repository, string[] withoutAuthenticationPages)
16+
{
17+
_repository = repository;
18+
_withoutAuthenticationPages = withoutAuthenticationPages;
19+
}
20+
21+
/// <summary>
22+
/// 查询认证用户信息
23+
/// </summary>
24+
/// <param name="context"></param>
25+
/// <param name="queryUserDelegate"></param>
26+
/// <returns>认证信息过期或用户不存在返回 null</returns>
27+
private async ValueTask<UserDTOEntity?> GetAuthUserAsync(HttpContext context)
28+
{
29+
if (context.User.Identity?.IsAuthenticated is not true)
30+
{
31+
return null;
32+
}
33+
34+
// 解析 ClaimIdentifies 中的用户信息
35+
var userId = context.User.FindFirst(ClaimTypes.SerialNumber)?.Value;
36+
var userLastModifyTime = context.User.FindFirst("LastModifyTime")?.Value;
37+
if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(userLastModifyTime))
38+
{
39+
return null;
40+
}
41+
42+
// 核对云端认证信息
43+
var user = await _repository.SingleAsync(u => u.Id.ToString() == userId);
44+
if ((user?.LastModifyTime.ToString("G") != userLastModifyTime) || (user.State is not UserState.Normal))
45+
{
46+
return null;
47+
}
48+
49+
return user.DTO;
50+
}
51+
52+
/// <summary>
53+
/// 认证用户
54+
/// </summary>
55+
/// <param name="context"></param>
56+
/// <param name="relativeUri">当前相对路径</param>
57+
/// <returns></returns>
58+
public async ValueTask<bool> AuthAsync(HttpContext context, string? relativeUri = null)
59+
{
60+
// 获取当前地址并判断是否需要校验
61+
if (relativeUri?.Contains(_withoutAuthenticationPages, true) is true)
62+
{
63+
return true;
64+
}
65+
66+
// 查询用户
67+
var user = await GetAuthUserAsync(context);
68+
return user is not null;
69+
}
70+
71+
/// <summary>
72+
/// 认证用户(默认当前页面需要授权)
73+
/// </summary>
74+
/// <param name="context"></param>
75+
/// <param name="redirectUri"></param>
76+
/// <returns></returns>
77+
public async ValueTask<UserDTOEntity?> AuthAndQueryAsync(HttpContext context)
78+
{
79+
// 查询用户
80+
return await GetAuthUserAsync(context);
81+
}
82+
}
83+
}

src/North.NSFW/appsettings.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*"
9+
}

src/North/App.razor

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
@using North.Common
22
@using North.Core.Common;
3+
@using North.Core.Entities
4+
@using North.Core.Services.AuthService
35
@using North.RCL.Texts
46
@using SqlSugar;
57

@@ -8,10 +10,11 @@
810
@inject ISqlSugarClient _client
911
@inject PluginsContext _pluginContext
1012
@inject IHttpContextAccessor _accessor
13+
@inject IAuthService<UserDTOEntity> _authService
1114

1215
<PageTitle>@_appSetting.Appearance.Name</PageTitle>
1316
<CascadingAuthenticationState>
14-
<Router AppAssembly="@typeof(App).Assembly"
17+
<Router AppAssembly="@typeof(App).Assembly" OnNavigateAsync="AuthAsync"
1518
AdditionalAssemblies="@_pluginContext.RazorPageAssembies">
1619
<Found Context="routeData">
1720
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />

0 commit comments

Comments
 (0)