- Region 表新增热度列,热门省份优先显示 - 区县下拉按地级市分组、已录区县优先、支持全省搜索 - 组选择内置一组至二十组 - 银行卡号独立行+粗体预览,开户行独立行 - 新增农户类型:农户/个体户/合作社/经营集体/公司 - 身份证正反面支持高拍仪/摄像头OCR与手机扫码上传,附件存本地/OSS - 新增农户头像采集组件(摄像头/本地上传),预留人脸识别收购扩展 - 同名村弹窗提醒(防选错乡镇) - 编辑窗体禁止遮罩/Esc误关,整体加宽适配高频操作 - 修复二维码局域网手机无法访问(监听0.0.0.0、局域网IP识别、Vite代理兜底)
149 lines
6.6 KiB
C#
149 lines
6.6 KiB
C#
using AgriculturalPlatform.Api.Data;
|
|
using AgriculturalPlatform.Api.Dtos;
|
|
using AgriculturalPlatform.Api.Models;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace AgriculturalPlatform.Api.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/farmers")]
|
|
[Authorize]
|
|
public class FarmersController(AppDbContext db) : ControllerBase
|
|
{
|
|
/// <summary>农户列表(分页/关键字/地区筛选)</summary>
|
|
[HttpGet]
|
|
public async Task<ActionResult<PagedResult<FarmerDto>>> List(
|
|
string? status, string? province, string? county, string? township, string? village,
|
|
[FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] string? keyword = null)
|
|
{
|
|
var query = db.Farmers.AsQueryable();
|
|
if (!string.IsNullOrWhiteSpace(status) && Enum.TryParse<FarmerStatus>(status, out var fs))
|
|
query = query.Where(f => f.Status == fs);
|
|
if (!string.IsNullOrWhiteSpace(province))
|
|
query = query.Where(f => f.Province == province);
|
|
if (!string.IsNullOrWhiteSpace(county))
|
|
query = query.Where(f => f.County == county);
|
|
if (!string.IsNullOrWhiteSpace(township))
|
|
query = query.Where(f => f.Township == township);
|
|
if (!string.IsNullOrWhiteSpace(village))
|
|
query = query.Where(f => f.Village == village);
|
|
if (!string.IsNullOrWhiteSpace(keyword))
|
|
query = query.Where(f => f.Name.Contains(keyword)
|
|
|| f.Phone.Contains(keyword)
|
|
|| f.IdCard.Contains(keyword)
|
|
|| f.Village.Contains(keyword)
|
|
|| f.Province.Contains(keyword)
|
|
|| f.County.Contains(keyword)
|
|
|| f.Township.Contains(keyword)
|
|
|| f.GroupName.Contains(keyword));
|
|
|
|
var total = await query.CountAsync();
|
|
var items = await query.OrderByDescending(f => f.Id)
|
|
.Skip((page - 1) * pageSize).Take(pageSize)
|
|
.ToListAsync();
|
|
return Ok(new PagedResult<FarmerDto>(items.ToDtos(), total));
|
|
}
|
|
|
|
/// <summary>全部农户(下拉选择用)</summary>
|
|
[HttpGet("all")]
|
|
public async Task<ActionResult> All(string? keyword, int limit = 50)
|
|
{
|
|
var query = db.Farmers.Where(f => f.Status == FarmerStatus.Active).AsQueryable();
|
|
if (!string.IsNullOrWhiteSpace(keyword))
|
|
query = query.Where(f => f.Name.Contains(keyword) || f.Phone.Contains(keyword) || f.IdCard.Contains(keyword));
|
|
var items = await query.OrderByDescending(f => f.Id).Take(limit)
|
|
.Select(f => new { f.Id, f.Name, f.Phone, f.Province, f.County, f.Township, f.Village, f.GroupName, f.IdCard }).ToListAsync();
|
|
return Ok(items);
|
|
}
|
|
|
|
/// <summary>农户详情(含交易统计)</summary>
|
|
[HttpGet("{id:int}")]
|
|
public async Task<ActionResult> Get(int id)
|
|
{
|
|
var farmer = await db.Farmers.FindAsync(id);
|
|
if (farmer is null) return NotFound();
|
|
|
|
var totalAmount = await db.PurchaseOrders
|
|
.Where(p => p.FarmerId == id && p.Status == PurchaseStatus.Completed)
|
|
.SumAsync(p => (decimal?)p.Amount) ?? 0;
|
|
var orderCount = await db.PurchaseOrders
|
|
.CountAsync(p => p.FarmerId == id && p.Status == PurchaseStatus.Completed);
|
|
var paidAmount = await db.PaymentRecords
|
|
.Where(p => p.FarmerId == id && p.Status == PayStatus.Success)
|
|
.SumAsync(p => (decimal?)p.Amount) ?? 0;
|
|
|
|
var dto = farmer.ToDto();
|
|
return Ok(new { farmer = dto, totalAmount, orderCount, paidAmount });
|
|
}
|
|
|
|
/// <summary>新增农户</summary>
|
|
[HttpPost]
|
|
public async Task<ActionResult<FarmerDto>> Create(FarmerSaveRequest req)
|
|
{
|
|
if (await db.Farmers.AnyAsync(f => f.IdCard == req.IdCard))
|
|
return BadRequest(new { message = "该身份证号已存在" });
|
|
if (!Enum.TryParse<FarmerStatus>(req.Status, out var status)) status = FarmerStatus.Active;
|
|
|
|
var farmer = new Farmer
|
|
{
|
|
Name = req.Name, IdCard = req.IdCard, Gender = req.Gender, FarmerType = req.FarmerType,
|
|
Phone = req.Phone,
|
|
Province = req.Province, County = req.County, Township = req.Township,
|
|
Village = req.Village, GroupName = req.GroupName,
|
|
Address = req.Address,
|
|
BankName = req.BankName, BankAccount = req.BankAccount,
|
|
IdCardFrontUrl = req.IdCardFrontUrl, IdCardBackUrl = req.IdCardBackUrl,
|
|
AvatarUrl = req.AvatarUrl,
|
|
CreditScore = req.CreditScore, Status = status, Notes = req.Notes
|
|
};
|
|
db.Farmers.Add(farmer);
|
|
await db.SaveChangesAsync();
|
|
return Ok(farmer.ToDto());
|
|
}
|
|
|
|
/// <summary>修改农户</summary>
|
|
[HttpPut("{id:int}")]
|
|
public async Task<ActionResult<FarmerDto>> Update(int id, FarmerSaveRequest req)
|
|
{
|
|
var farmer = await db.Farmers.FindAsync(id);
|
|
if (farmer is null) return NotFound();
|
|
if (req.IdCard != farmer.IdCard && await db.Farmers.AnyAsync(f => f.IdCard == req.IdCard))
|
|
return BadRequest(new { message = "该身份证号已存在" });
|
|
|
|
farmer.Name = req.Name; farmer.IdCard = req.IdCard; farmer.Gender = req.Gender;
|
|
farmer.FarmerType = req.FarmerType;
|
|
farmer.Phone = req.Phone;
|
|
farmer.Province = req.Province; farmer.County = req.County;
|
|
farmer.Township = req.Township; farmer.Village = req.Village;
|
|
farmer.GroupName = req.GroupName;
|
|
farmer.Address = req.Address;
|
|
farmer.BankName = req.BankName; farmer.BankAccount = req.BankAccount;
|
|
farmer.IdCardFrontUrl = req.IdCardFrontUrl; farmer.IdCardBackUrl = req.IdCardBackUrl;
|
|
farmer.AvatarUrl = req.AvatarUrl;
|
|
farmer.CreditScore = req.CreditScore; farmer.Notes = req.Notes;
|
|
if (Enum.TryParse<FarmerStatus>(req.Status, out var status)) farmer.Status = status;
|
|
farmer.UpdatedAt = DateTime.Now;
|
|
await db.SaveChangesAsync();
|
|
return Ok(farmer.ToDto());
|
|
}
|
|
|
|
/// <summary>删除农户(存在收购记录时禁止删除,仅冻结)</summary>
|
|
[HttpDelete("{id:int}")]
|
|
public async Task<IActionResult> Delete(int id)
|
|
{
|
|
var farmer = await db.Farmers.FindAsync(id);
|
|
if (farmer is null) return NotFound();
|
|
if (await db.PurchaseOrders.AnyAsync(p => p.FarmerId == id))
|
|
{
|
|
farmer.Status = FarmerStatus.Frozen;
|
|
await db.SaveChangesAsync();
|
|
return Ok(new { message = "该农户已有收购记录,已将其状态置为冻结" });
|
|
}
|
|
db.Farmers.Remove(farmer);
|
|
await db.SaveChangesAsync();
|
|
return Ok(new { message = "删除成功" });
|
|
}
|
|
}
|