新增农户功能升级:身份证OCR/OSS上传、头像采集、同名村检测、Region热度排序及表单体验优化
- Region 表新增热度列,热门省份优先显示 - 区县下拉按地级市分组、已录区县优先、支持全省搜索 - 组选择内置一组至二十组 - 银行卡号独立行+粗体预览,开户行独立行 - 新增农户类型:农户/个体户/合作社/经营集体/公司 - 身份证正反面支持高拍仪/摄像头OCR与手机扫码上传,附件存本地/OSS - 新增农户头像采集组件(摄像头/本地上传),预留人脸识别收购扩展 - 同名村弹窗提醒(防选错乡镇) - 编辑窗体禁止遮罩/Esc误关,整体加宽适配高频操作 - 修复二维码局域网手机无法访问(监听0.0.0.0、局域网IP识别、Vite代理兜底)
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
using AgriculturalPlatform.Api.Data;
|
||||
using AgriculturalPlatform.Api.Dtos;
|
||||
using AgriculturalPlatform.Api.Models;
|
||||
using AgriculturalPlatform.Api.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AgriculturalPlatform.Api.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/reports")]
|
||||
[Authorize]
|
||||
public class ReportsController(AppDbContext db, DataScopeService scope, CurrentUserService currentUser) : ControllerBase
|
||||
{
|
||||
/// <summary>收购汇总报表(维度:day=按日 / month=按月 / product=按品种 / farmer=按农户 / org=按收购方)</summary>
|
||||
[HttpGet("purchase-summary")]
|
||||
public async Task<ActionResult<PurchaseSummaryResult>> PurchaseSummary(
|
||||
string dimension = "day", DateTime? from = null, DateTime? to = null)
|
||||
{
|
||||
var start = from ?? DateTime.Today.AddDays(-29);
|
||||
var end = (to ?? DateTime.Today).Date.AddDays(1);
|
||||
|
||||
var visible = await scope.GetVisibleOrgIdsAsync(currentUser.Get());
|
||||
var query = db.PurchaseOrders
|
||||
.Where(p => p.Status == PurchaseStatus.Completed && p.CreatedAt >= start && p.CreatedAt < end)
|
||||
.AsQueryable();
|
||||
if (visible is not null)
|
||||
query = query.Where(p => visible.Contains(p.PurchaserOrgId));
|
||||
|
||||
var rows = dimension switch
|
||||
{
|
||||
"month" => await query
|
||||
.GroupBy(p => new { p.CreatedAt.Year, p.CreatedAt.Month })
|
||||
.Select(g => new
|
||||
{
|
||||
Key = $"{g.Key.Year}-{g.Key.Month:D2}",
|
||||
Amount = g.Sum(p => p.Amount),
|
||||
Weight = g.Sum(p => p.NetWeight),
|
||||
Cnt = g.Count()
|
||||
})
|
||||
.OrderBy(g => g.Key).ToListAsync(),
|
||||
"product" => await query
|
||||
.GroupBy(p => p.Product!.Name)
|
||||
.Select(g => new { Key = g.Key, Amount = g.Sum(p => p.Amount), Weight = g.Sum(p => p.NetWeight), Cnt = g.Count() })
|
||||
.OrderByDescending(g => g.Amount).ToListAsync(),
|
||||
"farmer" => await query
|
||||
.GroupBy(p => p.Farmer!.Name)
|
||||
.Select(g => new { Key = g.Key, Amount = g.Sum(p => p.Amount), Weight = g.Sum(p => p.NetWeight), Cnt = g.Count() })
|
||||
.OrderByDescending(g => g.Amount).Take(20).ToListAsync(),
|
||||
"org" => await query
|
||||
.GroupBy(p => p.PurchaserOrg!.Name)
|
||||
.Select(g => new { Key = g.Key, Amount = g.Sum(p => p.Amount), Weight = g.Sum(p => p.NetWeight), Cnt = g.Count() })
|
||||
.OrderByDescending(g => g.Amount).ToListAsync(),
|
||||
_ => await query
|
||||
.GroupBy(p => new { p.CreatedAt.Year, p.CreatedAt.Month, p.CreatedAt.Day })
|
||||
.Select(g => new
|
||||
{
|
||||
Key = $"{g.Key.Year}-{g.Key.Month:D2}-{g.Key.Day:D2}",
|
||||
Amount = g.Sum(p => p.Amount),
|
||||
Weight = g.Sum(p => p.NetWeight),
|
||||
Cnt = g.Count()
|
||||
})
|
||||
.OrderBy(g => g.Key).ToListAsync()
|
||||
};
|
||||
|
||||
return Ok(new PurchaseSummaryResult(
|
||||
dimension, start, end,
|
||||
rows.Sum(r => r.Amount), rows.Sum(r => r.Weight), rows.Sum(r => r.Cnt),
|
||||
rows.Select(r => new SummaryRow(r.Key, r.Key, r.Amount, r.Cnt)).ToArray()));
|
||||
}
|
||||
|
||||
/// <summary>付款统计报表</summary>
|
||||
[HttpGet("payment-summary")]
|
||||
public async Task<ActionResult<PaymentSummaryResult>> PaymentSummary(DateTime? from = null, DateTime? to = null)
|
||||
{
|
||||
var start = from ?? DateTime.Today.AddDays(-29);
|
||||
var end = (to ?? DateTime.Today).Date.AddDays(1);
|
||||
|
||||
var visible = await scope.GetVisibleOrgIdsAsync(currentUser.Get());
|
||||
var query = db.PaymentRecords.AsQueryable();
|
||||
if (visible is not null)
|
||||
query = query.Where(p => p.PurchaserOrgId != null && visible.Contains(p.PurchaserOrgId.Value));
|
||||
|
||||
var inRange = query.Where(p => p.CreatedAt >= start && p.CreatedAt < end);
|
||||
var totalPaid = await inRange.Where(p => p.Status == PayStatus.Success).SumAsync(p => (decimal?)p.Amount) ?? 0;
|
||||
var totalPending = await inRange.Where(p => p.Status == PayStatus.Pending).SumAsync(p => (decimal?)p.Amount) ?? 0;
|
||||
var payCount = await inRange.Where(p => p.Status == PayStatus.Success).CountAsync();
|
||||
|
||||
var byMethod = await inRange.GroupBy(p => p.Method.ToString())
|
||||
.Select(g => new { Key = g.Key, Value = g.Sum(p => p.Amount), Cnt = g.Count() })
|
||||
.ToListAsync();
|
||||
var byStatus = await inRange.GroupBy(p => p.Status.ToString())
|
||||
.Select(g => new { Key = g.Key, Value = g.Sum(p => p.Amount), Cnt = g.Count() })
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(new PaymentSummaryResult(start, end, totalPaid, totalPending, payCount,
|
||||
byMethod.Select(g => new SummaryRow(g.Key, g.Key, g.Value, g.Cnt)).ToArray(),
|
||||
byStatus.Select(g => new SummaryRow(g.Key, g.Key, g.Value, g.Cnt)).ToArray()));
|
||||
}
|
||||
|
||||
/// <summary>开票统计报表</summary>
|
||||
[HttpGet("invoice-summary")]
|
||||
public async Task<ActionResult<InvoiceSummaryResult>> InvoiceSummary(DateTime? from = null, DateTime? to = null)
|
||||
{
|
||||
var start = from ?? DateTime.Today.AddDays(-29);
|
||||
var end = (to ?? DateTime.Today).Date.AddDays(1);
|
||||
|
||||
var visible = await scope.GetVisibleOrgIdsAsync(currentUser.Get());
|
||||
var query = db.Invoices.Where(i => i.IssueDate >= start && i.IssueDate < end).AsQueryable();
|
||||
if (visible is not null)
|
||||
query = query.Where(i => visible.Contains(i.PurchaserOrgId));
|
||||
|
||||
var issued = query.Where(i => i.Status == InvoiceStatus.Issued);
|
||||
var totalAmount = await issued.SumAsync(i => (decimal?)i.Amount) ?? 0;
|
||||
var totalTax = await issued.SumAsync(i => (decimal?)i.TaxAmount) ?? 0;
|
||||
var issueCount = await issued.CountAsync();
|
||||
|
||||
var byProduct = await issued.GroupBy(i => i.Product!.Name)
|
||||
.Select(g => new { Key = g.Key, Value = g.Sum(i => i.Amount), Cnt = g.Count() })
|
||||
.OrderByDescending(g => g.Value).ToListAsync();
|
||||
var byStatus = await query.GroupBy(i => i.Status.ToString())
|
||||
.Select(g => new { Key = g.Key, Value = g.Sum(i => i.Amount), Cnt = g.Count() })
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(new InvoiceSummaryResult(start, end, totalAmount, totalTax, issueCount,
|
||||
byProduct.Select(g => new SummaryRow(g.Key, g.Key, g.Value, g.Cnt)).ToArray(),
|
||||
byStatus.Select(g => new SummaryRow(g.Key, g.Key, g.Value, g.Cnt)).ToArray()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user