Skip to content

Commit 5af6afc

Browse files
committed
Updated the API to be compatible with the latest upstream project's front-end code
1 parent bb27122 commit 5af6afc

File tree

7 files changed

+262
-1
lines changed

7 files changed

+262
-1
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using OpenBioCardServer.Data;
3+
using OpenBioCardServer.Models.DTOs.Classic;
4+
using OpenBioCardServer.Models.Entities;
5+
using OpenBioCardServer.Models.Enums;
6+
using OpenBioCardServer.Services;
7+
using OpenBioCardServer.Utilities.Mappers;
8+
9+
namespace OpenBioCardServer.Controllers.Classic;
10+
11+
[Route("classic")]
12+
[ApiController]
13+
public class ClassicSettingsController : ControllerBase
14+
{
15+
private readonly AppDbContext _context;
16+
private readonly ClassicAuthService _authService;
17+
private readonly ILogger<ClassicSettingsController> _logger;
18+
19+
public ClassicSettingsController(
20+
AppDbContext context,
21+
ClassicAuthService authService,
22+
ILogger<ClassicSettingsController> logger)
23+
{
24+
_context = context;
25+
_authService = authService;
26+
_logger = logger;
27+
}
28+
29+
/// <summary>
30+
/// Get public system settings (no authentication required)
31+
/// GET /settings
32+
/// </summary>
33+
[HttpGet("settings")]
34+
public async Task<IActionResult> GetPublicSettings()
35+
{
36+
try
37+
{
38+
var settings = await _context.SystemSettings.FindAsync(1);
39+
40+
var response = new
41+
{
42+
title = settings?.Title ?? "OpenBioCard",
43+
logo = settings?.LogoType.HasValue == true
44+
? AssetToString(settings.LogoType.Value, settings.LogoText, settings.LogoData)
45+
: string.Empty
46+
};
47+
48+
return Ok(response);
49+
}
50+
catch (Exception ex)
51+
{
52+
_logger.LogError(ex, "Error retrieving public settings");
53+
return StatusCode(500, new { error = "Failed to get settings" });
54+
}
55+
}
56+
57+
/// <summary>
58+
/// Get admin system settings (admin only)
59+
/// POST /admin/settings
60+
/// </summary>
61+
[HttpPost("admin/settings")]
62+
public async Task<IActionResult> GetAdminSettings([FromBody] ClassicAdminRequest request)
63+
{
64+
try
65+
{
66+
var (isValid, account) = await _authService.ValidateTokenAsync(request.Token);
67+
68+
if (!isValid || account == null)
69+
{
70+
return Unauthorized(new { error = "Invalid token" });
71+
}
72+
73+
if (account.UserName != request.Username)
74+
{
75+
return Unauthorized(new { error = "Token does not match username" });
76+
}
77+
78+
if (!await _authService.HasAdminPermissionAsync(account))
79+
{
80+
return StatusCode(403, new { error = "Insufficient permissions" });
81+
}
82+
83+
var settings = await _context.SystemSettings.FindAsync(1);
84+
85+
var response = new
86+
{
87+
title = settings?.Title ?? "OpenBioCard",
88+
logo = settings?.LogoType.HasValue == true
89+
? AssetToString(settings.LogoType.Value, settings.LogoText, settings.LogoData)
90+
: string.Empty
91+
};
92+
93+
return Ok(response);
94+
}
95+
catch (Exception ex)
96+
{
97+
_logger.LogError(ex, "Error retrieving admin settings");
98+
return StatusCode(500, new { error = "Failed to get settings" });
99+
}
100+
}
101+
102+
/// <summary>
103+
/// Update system settings (admin only)
104+
/// POST /admin/settings/update
105+
/// </summary>
106+
[HttpPost("admin/settings/update")]
107+
public async Task<IActionResult> UpdateSettings([FromBody] ClassicUpdateSettingsRequest request)
108+
{
109+
try
110+
{
111+
var (isValid, account) = await _authService.ValidateTokenAsync(request.Token);
112+
113+
if (!isValid || account == null)
114+
{
115+
return Unauthorized(new { error = "Invalid token" });
116+
}
117+
118+
if (account.UserName != request.Username)
119+
{
120+
return Unauthorized(new { error = "Token does not match username" });
121+
}
122+
123+
if (!await _authService.HasAdminPermissionAsync(account))
124+
{
125+
return StatusCode(403, new { error = "Insufficient permissions" });
126+
}
127+
128+
if (string.IsNullOrWhiteSpace(request.Title))
129+
{
130+
return BadRequest(new { error = "Title is required" });
131+
}
132+
133+
var settings = await _context.SystemSettings.FindAsync(1);
134+
135+
if (settings == null)
136+
{
137+
settings = new SystemSettingsEntity
138+
{
139+
Id = 1,
140+
Title = request.Title
141+
};
142+
_context.SystemSettings.Add(settings);
143+
}
144+
else
145+
{
146+
settings.Title = request.Title;
147+
}
148+
149+
// Parse and update logo
150+
if (!string.IsNullOrEmpty(request.Logo))
151+
{
152+
var (logoType, logoText, logoData) = ClassicMapper.ParseAsset(request.Logo);
153+
settings.LogoType = logoType;
154+
settings.LogoText = logoText;
155+
settings.LogoData = logoData;
156+
}
157+
else
158+
{
159+
settings.LogoType = null;
160+
settings.LogoText = null;
161+
settings.LogoData = null;
162+
}
163+
164+
await _context.SaveChangesAsync();
165+
166+
_logger.LogInformation("Admin {Username} updated system settings", request.Username);
167+
168+
return Ok(new { success = true });
169+
}
170+
catch (Exception ex)
171+
{
172+
_logger.LogError(ex, "Error updating settings");
173+
return StatusCode(500, new { error = "Failed to update settings" });
174+
}
175+
}
176+
177+
private static string AssetToString(AssetType type, string? text, byte[]? data) => type switch
178+
{
179+
AssetType.Text => text ?? string.Empty,
180+
AssetType.Remote => text ?? string.Empty,
181+
AssetType.Image => data != null ? $"data:image/png;base64,{Convert.ToBase64String(data)}" : string.Empty,
182+
_ => string.Empty
183+
};
184+
}

OpenBioCardServer/Data/AppDbContext.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public AppDbContext(DbContextOptions<AppDbContext> options, IConfiguration confi
2323
public DbSet<WorkExperienceItemEntity> WorkExperienceItems => Set<WorkExperienceItemEntity>();
2424
public DbSet<SchoolExperienceItemEntity> SchoolExperienceItems => Set<SchoolExperienceItemEntity>();
2525
public DbSet<GalleryItemEntity> GalleryItems => Set<GalleryItemEntity>();
26+
27+
// DbSets (System Settings)
28+
public DbSet<SystemSettingsEntity> SystemSettings => Set<SystemSettingsEntity>();
2629

2730
protected override void OnModelCreating(ModelBuilder modelBuilder)
2831
{
@@ -108,6 +111,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
108111
entity.Property(e => e.AttributesJson)
109112
.HasColumnType(columnType);
110113
});
114+
115+
// System Settings configuration
116+
modelBuilder.Entity<SystemSettingsEntity>(entity =>
117+
{
118+
// Ensure only one record can exist with Id = 1
119+
entity.HasIndex(e => e.Id).IsUnique();
120+
});
111121
}
112122

113123
public string GetDatabaseType() => _databaseType;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Newtonsoft.Json;
2+
3+
namespace OpenBioCardServer.Models.DTOs.Classic;
4+
5+
public class ClassicUpdateSettingsRequest
6+
{
7+
[JsonProperty("username")]
8+
public string Username { get; set; } = string.Empty;
9+
10+
[JsonProperty("token")]
11+
public string Token { get; set; } = string.Empty;
12+
13+
[JsonProperty("title")]
14+
public string Title { get; set; } = string.Empty;
15+
16+
[JsonProperty("logo")]
17+
public string Logo { get; set; } = string.Empty;
18+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.ComponentModel.DataAnnotations;
2+
using OpenBioCardServer.Models.Enums;
3+
4+
namespace OpenBioCardServer.Models.Entities;
5+
6+
/// <summary>
7+
/// 系统设置实体 - 单例配置
8+
/// </summary>
9+
public class SystemSettingsEntity
10+
{
11+
[Key]
12+
public int Id { get; set; } = 1; // Singleton, always 1
13+
14+
[Required]
15+
[MaxLength(256)]
16+
public string Title { get; set; } = "OpenBioCard (Server)";
17+
18+
// Logo Asset (optional)
19+
public AssetType? LogoType { get; set; }
20+
[MaxLength(512)]
21+
public string? LogoText { get; set; }
22+
public byte[]? LogoData { get; set; }
23+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace OpenBioCardServer.Models;
2+
3+
public class WebsiteSettings
4+
{
5+
public string Title { get; set; } = string.Empty;
6+
public Asset Logo { get; set; } = new();
7+
}

OpenBioCardServer/Program.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,25 @@ await context.HttpContext.Response.WriteAsJsonAsync(new
188188
logger.LogInformation("==> Root password updated for: {Username}", rootUsername);
189189
}
190190
}
191+
192+
// System settings initialization
193+
var existingSettings = await context.SystemSettings.FindAsync(1);
194+
if (existingSettings == null)
195+
{
196+
var defaultSettings = new SystemSettingsEntity
197+
{
198+
Id = 1,
199+
Title = "OpenBioCard",
200+
LogoType = null,
201+
LogoText = null,
202+
LogoData = null
203+
};
204+
205+
context.SystemSettings.Add(defaultSettings);
206+
await context.SaveChangesAsync();
207+
208+
logger.LogInformation("==> Default system settings initialized");
209+
}
191210
}
192211

193212
if (app.Environment.IsDevelopment())

OpenBioCardServer/Utilities/Mappers/ClassicMapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public static void UpdateProfileFromClassic(ProfileEntity profile, ClassicProfil
161161
profile.CurrentSchoolLink = classic.CurrentSchoolLink;
162162
}
163163

164-
private static (AssetType type, string? text, byte[]? data) ParseAsset(string value)
164+
public static (AssetType type, string? text, byte[]? data) ParseAsset(string value)
165165
{
166166
if (string.IsNullOrEmpty(value))
167167
return (AssetType.Text, null, null);

0 commit comments

Comments
 (0)