修复充值
This commit is contained in:
parent
1c5a38ad73
commit
f18dd7a470
31
src/Oms.Application/Dtos/Recharge/SubmitRechargeFormInput.cs
Normal file
31
src/Oms.Application/Dtos/Recharge/SubmitRechargeFormInput.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Oms.Domain.RechargeAggregate.Enums;
|
||||
|
||||
namespace Oms.Application.Dtos.Recharge;
|
||||
|
||||
/// <summary>
|
||||
/// 充值提交入参(multipart/form-data,截图字段名为 rechargeScreenshot)。
|
||||
/// </summary>
|
||||
public class SubmitRechargeFormInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户主键(t_customer.Id)。
|
||||
/// </summary>
|
||||
public int? CustomerId { get; set; }
|
||||
|
||||
[Range(typeof(decimal), "0.01", "999999999999")]
|
||||
public decimal RechargeAmount { get; set; }
|
||||
|
||||
[Required]
|
||||
public PayType PayType { get; set; }
|
||||
|
||||
[StringLength(512)]
|
||||
public string? Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值截图文件。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public IFormFile RechargeScreenshot { get; set; } = null!;
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
using System.Linq.Expressions;
|
||||
using Fake.Application;
|
||||
using Fake.Domain.Exceptions;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MiniExcelLibs;
|
||||
using Oms.Application.Dtos.Recharge;
|
||||
@ -17,20 +19,16 @@ public class RechargeService : ApplicationService
|
||||
{
|
||||
private IRechargeRecordRepository RechargeRecordRepository => LazyServiceProvider.GetRequiredService<IRechargeRecordRepository>();
|
||||
private ICustomerRepository CustomerRepository => LazyServiceProvider.GetRequiredService<ICustomerRepository>();
|
||||
private IWebHostEnvironment WebHostEnvironment => LazyServiceProvider.GetRequiredService<IWebHostEnvironment>();
|
||||
|
||||
/// <summary>
|
||||
/// 提交充值申请。
|
||||
/// </summary>
|
||||
/// <param name="input">入参:充值提交参数。</param>
|
||||
/// <param name="input">入参:multipart 表单,截图字段 rechargeScreenshot。</param>
|
||||
/// <returns>充值记录结果。</returns>
|
||||
/// <remarks>
|
||||
/// 核心业务逻辑:
|
||||
/// 1. 校验入参与关联对象、唯一性等前置条件。
|
||||
/// 2. 组装目标实体及相关明细数据。
|
||||
/// 3. 写入审计字段并持久化结果。
|
||||
/// </remarks>
|
||||
[HttpPost("/recharge/recharge/submit")]
|
||||
public async Task<RechargeRecordOutput> SubmitAsync(SubmitRechargeInput input)
|
||||
[Consumes("multipart/form-data")]
|
||||
public async Task<RechargeRecordOutput> SubmitAsync([FromForm] SubmitRechargeFormInput input)
|
||||
{
|
||||
var customerId = input.CustomerId ?? CurrentUser.GetId<int>();
|
||||
if (customerId <= 0)
|
||||
@ -44,6 +42,15 @@ public class RechargeService : ApplicationService
|
||||
throw new BusinessException("客户不存在");
|
||||
}
|
||||
|
||||
if (input.RechargeAmount < 0.01M)
|
||||
{
|
||||
throw new BusinessException("充值金额不能小于 0.01");
|
||||
}
|
||||
|
||||
var screenshotPath = await OmsFileUploadHelper.SaveRechargeScreenshotAsync(
|
||||
input.RechargeScreenshot,
|
||||
WebHostEnvironment);
|
||||
|
||||
var entity = new RechargeRecord
|
||||
{
|
||||
CustomerId = customer.Id,
|
||||
@ -51,7 +58,7 @@ public class RechargeService : ApplicationService
|
||||
RechargeTime = DateTime.Now,
|
||||
PayType = input.PayType,
|
||||
RechargeAmount = input.RechargeAmount,
|
||||
RechargeScreenshot = input.RechargeScreenshot,
|
||||
RechargeScreenshot = screenshotPath,
|
||||
RechargeStatus = RechargeStatus.Pending,
|
||||
Remark = input.Remark
|
||||
};
|
||||
|
||||
73
src/Oms.Application/Shared/OmsFileUploadHelper.cs
Normal file
73
src/Oms.Application/Shared/OmsFileUploadHelper.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using Fake.Domain.Exceptions;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Oms.Application.Shared;
|
||||
|
||||
/// <summary>
|
||||
/// OMS 上传文件落盘(wwwroot/uploads)。
|
||||
/// </summary>
|
||||
public static class OmsFileUploadHelper
|
||||
{
|
||||
private static readonly HashSet<string> ImageExtensions =
|
||||
new(StringComparer.OrdinalIgnoreCase) { ".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp" };
|
||||
|
||||
private const long MaxImageBytes = 5 * 1024 * 1024;
|
||||
|
||||
/// <summary>
|
||||
/// 保存充值截图,返回以 /uploads 开头的相对访问路径。
|
||||
/// </summary>
|
||||
public static async Task<string> SaveRechargeScreenshotAsync(IFormFile file, IWebHostEnvironment env)
|
||||
{
|
||||
if (file == null || file.Length <= 0)
|
||||
{
|
||||
throw new BusinessException("请上传充值截图");
|
||||
}
|
||||
|
||||
if (file.Length > MaxImageBytes)
|
||||
{
|
||||
throw new BusinessException("充值截图大小不能超过 5MB");
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(file.FileName);
|
||||
if (string.IsNullOrWhiteSpace(ext) || !ImageExtensions.Contains(ext))
|
||||
{
|
||||
ext = GuessExtensionFromContentType(file.ContentType) ?? ".jpg";
|
||||
}
|
||||
|
||||
if (!ImageExtensions.Contains(ext))
|
||||
{
|
||||
throw new BusinessException("充值截图仅支持 jpg、png、webp、gif、bmp 格式");
|
||||
}
|
||||
|
||||
var webRoot = env.WebRootPath;
|
||||
if (string.IsNullOrWhiteSpace(webRoot))
|
||||
{
|
||||
webRoot = Path.Combine(env.ContentRootPath, "wwwroot");
|
||||
}
|
||||
|
||||
var monthFolder = DateTime.Now.ToString("yyyyMM");
|
||||
var relativeDir = Path.Combine("uploads", "recharge", monthFolder);
|
||||
var absoluteDir = Path.Combine(webRoot, relativeDir);
|
||||
Directory.CreateDirectory(absoluteDir);
|
||||
|
||||
var fileName = $"{Guid.NewGuid():N}{ext.ToLowerInvariant()}";
|
||||
var absolutePath = Path.Combine(absoluteDir, fileName);
|
||||
await using (var stream = File.Create(absolutePath))
|
||||
{
|
||||
await file.CopyToAsync(stream);
|
||||
}
|
||||
|
||||
return $"/uploads/recharge/{monthFolder}/{fileName}".Replace('\\', '/');
|
||||
}
|
||||
|
||||
private static string? GuessExtensionFromContentType(string? contentType) => contentType?.ToLowerInvariant() switch
|
||||
{
|
||||
"image/jpeg" or "image/jpg" => ".jpg",
|
||||
"image/png" => ".png",
|
||||
"image/webp" => ".webp",
|
||||
"image/gif" => ".gif",
|
||||
"image/bmp" => ".bmp",
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user