Skip to content

Commit 663042b

Browse files
committed
Add multilingual profile support with unique index on AccountName and Language
1 parent b8484f2 commit 663042b

File tree

6 files changed

+15
-15
lines changed

6 files changed

+15
-15
lines changed

OpenBioCardServer/Constants/CacheKeys.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ public static string GetProfileCacheKey(string username)
99
return $"Profile:{username.Trim().ToLowerInvariant()}";
1010
}
1111

12-
public static string GetClassicProfileCacheKey(string username)
12+
public static string GetClassicProfileCacheKey(string accountName, string? language = null)
1313
{
14-
return $"Classic:Profile:{username.Trim().ToLowerInvariant()}";
14+
// 如果 Language 为 NULL 或空,使用 "@Default" 作为后缀
15+
var langKey = string.IsNullOrWhiteSpace(language) ? "@Default" : language.Trim().ToLowerInvariant();
16+
return $"Classic:Profile:{accountName.Trim().ToLowerInvariant()}:{langKey}";
1517
}
1618

1719
}

OpenBioCardServer/Controllers/Classic/ClassicAdminController.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ public async Task<IActionResult> CreateUser([FromBody] ClassicCreateUserRequest
198198
{
199199
AccountId = newAccount.Id,
200200
AccountName = request.NewUsername,
201+
Language = null,
201202
AvatarType = AssetType.Text,
202203
AvatarText = "👤"
203204
};

OpenBioCardServer/Data/AppDbContext.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
3434
// Account configuration
3535
modelBuilder.Entity<Account>(entity =>
3636
{
37-
// Unique index on Username for fast lookup
3837
entity.HasIndex(e => e.AccountName).IsUnique();
3938

40-
// One-to-One with Profile
41-
entity.HasOne(e => e.Profile)
39+
entity.HasMany(e => e.Profiles)
4240
.WithOne(e => e.Account)
43-
.HasForeignKey<ProfileEntity>(e => e.AccountId)
41+
.HasForeignKey(e => e.AccountId)
4442
.OnDelete(DeleteBehavior.Cascade);
4543

46-
// One-to-Many with Tokens
4744
entity.HasMany(e => e.Tokens)
4845
.WithOne(e => e.Account)
4946
.HasForeignKey(e => e.AccountId)
@@ -64,7 +61,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
6461
modelBuilder.Entity<ProfileEntity>(entity =>
6562
{
6663
// Unique index on Username (redundant with Account but useful)
67-
entity.HasIndex(e => e.AccountName).IsUnique();
64+
entity.HasIndex(e => new { e.AccountName, e.Language }).IsUnique();
6865

6966
// One-to-Many relationships with all child entities
7067
entity.HasMany(e => e.Contacts)

OpenBioCardServer/Models/Entities/Account.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ public class Account
2828
public DateTime LastLogin { get; set; } = DateTime.UtcNow;
2929

3030
// Navigation properties
31-
public ProfileEntity? Profile { get; set; }
31+
public ICollection<ProfileEntity> Profiles { get; set; } = new List<ProfileEntity>();
3232
public ICollection<Token> Tokens { get; set; } = new List<Token>();
3333
}

OpenBioCardServer/Services/ClassicProfileService.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public ClassicProfileService(
4444
.Include(p => p.WorkExperiences)
4545
.Include(p => p.SchoolExperiences)
4646
.Include(p => p.Gallery)
47-
.FirstOrDefaultAsync(p => p.AccountName == username, token);
47+
.FirstOrDefaultAsync(p => p.AccountName == username && p.Language == null, token);
4848
return profile == null ? null : ClassicMapper.ToClassicProfile(profile);
4949
});
5050
}
@@ -102,7 +102,7 @@ public async Task<bool> UpdateProfileAsync(string username, ClassicProfile reque
102102
{
103103
var profile = await _context.Profiles
104104
.AsTracking()
105-
.FirstOrDefaultAsync(p => p.AccountName == username);
105+
.FirstOrDefaultAsync(p => p.AccountName == username && p.Language == null);
106106

107107
if (profile == null)
108108
{
@@ -187,7 +187,7 @@ public async Task<bool> PatchProfileAsync(string username, ClassicProfilePatch p
187187
{
188188
var profile = await _context.Profiles
189189
.AsTracking()
190-
.FirstOrDefaultAsync(p => p.AccountName == username);
190+
.FirstOrDefaultAsync(p => p.AccountName == username && p.Language == null);
191191

192192
if (profile == null)
193193
{

OpenBioCardServer/Services/ProfileService.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public ProfileService(
4444
.Include(p => p.WorkExperiences)
4545
.Include(p => p.SchoolExperiences)
4646
.Include(p => p.Gallery)
47-
.FirstOrDefaultAsync(p => p.AccountName == username, token);
47+
.FirstOrDefaultAsync(p => p.AccountName == username && p.Language == null, token);
4848

4949
return profile == null ? null : DataMapper.ToProfileDto(profile);
5050
});
@@ -64,7 +64,7 @@ public ProfileService(
6464
.Include(p => p.WorkExperiences)
6565
.Include(p => p.SchoolExperiences)
6666
.Include(p => p.Gallery)
67-
.FirstOrDefaultAsync(p => p.AccountId == accountId);
67+
.FirstOrDefaultAsync(p => p.AccountId == accountId && p.Language == null);
6868

6969
return profile == null ? null : DataMapper.ToProfileDto(profile);
7070
}
@@ -79,7 +79,7 @@ public async Task<bool> UpdateProfileAsync(string username, ProfileDto request)
7979
try
8080
{
8181
var profile = await _context.Profiles
82-
.FirstOrDefaultAsync(p => p.AccountName == username);
82+
.FirstOrDefaultAsync(p => p.AccountName == username && p.Language == null);
8383

8484
if (profile == null)
8585
{

0 commit comments

Comments
 (0)