超级管理员操作数据不受时间限制

This commit is contained in:
fuenmao
2025-10-13 09:51:04 +08:00
parent 8d5a094408
commit 21d11a9805
2 changed files with 24 additions and 28 deletions
@@ -27,7 +27,7 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
//var dataScope = await _sysUserService.GetLoginUserApiDataScope(); //var dataScope = await _sysUserService.GetLoginUserApiDataScope();
//dataScope?.Remove(UserManager.OrgId); //dataScope?.Remove(UserManager.OrgId);
// 2. 分页查询药材基本信息(1次查询,原有逻辑不变) // 2. 分页查询药材基本信息
var query = this.AsQueryable() var query = this.AsQueryable()
//.WhereIF(dataScope.Any(), m => dataScope.Contains(m.Id)) //.WhereIF(dataScope.Any(), m => dataScope.Contains(m.Id))
.WhereIF(!string.IsNullOrEmpty(medicinalName), m => m.MedicinalName.Contains(medicinalName)) .WhereIF(!string.IsNullOrEmpty(medicinalName), m => m.MedicinalName.Contains(medicinalName))
@@ -42,11 +42,10 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
var pageInfo = await query.ToPagedListAsync(page, size); var pageInfo = await query.ToPagedListAsync(page, size);
if (!pageInfo.List.Any()) return pageInfo; if (!pageInfo.List.Any()) return pageInfo;
// 3. 批量计算:成本、剩余价值、总使用量(仅2次查询,无循环查询) // 3. 批量计算:成本、剩余价值、总使用量
var medicinalIds = pageInfo.List.Select(dto => dto.Id).ToList(); var medicinalIds = pageInfo.List.Select(dto => dto.Id).ToList();
var costAndUsageDict = await BatchCalculateCostAndValue(medicinalIds); var costAndUsageDict = await BatchCalculateCostAndValue(medicinalIds);
// 4. 内存中赋值所有指标(无数据库查询)
foreach (var item in pageInfo.List) foreach (var item in pageInfo.List)
{ {
if (costAndUsageDict.TryGetValue(item.Id, out var metrics)) if (costAndUsageDict.TryGetValue(item.Id, out var metrics))
@@ -102,10 +101,8 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
.LeftJoin<Person>((ph, p, pe) => p.PersonId == pe.Id) .LeftJoin<Person>((ph, p, pe) => p.PersonId == pe.Id)
// 再关联员工 // 再关联员工
.LeftJoin<Person>((ph, p, pe, emp) => pe.EmployeeId != null && pe.EmployeeId == emp.Id) .LeftJoin<Person>((ph, p, pe, emp) => pe.EmployeeId != null && pe.EmployeeId == emp.Id)
// 条件也使用多参数
.Where((ph, p, pe, emp) => ph.MedicinalId == medicinalId) .Where((ph, p, pe, emp) => ph.MedicinalId == medicinalId)
.OrderByDescending((ph, p, pe, emp) => p.VisitDate) .OrderByDescending((ph, p, pe, emp) => p.CreateTime)
// 投影使用所有表别名
.Select((ph, p, pe, emp) => new MedicinalConsumptionRecordDto .Select((ph, p, pe, emp) => new MedicinalConsumptionRecordDto
{ {
AmountG = ph.AmountG, AmountG = ph.AmountG,
@@ -114,7 +111,6 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
EmployeeName = emp == null ? null : emp.Name, EmployeeName = emp == null ? null : emp.Name,
UseTime = p.VisitDate UseTime = p.VisitDate
}) })
// 分页
.ToPagedListAsync(page, size); .ToPagedListAsync(page, size);
} }
@@ -142,7 +138,7 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
foreach (var item in returnList.List) foreach (var item in returnList.List)
{ {
if (item.AddTime.Date == DateTime.Now.Date) if (item.AddTime.Date == DateTime.Now.Date || UserManager.SuperAdmin)
{ {
item.CanEdit = true; item.CanEdit = true;
} }
@@ -156,7 +152,7 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
/// <returns></returns> /// <returns></returns>
public async Task<bool> AddMedicinal(AddMedicinalInput input) public async Task<bool> AddMedicinal(AddMedicinalInput input)
{ {
if (input.TotalPrice <= 0 || input.AddWeight <= 0) throw Oops.Bah("请填写正确的金额或者重量!"); if (input.TotalPrice <= 0 || input.AddWeight <= 0) throw Oops.Bah("请填写正确的金额!");
// 开启事务 // 开启事务
await Context.Ado.BeginTranAsync(); await Context.Ado.BeginTranAsync();
try try
@@ -213,21 +209,20 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
/// <summary> /// <summary>
/// 修改药材添加记录 /// 修改药材添加记录
/// </summary> /// </summary>
/// <param name="id"></param>
/// <param name="input"></param> /// <param name="input"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="Exception"></exception> /// <exception cref="Exception"></exception>
public async Task<bool> UpdateAdditionRecord(UpdateMedicinalAddLogInput input) public async Task<bool> UpdateAdditionRecord(UpdateMedicinalAddLogInput input)
{ {
if(input.TotalPrice<=0 || input.AddWeight<=0) throw Oops.Bah("请填写正确的金额或者重量!"); if(input.TotalPrice<=0 || input.AddWeight<=0) throw Oops.Bah("请填写正确的金额!");
var log = await Context.Queryable<MedicinalAddLog>().Where(l => l.Id == input.Id).FirstAsync(); var log = await Context.Queryable<MedicinalAddLog>().Where(l => l.Id == input.Id).FirstAsync();
if (log == null) if (log == null)
{ {
throw Oops.Bah("记录不存在!"); throw Oops.Bah("记录不存在!");
} }
// 检查是否是当天记录 // 检查是否是当天记录,超级管理员随时都可以操作
if (log.CreateTime.Value.Date != DateTime.Now.Date) if (log.CreateTime.Value.Date != DateTime.Now.Date && !UserManager.SuperAdmin)
{ {
throw Oops.Bah("只能修改当天的记录!"); throw Oops.Bah("只能修改当天的记录!");
} }
@@ -282,8 +277,8 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
throw Oops.Bah("记录不存在!"); throw Oops.Bah("记录不存在!");
} }
// 检查是否是当天记录 // 检查是否是当天记录,超级管理员随时都可以操作
if (log.CreateTime.Value.Date != DateTime.Now.Date) if (log.CreateTime.Value.Date != DateTime.Now.Date && !UserManager.SuperAdmin)
{ {
throw Oops.Bah("只能删除当天的记录!"); throw Oops.Bah("只能删除当天的记录!");
} }
@@ -334,13 +329,13 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
var result = new Dictionary<long, (decimal, decimal, decimal)>(); var result = new Dictionary<long, (decimal, decimal, decimal)>();
if (!medicinalIds.Any()) return result; if (!medicinalIds.Any()) return result;
// 1. 批量查询所有药材的【当前库存】(1次查询) // 1. 批量查询所有药材的【当前库存】
var medicinals = await Context.Queryable<Medicinal>() var medicinals = await Context.Queryable<Medicinal>()
.Where(m => medicinalIds.Contains(m.Id)) .Where(m => medicinalIds.Contains(m.Id))
.Select(m => new { m.Id, m.Number }) // Number = 当前库存 .Select(m => new { m.Id, m.Number }) // Number = 当前库存
.ToListAsync(); .ToListAsync();
// 2. 批量查询所有药材的【入库记录】(1次查询,仅查需要的字段) // 2. 批量查询所有药材的【入库记录】
var allAddLogs = await Context.Queryable<MedicinalAddLog>() var allAddLogs = await Context.Queryable<MedicinalAddLog>()
.Where(l => medicinalIds.Contains(l.MedicinalId)) .Where(l => medicinalIds.Contains(l.MedicinalId))
.OrderBy(l => l.CreateTime) // 先进先出:按入库时间排序 .OrderBy(l => l.CreateTime) // 先进先出:按入库时间排序
@@ -352,7 +347,7 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
}) })
.ToListAsync(); .ToListAsync();
// 3. 按【药材ID】分组入库记录(内存处理,无数据库查询) // 3. 按【药材ID】分组入库记录
var groupedLogs = allAddLogs var groupedLogs = allAddLogs
.GroupBy(l => l.MedicinalId) .GroupBy(l => l.MedicinalId)
.ToDictionary(g => g.Key, g => g.ToList()); .ToDictionary(g => g.Key, g => g.ToList());
@@ -377,7 +372,7 @@ public class MedicinalService : DbRepository<Medicinal>, IMedicinalService
// 计算总使用量:总入库量 - 当前库存(若结果为负,说明数据异常,按0处理) // 计算总使用量:总入库量 - 当前库存(若结果为负,说明数据异常,按0处理)
totalUsedWeight = Math.Max(0, totalIn - med.Number); totalUsedWeight = Math.Max(0, totalIn - med.Number);
// 若有使用量,继续用先进先出法计算使用成本 // 若有使用量,先进先出法计算使用成本
if (totalUsedWeight > 0 && groupedLogs.TryGetValue(med.Id, out var validLogs)) if (totalUsedWeight > 0 && groupedLogs.TryGetValue(med.Id, out var validLogs))
{ {
decimal remainingToCalculate = totalUsedWeight; decimal remainingToCalculate = totalUsedWeight;
@@ -53,7 +53,10 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
// 设置可编辑状态 // 设置可编辑状态
foreach (var item in prescriptionPage.List) foreach (var item in prescriptionPage.List)
{ {
item.CanEdit = item.CreateTime.Date == DateTime.Now.Date; if (item.CreateTime.Date == DateTime.Now.Date || UserManager.SuperAdmin)
{
item.CanEdit = true;
}
} }
// 获取当前页所有处方的药材明细 // 获取当前页所有处方的药材明细
@@ -109,7 +112,6 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
//家属成本多十个点 //家属成本多十个点
if (item.PersonType== PersonType.Relative) if (item.PersonType== PersonType.Relative)
{ {
// 四舍五入规则
item.TotalMedicineCost = Math.Round(item.TotalMedicineCost * (decimal)1.1, 2, MidpointRounding.AwayFromZero); item.TotalMedicineCost = Math.Round(item.TotalMedicineCost * (decimal)1.1, 2, MidpointRounding.AwayFromZero);
} }
} }
@@ -133,7 +135,7 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
// 批量查询所有涉及药材的入库记录(按时间排序) // 批量查询所有涉及药材的入库记录(按时间排序)
var addLogs = await Context.Queryable<MedicinalAddLog>() var addLogs = await Context.Queryable<MedicinalAddLog>()
.Where(l => medicinalIds.Contains(l.MedicinalId)) .Where(l => medicinalIds.Contains(l.MedicinalId))
.OrderBy(l => l.CreateTime) // FIFO核心:按入库时间排序 .OrderBy(l => l.CreateTime)
.Select(l => new MedicinalFifoRecord .Select(l => new MedicinalFifoRecord
{ {
MedicinalId = l.MedicinalId, MedicinalId = l.MedicinalId,
@@ -228,7 +230,7 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
Name = pe.Name Name = pe.Name
}) })
.FirstAsync(); .FirstAsync();
employee = empPerson; employee = empPerson;
} }
var RelationShipName = await GetRelationTypes(); var RelationShipName = await GetRelationTypes();
@@ -392,7 +394,7 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
}; };
await Context.Storageable(person).ExecuteCommandAsync(); await Context.Storageable(person).ExecuteCommandAsync();
// ---------- 4. 处方保存/编辑逻辑(沿用原逻辑) ---------- // ---------- 4. 处方保存/编辑逻辑----------
Prescription prescription; Prescription prescription;
if (input.Id.HasValue) // 编辑 if (input.Id.HasValue) // 编辑
{ {
@@ -402,7 +404,7 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
if (prescription == null) if (prescription == null)
throw Oops.Bah("处方不存在"); throw Oops.Bah("处方不存在");
if (prescription.CreateTime.Value.Date != DateTime.Now.Date) if (prescription.CreateTime.Value.Date != DateTime.Now.Date && !UserManager.SuperAdmin)
throw Oops.Bah("只能编辑当天的处方"); throw Oops.Bah("只能编辑当天的处方");
// 查询原有消耗记录并恢复库存 // 查询原有消耗记录并恢复库存
@@ -415,7 +417,6 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
foreach (var g in oldHerbs.GroupBy(x => x.MedicinalId)) foreach (var g in oldHerbs.GroupBy(x => x.MedicinalId))
{ {
// 恢复库存(加回已消耗) // 恢复库存(加回已消耗)
// 注意:使用 Updateable 批量操作替换为 SetColumns 表达式累加数值
await Context.Updateable<Medicinal>() await Context.Updateable<Medicinal>()
.SetColumns(m => new Medicinal { Number = m.Number + g.Sum(x => x.AmountG) }) .SetColumns(m => new Medicinal { Number = m.Number + g.Sum(x => x.AmountG) })
.Where(m => m.Id == g.Key) .Where(m => m.Id == g.Key)
@@ -423,7 +424,7 @@ public class PrescriptionService : DbRepository<Prescription>, IPrescriptionServ
} }
} }
// 删除原有处方药材(物理删除或软删按你系统策略) // 删除原有处方药材
await Context.Deleteable<PrescriptionHerb>() await Context.Deleteable<PrescriptionHerb>()
.Where(ph => ph.PrescriptionId == input.Id.Value) .Where(ph => ph.PrescriptionId == input.Id.Value)
.ExecuteCommandAsync(); .ExecuteCommandAsync();