luoqian 6acc92ca27 fix: 修复空 catch 吞异常问题,端口号抽离到配置,统一日志为 Serilog
- 所有空 catch 块补全日志记录,统一使用 Serilog/AppLog
- 按场景分级:Error(意外失败)、Warning(次要问题)、Information(预期内)
- 端口 HttpPort/HttpsPort 抽离到 appsettings.json Server 配置节
- QrCodeService 通过 IConfiguration 读取端口,消除硬编码
- 前端通过 Vite proxy 转发 /api,http.ts 统一使用 origin 地址
- 移除所有 Debug.WriteLine 和 Serilog.Log.Debug 日志

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 15:17:59 +08:00

62 lines
2.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FileShare_Common.Core;
using FileShare_Services.Core;
using Microsoft.Extensions.Configuration;
using QRCoder;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace FileShare_Services.Services.QrCode
{
/// <summary>
/// 二维码生成服务,获取局域网 IP 并生成 PNG 格式的访问二维码。
/// </summary>
public sealed class QrCodeService(IConfiguration configuration) : IQrCodeService
{
/// <inheritdoc />
public Task<object?> GenerateQrCodeAsync(ServiceEndpointContext ctx)
{
var ip = GetLanIpAddress();
if (ip is null)
throw new InvalidOperationException("无法获取局域网IP地址");
var port = int.TryParse(configuration["Server:HttpPort"], out var p) ? p : 5206;
var url = $"http://{ip}:{port}";
var base64 = GeneratePngBase64(url);
return Task.FromResult<object?>(ResponseHelper.Ok(new QrCodeResponse(url, base64)));
}
/// <summary>
/// 使用 QRCoder 库生成指定内容的二维码,输出为 Base64 编码的 PNG data URI。
/// </summary>
/// <param name="content">二维码编码内容。</param>
/// <returns>data URI 格式的 Base64 PNG 字符串。</returns>
private static string GeneratePngBase64(string content)
{
using var generator = new QRCodeGenerator();
using var data = generator.CreateQrCode(content, QRCodeGenerator.ECCLevel.Q);
using var png = new PngByteQRCode(data);
var bytes = png.GetGraphic(20);
return $"data:image/png;base64,{Convert.ToBase64String(bytes)}";
}
/// <summary>
/// 获取本机第一个可用的局域网 IPv4 地址,排除回环地址和 APIPA 地址169.254.x.x
/// </summary>
/// <returns>局域网 IP 地址字符串,无可用地址时返回 null。</returns>
private static string? GetLanIpAddress()
{
return NetworkInterface.GetAllNetworkInterfaces()
.Where(ni => ni.OperationalStatus == OperationalStatus.Up
&& ni.NetworkInterfaceType != NetworkInterfaceType.Loopback)
.SelectMany(ni => ni.GetIPProperties().UnicastAddresses)
.Select(ua => ua.Address)
.FirstOrDefault(ip =>
ip.AddressFamily == AddressFamily.InterNetwork
&& !IPAddress.IsLoopback(ip)
&& !ip.ToString().StartsWith("169.254"))
?.ToString();
}
}
}