Platform upgrade: login auth fix, OCR/OSS upload, system menus and dicts, weather dashboard, weighing and invoice modules

This commit is contained in:
2026-08-14 01:12:33 +08:00
parent c377421a3e
commit 8099ebae0a
75 changed files with 5611 additions and 473 deletions
@@ -7,7 +7,7 @@ public record LoginResult(string Token, UserInfoDto User);
public record UserInfoDto(
int Id, string Username, string RealName, string Phone, string Role,
int? OrgId, string? OrgName, string? OrgType, bool IsActive);
int? RoleId, string? RoleName, int? OrgId, string? OrgName, string? OrgType, bool IsActive);
public record ChangePasswordRequest(string OldPassword, string NewPassword);
@@ -3,7 +3,7 @@ using AgriculturalPlatform.Api.Models;
namespace AgriculturalPlatform.Api.Dtos;
public record FarmerDto(
int Id, string Name, string IdCard, string Gender, string FarmerType, string Phone,
int Id, string Name, string PinyinInitials, string IdCard, string Gender, string FarmerType, string Phone,
string Province, string County, string Township, string Village, string GroupName,
string Address, string BankName, string BankAccount, int CreditScore,
string IdCardFrontUrl, string IdCardBackUrl, string AvatarUrl,
@@ -15,12 +15,12 @@ public record FarmerSaveRequest(
string Address, string BankName, string BankAccount, int CreditScore = 80,
string FarmerType = "农户",
string IdCardFrontUrl = "", string IdCardBackUrl = "", string AvatarUrl = "",
string Status = "Active", string Notes = "");
string Status = "Active", string Notes = "", string PinyinInitials = "");
public static class FarmerMappers
{
public static FarmerDto ToDto(this Farmer f) => new(
f.Id, f.Name, f.IdCard, f.Gender, f.FarmerType, f.Phone,
f.Id, f.Name, f.PinyinInitials, f.IdCard, f.Gender, f.FarmerType, f.Phone,
f.Province, f.County, f.Township, f.Village, f.GroupName,
f.Address, f.BankName, f.BankAccount, f.CreditScore,
f.IdCardFrontUrl, f.IdCardBackUrl, f.AvatarUrl,
@@ -2,23 +2,53 @@ using AgriculturalPlatform.Api.Models;
namespace AgriculturalPlatform.Api.Dtos;
public record PurchaseWeighDto(
int Id, int SortNo, string Grade, string PriceType, decimal UnitPrice,
decimal GrossWeight, decimal TareWeight, decimal NetWeight, int BoxCount, decimal Amount, DateTime CreatedAt);
public record PurchaseTransferDto(
int Id, string TransferNo, string FromFarmer, string ToFarmer, string ToIdCard,
string Reason, string? OperatorName, DateTime CreatedAt);
public record PurchaseDto(
int Id, string OrderNo, int FarmerId, string FarmerName, string? FarmerPhone,
int ProductId, string ProductName, string Category, int PurchaserOrgId, string PurchaserOrgName,
string Grade, string Unit, decimal UnitPrice, decimal GrossWeight, decimal TareWeight,
decimal NetWeight, decimal Amount, int WeighCount, string Status,
string? OperatorName, DateTime WeighInAt, DateTime? WeighOutAt, string Notes, DateTime CreatedAt);
string? OperatorName, DateTime WeighInAt, DateTime? WeighOutAt, string Notes, DateTime CreatedAt,
List<PurchaseWeighDto> Weighs, int BoxCount);
/// <summary>新建收购单(第一次过磅:称毛重)</summary>
public record PurchaseCreateRequest(
int FarmerId, int ProductId, int PurchaserOrgId, string Grade,
decimal GrossWeight, string Unit = "公斤", decimal UnitPrice = 0, string Notes = "");
/// <summary>多磅收购单保存请求(一单多磅、多等级)</summary>
public record PurchaseMultiCreateRequest(
int FarmerId, int ProductId, int PurchaserOrgId, string Unit,
string? Notes, List<PurchaseWeighSaveRequest> Weighs);
public record PurchaseWeighSaveRequest(
string Grade, string PriceType, decimal UnitPrice, decimal GrossWeight,
decimal TareWeight, int BoxCount, decimal? NetWeight);
/// <summary>回皮完成(第二次过磅:称皮重,计算净重与金额)</summary>
public record PurchaseTareRequest(decimal TareWeight);
/// <summary>票据过户请求</summary>
public record PurchaseTransferRequest(string ToFarmer, string ToIdCard, string Reason);
/// <summary>收购单统计(多维汇总)</summary>
public record PurchaseSummaryDto(
int OrderCount, decimal TotalNetWeight, decimal AvgPrice, decimal TotalAmount,
int FarmerCount, int TodayOrderCount);
public static class PurchaseMappers
{
public static PurchaseWeighDto ToDto(this PurchaseWeigh w) => new(
w.Id, w.SortNo, w.Grade, w.PriceType, w.UnitPrice,
w.GrossWeight, w.TareWeight, w.NetWeight, w.BoxCount, w.Amount, w.CreatedAt);
public static PurchaseDto ToDto(this PurchaseOrder p) => new(
p.Id, p.OrderNo,
p.FarmerId, p.Farmer?.Name ?? "", p.Farmer?.Phone ?? "",
@@ -26,7 +56,9 @@ public static class PurchaseMappers
p.PurchaserOrgId, p.PurchaserOrg?.Name ?? "",
p.Grade, p.Unit, p.UnitPrice, p.GrossWeight, p.TareWeight,
p.NetWeight, p.Amount, p.WeighCount, p.Status.ToString(),
p.Operator?.RealName ?? "", p.WeighInAt, p.WeighOutAt, p.Notes, p.CreatedAt);
p.Operator?.RealName ?? "", p.WeighInAt, p.WeighOutAt, p.Notes, p.CreatedAt,
p.Weighs?.OrderBy(w => w.SortNo).Select(w => w.ToDto()).ToList() ?? new List<PurchaseWeighDto>(),
p.BoxCount);
public static PurchaseDto[] ToDtos(this IEnumerable<PurchaseOrder> items) => items.Select(ToDto).ToArray();
}
@@ -0,0 +1,34 @@
using AgriculturalPlatform.Api.Models;
namespace AgriculturalPlatform.Api.Dtos;
// ---------- 数据字典 ----------
public record DictDto(int Id, string Name, string Code, string Remark, bool IsSystem, int Sort, int ItemCount);
public record DictSaveRequest(string Name, string Code, string Remark, int Sort);
public record DictItemDto(int Id, int DictId, string Label, string Value, string Ext, bool IsDefault, bool Enabled, int Sort);
public record DictItemSaveRequest(string Label, string Value, string Ext, bool IsDefault, bool Enabled, int Sort);
public record DictDetailDto(DictDto Dict, List<DictItemDto> Items);
// ---------- 菜单/权限 ----------
public record MenuDto(
int Id, int? ParentId, string Name, string Path, string Component, string Icon,
string Type, string Permission, bool Visible, int Sort, List<MenuDto> Children);
public record MenuSaveRequest(
int? ParentId, string Name, string Path, string Component, string Icon,
string Type, string Permission, bool Visible, int Sort);
// ---------- 角色 ----------
public record RoleDto(int Id, string Name, string Code, string Description, bool IsSystem, int[] MenuIds);
public record RoleSaveRequest(string Name, string Code, string Description, int[] MenuIds);
// ---------- 通知公告 ----------
public record AnnouncementDto(
int Id, string Title, string Content, string Type, string ScopeOrgIds, bool IsPinned,
string PublisherName, DateTime PublishedAt, DateTime CreatedAt, bool IsRead);
public record AnnouncementSaveRequest(string Title, string Content, string Type, string ScopeOrgIds, bool IsPinned);
// ---------- 关于 ----------
public record AboutDto(
string AppName, string Version, string Copyright, string Company, string License,
string Description, DateTime BuiltAt);
@@ -4,17 +4,17 @@ namespace AgriculturalPlatform.Api.Dtos;
public record UserDto(
int Id, string Username, string RealName, string Phone, string Role,
int? OrgId, string? OrgName, bool IsActive, DateTime? LastLoginAt, DateTime CreatedAt);
int? RoleId, string? RoleName, int? OrgId, string? OrgName, bool IsActive, DateTime? LastLoginAt, DateTime CreatedAt);
public record UserSaveRequest(
string Username, string RealName, string Phone, string Role,
int? OrgId, bool IsActive = true, string? Password = null);
int? OrgId, int? RoleId = null, bool IsActive = true, string? Password = null);
public static class UserMappers
{
public static UserDto ToDto(this User u) => new(
u.Id, u.Username, u.RealName, u.Phone, u.Role.ToString(),
u.OrgId, u.Org?.Name, u.IsActive, u.LastLoginAt, u.CreatedAt);
u.RoleId, u.SysRole?.Name, u.OrgId, u.Org?.Name, u.IsActive, u.LastLoginAt, u.CreatedAt);
public static UserDto[] ToDtos(this IEnumerable<User> items) => items.Select(ToDto).ToArray();
}