| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- using Admin.NET.Plugin.AiDOP.Dto.S0.Sales;
- using Admin.NET.Plugin.AiDOP.Entity.S0.Sales;
- using Admin.NET.Plugin.AiDOP.Infrastructure;
- namespace Admin.NET.Plugin.AiDOP.Controllers.S0.Sales;
- [ApiController]
- [Route("api/s0/sales/product-design-cycles")]
- [AllowAnonymous]
- [NonUnify]
- public class AdoS0ProductDesignCyclesController : ControllerBase
- {
- private readonly SqlSugarRepository<AdoS0ProductDesignCycle> _rep;
- private readonly SqlSugarRepository<AdoS0ItemMaster> _itemMasterRep;
- public AdoS0ProductDesignCyclesController(
- SqlSugarRepository<AdoS0ProductDesignCycle> rep,
- SqlSugarRepository<AdoS0ItemMaster> itemMasterRep)
- {
- _rep = rep;
- _itemMasterRep = itemMasterRep;
- }
- [HttpGet]
- public async Task<IActionResult> GetPagedAsync([FromQuery] AdoS0ProductDesignCycleQueryDto q)
- {
- (q.Page, q.PageSize) = PagingGuard.Normalize(q.Page, q.PageSize);
- var query = _rep.AsQueryable()
- .WhereIF(q.CompanyRefId.HasValue, x => x.CompanyRefId == q.CompanyRefId!.Value)
- .WhereIF(q.FactoryRefId.HasValue, x => x.FactoryRefId == q.FactoryRefId!.Value)
- .WhereIF(!string.IsNullOrWhiteSpace(q.DomainCode), x => x.DomainCode == q.DomainCode)
- .WhereIF(!string.IsNullOrWhiteSpace(q.ItemType), x => x.ItemType == q.ItemType)
- .WhereIF(!string.IsNullOrWhiteSpace(q.OwnerApplication), x => x.OwnerApplication == q.OwnerApplication)
- .WhereIF(q.IsActive.HasValue, x => x.IsActive == q.IsActive!.Value);
- var total = await query.CountAsync();
- var entities = await query
- .OrderByDescending(x => x.CreateTime)
- .Skip((q.Page - 1) * q.PageSize)
- .Take(q.PageSize)
- .ToListAsync();
- var list = await BuildRowsWithItemMasterMatchAsync(entities);
- return Ok(new { total, page = q.Page, pageSize = q.PageSize, list });
- }
- /// <summary>
- /// 在 PDC 实体基础上附带 ItemMaster 命中校验信息。
- /// 统计口径:
- /// - ItemMaster.ItemType = PDC.item_type;
- /// - PDC.domain_code 有值 → ItemMaster.Domain = domain_code;为 NULL → 不限 Domain;
- /// - OwnerApplication / Status 均不参与过滤。
- /// 实现:2 次查询(PDC 主列表上游已查 + ItemMaster 按 ItemType IN 一次性拉取相关列),
- /// 内存按 (ItemType, Domain) 分组计算 count / top3,避免 N+1。
- /// </summary>
- private async Task<List<AdoS0ProductDesignCycleRowDto>> BuildRowsWithItemMasterMatchAsync(
- List<AdoS0ProductDesignCycle> entities)
- {
- if (entities.Count == 0) return new List<AdoS0ProductDesignCycleRowDto>();
- var distinctItemTypes = entities
- .Select(e => e.ItemType)
- .Where(t => !string.IsNullOrWhiteSpace(t))
- .Distinct()
- .ToList();
- // 候选 ItemMaster 行(仅当前页相关 ItemType);空集合不发起查询。
- var candidates = distinctItemTypes.Count == 0
- ? new List<AdoS0ItemMaster>()
- : await _itemMasterRep.AsQueryable()
- .Where(x => distinctItemTypes.Contains(x.ItemType!))
- .Select(x => new AdoS0ItemMaster
- {
- Id = x.Id,
- ItemType = x.ItemType,
- DomainCode = x.DomainCode,
- ItemNum = x.ItemNum,
- Descr = x.Descr,
- })
- .ToListAsync();
- return entities.Select(e =>
- {
- var matched = candidates.Where(c =>
- c.ItemType == e.ItemType &&
- (string.IsNullOrWhiteSpace(e.DomainCode) || c.DomainCode == e.DomainCode))
- .ToList();
- var samples = matched
- .OrderBy(c => c.Id)
- .Take(3)
- .Select(c => string.IsNullOrWhiteSpace(c.Descr) ? c.ItemNum : $"{c.ItemNum} / {c.Descr}")
- .ToList();
- return new AdoS0ProductDesignCycleRowDto
- {
- Id = e.Id,
- CompanyRefId = e.CompanyRefId,
- FactoryRefId = e.FactoryRefId,
- DomainCode = e.DomainCode,
- ItemType = e.ItemType,
- OwnerApplication = e.OwnerApplication,
- StdHours = e.StdHours,
- IsActive = e.IsActive,
- CreateUser = e.CreateUser,
- CreateTime = e.CreateTime,
- UpdateUser = e.UpdateUser,
- UpdateTime = e.UpdateTime,
- ItemMasterMatchedCount = matched.Count,
- ItemMasterSampleItems = samples,
- };
- }).ToList();
- }
- [HttpGet("{id:long}")]
- public async Task<IActionResult> GetAsync(long id)
- {
- var item = await _rep.GetByIdAsync(id);
- return item == null ? NotFound() : Ok(item);
- }
- [HttpPost]
- public async Task<IActionResult> CreateAsync([FromBody] AdoS0ProductDesignCycleUpsertDto dto)
- {
- if (await _rep.IsAnyAsync(x => x.FactoryRefId == dto.FactoryRefId && x.ItemType == dto.ItemType && x.OwnerApplication == dto.OwnerApplication))
- return AdoS0ApiErrors.Conflict(AdoS0ErrorCodes.DuplicateCode, "该工厂下此物料类型+属性组合已存在");
- var entity = new AdoS0ProductDesignCycle
- {
- CompanyRefId = dto.CompanyRefId,
- FactoryRefId = dto.FactoryRefId,
- DomainCode = dto.DomainCode,
- ItemType = dto.ItemType,
- OwnerApplication = dto.OwnerApplication,
- StdHours = dto.StdHours,
- IsActive = dto.IsActive,
- CreateUser = dto.CreateUser,
- CreateTime = DateTime.Now,
- };
- await _rep.AsInsertable(entity).ExecuteReturnEntityAsync();
- return Ok(entity);
- }
- [HttpPut("{id:long}")]
- public async Task<IActionResult> UpdateAsync(long id, [FromBody] AdoS0ProductDesignCycleUpsertDto dto)
- {
- var entity = await _rep.GetByIdAsync(id);
- if (entity == null) return NotFound();
- if (await _rep.IsAnyAsync(x => x.Id != id && x.FactoryRefId == dto.FactoryRefId && x.ItemType == dto.ItemType && x.OwnerApplication == dto.OwnerApplication))
- return AdoS0ApiErrors.Conflict(AdoS0ErrorCodes.DuplicateCode, "该工厂下此物料类型+属性组合已存在");
- entity.CompanyRefId = dto.CompanyRefId;
- entity.FactoryRefId = dto.FactoryRefId;
- entity.DomainCode = dto.DomainCode;
- entity.ItemType = dto.ItemType;
- entity.OwnerApplication = dto.OwnerApplication;
- entity.StdHours = dto.StdHours;
- entity.IsActive = dto.IsActive;
- entity.UpdateUser = dto.UpdateUser;
- entity.UpdateTime = DateTime.Now;
- await _rep.AsUpdateable(entity).ExecuteCommandAsync();
- return Ok(entity);
- }
- [HttpPatch("{id:long}/toggle-enabled")]
- public async Task<IActionResult> ToggleActiveAsync(long id, [FromBody] AdoS0ProductDesignCycleToggleActiveDto dto)
- {
- var entity = await _rep.GetByIdAsync(id);
- if (entity == null) return NotFound();
- entity.IsActive = dto.IsActive;
- entity.UpdateTime = DateTime.Now;
- await _rep.AsUpdateable(entity).ExecuteCommandAsync();
- return Ok(entity);
- }
- [HttpDelete("{id:long}")]
- public async Task<IActionResult> DeleteAsync(long id)
- {
- var item = await _rep.GetByIdAsync(id);
- if (item == null) return NotFound();
- await _rep.DeleteAsync(item);
- return Ok(new { message = "删除成功" });
- }
- }
|