using Admin.NET.Plugin.AiDOP.Dto.S0.Manufacturing; using Admin.NET.Plugin.AiDOP.Dto.S0.Sales; using Admin.NET.Plugin.AiDOP.Entity.S0.Manufacturing; using Admin.NET.Plugin.AiDOP.Entity.S0.Sales; using Admin.NET.Plugin.AiDOP.Infrastructure; namespace Admin.NET.Plugin.AiDOP.Controllers.S0.Manufacturing; [ApiController] [Route("api/s0/manufacturing/preprocess-elements")] [AllowAnonymous] [NonUnify] public class AdoS0MfgPreprocessElementsController : ControllerBase { private readonly SqlSugarRepository _rep; private readonly SqlSugarRepository _itemRep; private readonly SqlSugarRepository _codeRep; public AdoS0MfgPreprocessElementsController( SqlSugarRepository rep, SqlSugarRepository itemRep, SqlSugarRepository codeRep) { _rep = rep; _itemRep = itemRep; _codeRep = codeRep; } [HttpGet] public async Task GetPagedAsync([FromQuery] AdoS0MfgPreprocessElementQueryDto q) { var page = q.EffectivePage; var pageSize = q.PageSize; (page, pageSize) = PagingGuard.Normalize(page, pageSize); // 去 domain 化(S0-DOMAIN-FILTER-REMOVAL-READONLY-1):主列表不再按 Domain 过滤、不再因缺 domain 返空, // 租户隔离由 ITenantIdFilter 自动生效。domain 仅保留供下方工序名(GeneralizedCode,无租户过滤)补显—— // 该补显为 D 档例外,本批不去 domain(去掉会跨租户/ToDictionary 重复键),domain 空时工序名留空、不报错。 var domain = q.Domain?.Trim() ?? string.Empty; var qsDomain = HttpContext.Request.Query["domain"].ToString(); if (!string.IsNullOrWhiteSpace(qsDomain)) domain = qsDomain.Trim(); var query = _rep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(q.MaterialCode), x => x.ItemNum.Contains(q.MaterialCode!)) .WhereIF(!string.IsNullOrWhiteSpace(q.Op), x => x.Op != null && x.Op.Contains(q.Op!)) .WhereIF(!string.IsNullOrWhiteSpace(q.ElementCode), x => x.ItemCode != null && x.ItemCode.Contains(q.ElementCode!)) .WhereIF(!string.IsNullOrWhiteSpace(q.Keyword), x => x.ItemNum.Contains(q.Keyword!) || (x.Op != null && x.Op.Contains(q.Keyword!)) || (x.ItemCode != null && x.ItemCode.Contains(q.Keyword!)) || (x.Descr != null && x.Descr.Contains(q.Keyword!))); var total = await query.CountAsync(); var list = await query .OrderByDescending(x => x.UpdateTime ?? x.CreateTime) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(); // 去 domain 化:物料名补显不再按 Domain 等值;ItemMaster 带 ITenantIdFilter,租户内 ItemNum 唯一,以 IsActive/RecID 稳定排序兜底确定性。 var distinctItemNums = list.Select(x => x.ItemNum).Distinct().ToList(); var items = await _itemRep.AsQueryable() .Where(m => distinctItemNums.Contains(m.ItemNum)) .OrderByDescending(m => m.IsActive) .OrderBy(m => m.Id) .Select(m => new { m.ItemNum, m.Descr }) .ToListAsync(); var itemDescrMap = items .GroupBy(x => x.ItemNum) .ToDictionary(g => g.Key, g => g.First().Descr); var opVals = list.Select(x => x.Op).Where(x => !string.IsNullOrWhiteSpace(x)).Cast().Distinct().ToList(); var opCodes = await _codeRep.AsQueryable() .Where(x => x.Domain == domain && x.FldName == "PrevProcessOp" && opVals.Contains(x.Val)) .Select(x => new { x.Val, x.Comments }) .ToListAsync(); var opDescrMap = opCodes.ToDictionary(x => x.Val, x => x.Comments ?? ""); var shaped = list.Select(x => new { id = x.Id, itemNum = x.ItemNum, itemDescr = itemDescrMap.TryGetValue(x.ItemNum, out var desc) ? desc : "", op = x.Op, opDescr = x.Op != null && opDescrMap.TryGetValue(x.Op, out var odesc) ? odesc : "", itemCode = x.ItemCode, descr = x.Descr, isMain = x.IsMain, domain = x.Domain, createUser = x.CreateUser, createTime = x.CreateTime, updateUser = x.UpdateUser, updateTime = x.UpdateTime, }).ToList(); return Ok(new { total, page, pageSize, list = shaped }); } [HttpGet("{id:long}")] public async Task GetAsync(long id) { var item = await _rep.GetByIdAsync(id); return item == null ? NotFound() : Ok(item); } [HttpPost] public async Task CreateAsync([FromBody] AdoS0MfgPreprocessElementUpsertDto dto) { var now = DateTime.Now; var entity = new AdoS0MfgPreprocessElement { Domain = dto.Domain.Trim(), ItemNum = dto.ItemNum.Trim(), Op = dto.Op, Line = dto.Line, Typed = dto.Typed, ItemCode = dto.ItemCode, Descr = dto.Descr, IsMain = dto.IsMain, CreateUser = dto.CreateUser ?? dto.UpdateUser, CreateTime = dto.CreateTime ?? dto.UpdateTime ?? now, UpdateUser = dto.UpdateUser, UpdateTime = dto.UpdateTime }; await _rep.AsInsertable(entity).ExecuteReturnEntityAsync(); return Ok(entity); } [HttpPut("{id:long}")] public async Task UpdateAsync(long id, [FromBody] AdoS0MfgPreprocessElementUpsertDto dto) { var entity = await _rep.GetByIdAsync(id); if (entity == null) return NotFound(); entity.Domain = dto.Domain.Trim(); entity.ItemNum = dto.ItemNum.Trim(); entity.Op = dto.Op; entity.Line = dto.Line; entity.Typed = dto.Typed; entity.ItemCode = dto.ItemCode; entity.Descr = dto.Descr; entity.IsMain = dto.IsMain; entity.UpdateUser = dto.UpdateUser; entity.UpdateTime = dto.UpdateTime ?? DateTime.Now; await _rep.AsUpdateable(entity).ExecuteCommandAsync(); return Ok(entity); } [HttpDelete("{id:long}")] public async Task DeleteAsync(long id) { var item = await _rep.GetByIdAsync(id); if (item == null) return NotFound(); await _rep.DeleteAsync(item); return Ok(new { message = "删除成功" }); } }