diff --git a/backend/F9WebAiTest.Api/Controllers/Prod/KtpbController.cs b/backend/F9WebAiTest.Api/Controllers/Prod/KtpbController.cs new file mode 100644 index 0000000..89ee3cb --- /dev/null +++ b/backend/F9WebAiTest.Api/Controllers/Prod/KtpbController.cs @@ -0,0 +1,169 @@ +using F9WebAiTest.Application.Common; +using F9WebAiTest.Application.Dtos.Prod; +using F9WebAiTest.Application.Services.Prod; +using F9WebAiTest.Domain.Common; +using F9WebAiTest.Domain.Enums.SYS.Employees; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace F9WebAiTest.Api.Controllers.Prod; + +/// 看台排班(生产-前缫):车头工 / 挡车工 / 值班长 +[ApiController] +[Route("api/prod/ktpb")] +[Authorize] +public class KtpbController : ControllerBase +{ + private readonly IKtpbService _svc; + public KtpbController(IKtpbService svc) => _svc = svc; + + // ---------- 下拉 ---------- + + /// 车间下拉(职责类型=前缫) + [HttpGet("qianxian-deps")] + public async Task GetQianxianDeps() + => Ok(ApiResult>.Ok(await _svc.GetQianxianDepsAsync())); + + /// 机组下拉(含车台范围,来源于机组车台) + [HttpGet("jizu-options")] + public async Task GetJizuOptions([FromQuery] long depId) + => Ok(ApiResult>.Ok(await _svc.GetJizuOptionsAsync(depId))); + + // ---------- 车头工 ---------- + + [HttpGet("ctg")] + public async Task GetCtgPaged([FromQuery] long depId = 0, [FromQuery] Prod_Banci_Enum? banci = null, + [FromQuery] int? jizu = null, [FromQuery] string like = "", [FromQuery] int pageIndex = 1, + [FromQuery] int pageSize = 20) + => Ok(ApiResult>.Ok( + await _svc.GetCtgPagedAsync(depId, banci, jizu, like ?? string.Empty, pageIndex, pageSize))); + + [HttpGet("ctg/{id}")] + public async Task GetCtgById(long id) + { + try { return Ok(ApiResult.Ok(await _svc.GetCtgByIdAsync(id))); } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + [HttpPost("ctg")] + public async Task CreateCtg([FromBody] KtpbctgReadDto_View dto) + { + try + { + await _svc.CreateCtgAsync(dto); + return Ok(ApiResult.Ok(null, "新增成功")); + } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + [HttpPut("ctg/{id}")] + public async Task UpdateCtg(long id, [FromBody] KtpbctgReadDto_View dto) + { + try + { + await _svc.UpdateCtgAsync(id, dto); + return Ok(ApiResult.Ok(null, "修改成功")); + } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + [HttpDelete("ctg/{id}")] + public async Task DeleteCtg(long id) + { + try + { + await _svc.DeleteCtgAsync(id); + return Ok(ApiResult.Ok(null, "删除成功")); + } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + // ---------- 挡车工 ---------- + + [HttpGet("dcg")] + public async Task GetDcgPaged([FromQuery] long depId = 0, [FromQuery] Prod_Banci_Enum? banci = null, + [FromQuery] int? jizu = null, [FromQuery] string like = "", [FromQuery] int pageIndex = 1, + [FromQuery] int pageSize = 20) + => Ok(ApiResult>.Ok( + await _svc.GetDcgPagedAsync(depId, banci, jizu, like ?? string.Empty, pageIndex, pageSize))); + + /// 某「车间+班次+机组」下的整组排班(批量编辑弹窗) + [HttpGet("dcg/group")] + public async Task GetDcgGroup([FromQuery] long depId, [FromQuery] Prod_Banci_Enum banci, + [FromQuery] int jizu) + { + try { return Ok(ApiResult>.Ok(await _svc.GetDcgGroupAsync(depId, banci, jizu))); } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + /// 整组替换保存(传空集合表示清空该组) + [HttpPost("dcg/batch")] + public async Task SaveDcgBatch([FromBody] KtpbdcgBatchDto dto) + { + try + { + var count = await _svc.SaveDcgBatchAsync(dto); + return Ok(ApiResult.Ok(count, count > 0 ? $"已保存 {count} 条排班" : "已清空该组排班")); + } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + [HttpDelete("dcg/{id}")] + public async Task DeleteDcg(long id) + { + try + { + await _svc.DeleteDcgAsync(id); + return Ok(ApiResult.Ok(null, "删除成功")); + } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + // ---------- 值班长 ---------- + + [HttpGet("zbz")] + public async Task GetZbzPaged([FromQuery] long depId = 0, [FromQuery] Prod_Banci_Enum? banci = null, + [FromQuery] string like = "", [FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 20) + => Ok(ApiResult>.Ok( + await _svc.GetZbzPagedAsync(depId, banci, like ?? string.Empty, pageIndex, pageSize))); + + [HttpGet("zbz/{id}")] + public async Task GetZbzById(long id) + { + try { return Ok(ApiResult.Ok(await _svc.GetZbzByIdAsync(id))); } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + [HttpPost("zbz")] + public async Task CreateZbz([FromBody] KtpbzbzReadDto_View dto) + { + try + { + await _svc.CreateZbzAsync(dto); + return Ok(ApiResult.Ok(null, "新增成功")); + } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + [HttpPut("zbz/{id}")] + public async Task UpdateZbz(long id, [FromBody] KtpbzbzReadDto_View dto) + { + try + { + await _svc.UpdateZbzAsync(id, dto); + return Ok(ApiResult.Ok(null, "修改成功")); + } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } + + [HttpDelete("zbz/{id}")] + public async Task DeleteZbz(long id) + { + try + { + await _svc.DeleteZbzAsync(id); + return Ok(ApiResult.Ok(null, "删除成功")); + } + catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult.Fail(ex.Message, ex.Code)); } + } +} diff --git a/backend/F9WebAiTest.Api/f9_web_ai_test_rbac.db b/backend/F9WebAiTest.Api/f9_web_ai_test_rbac.db index 367ff92..13e22f1 100644 Binary files a/backend/F9WebAiTest.Api/f9_web_ai_test_rbac.db and b/backend/F9WebAiTest.Api/f9_web_ai_test_rbac.db differ diff --git a/backend/F9WebAiTest.Application/DependencyInjection.cs b/backend/F9WebAiTest.Application/DependencyInjection.cs index d9f1e82..17842a2 100644 --- a/backend/F9WebAiTest.Application/DependencyInjection.cs +++ b/backend/F9WebAiTest.Application/DependencyInjection.cs @@ -27,6 +27,7 @@ public static class DependencyInjection services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/backend/F9WebAiTest.Application/Dtos/Prod/KtpbDtos.cs b/backend/F9WebAiTest.Application/Dtos/Prod/KtpbDtos.cs new file mode 100644 index 0000000..9d8f81f --- /dev/null +++ b/backend/F9WebAiTest.Application/Dtos/Prod/KtpbDtos.cs @@ -0,0 +1,70 @@ +using F9WebAiTest.Domain.Enums.SYS.Employees; + +namespace F9WebAiTest.Application.Dtos.Prod; + +// ==================== 车头工看台排班 ==================== + +/// 车头工看台排班(列表/编辑) +public class KtpbctgReadDto_View +{ + public long Id { get; set; } + public long DepId { get; set; } + public string DeptName { get; set; } = ""; + public Prod_Banci_Enum Banci { get; set; } + public string BanciName { get; set; } = ""; + public int Jizu { get; set; } + public long Ygid1 { get; set; } + public string Ygid1Name { get; set; } = ""; + public long Ygid2 { get; set; } + public string Ygid2Name { get; set; } = ""; +} + +// ==================== 挡车工看台排班 ==================== + +/// 挡车工看台排班(列表/编辑) +public class KtpbdcgReadDto_View +{ + public long Id { get; set; } + public long DepId { get; set; } + public string DeptName { get; set; } = ""; + public Prod_Banci_Enum Banci { get; set; } + public string BanciName { get; set; } = ""; + public int Jizu { get; set; } + public int ChetaiStart { get; set; } + public int ChetaiEnd { get; set; } + public long YgId { get; set; } + public string YgName { get; set; } = ""; + public double Dangcheshu { get; set; } +} + +/// 挡车工批量编辑:一个「车间 + 班次 + 机组」下的整组排班替换 +public class KtpbdcgBatchDto +{ + public long DepId { get; set; } + public Prod_Banci_Enum Banci { get; set; } + public int Jizu { get; set; } + /// 该组下的全部挡车工排班(为空表示清空该组) + public List Items { get; set; } = new(); +} + +// ==================== 值班长排班 ==================== + +/// 值班长排班(列表/编辑) +public class KtpbzbzReadDto_View +{ + public long Id { get; set; } + public long DepId { get; set; } + public string DeptName { get; set; } = ""; + public Prod_Banci_Enum Banci { get; set; } + public string BanciName { get; set; } = ""; + public long YgId { get; set; } + public string YgName { get; set; } = ""; +} + +/// 机组下拉项(来源于机组车台) +public class KtpbJizuOptionDto +{ + public int Jizu { get; set; } + public int ChetaiStart { get; set; } + public int ChetaiEnd { get; set; } +} diff --git a/backend/F9WebAiTest.Application/Services/Prod/KtpbService.cs b/backend/F9WebAiTest.Application/Services/Prod/KtpbService.cs new file mode 100644 index 0000000..2f332bd --- /dev/null +++ b/backend/F9WebAiTest.Application/Services/Prod/KtpbService.cs @@ -0,0 +1,443 @@ +using F9WebAiTest.Application.Common; +using F9WebAiTest.Application.Dtos.Prod; +using F9WebAiTest.Domain.Common; +using F9WebAiTest.Domain.Entities.Base; +using F9WebAiTest.Domain.Entities.Prod; +using F9WebAiTest.Domain.Enums.SYS.Departments; +using F9WebAiTest.Domain.Enums.SYS.Employees; +using SysDept = F9WebAiTest.Domain.Entities.SYS.Departments; +using SysEmp = F9WebAiTest.Domain.Entities.SYS.Employees; + +namespace F9WebAiTest.Application.Services.Prod; + +/// +/// 看台排班(生产-前缫):车头工 / 挡车工 / 值班长三类排班的查询与维护。 +/// 对应 F9 WinClient\F9.Business.Prod\QS\KTPB 下的 Page_KTPB 与三个编辑页。 +/// +public interface IKtpbService +{ + /// 车间下拉(职责类型=前缫) + Task> GetQianxianDepsAsync(); + /// 指定车间的机组下拉(含车台范围,来源于机组车台) + Task> GetJizuOptionsAsync(long depId); + + // 车头工 + Task> GetCtgPagedAsync(long depId, Prod_Banci_Enum? banci, int? jizu, + string keyword, int pageIndex, int pageSize); + Task GetCtgByIdAsync(long id); + Task CreateCtgAsync(KtpbctgReadDto_View dto); + Task UpdateCtgAsync(long id, KtpbctgReadDto_View dto); + Task DeleteCtgAsync(long id); + + // 挡车工 + Task> GetDcgPagedAsync(long depId, Prod_Banci_Enum? banci, int? jizu, + string keyword, int pageIndex, int pageSize); + /// 取某个「车间+班次+机组」下的整组排班(批量编辑弹窗用) + Task> GetDcgGroupAsync(long depId, Prod_Banci_Enum banci, int jizu); + /// 整组替换:先删除该组旧排班,再按提交内容重建(挡车数由服务端重算) + Task SaveDcgBatchAsync(KtpbdcgBatchDto dto); + Task DeleteDcgAsync(long id); + + // 值班长 + Task> GetZbzPagedAsync(long depId, Prod_Banci_Enum? banci, + string keyword, int pageIndex, int pageSize); + Task GetZbzByIdAsync(long id); + Task CreateZbzAsync(KtpbzbzReadDto_View dto); + Task UpdateZbzAsync(long id, KtpbzbzReadDto_View dto); + Task DeleteZbzAsync(long id); +} + +public class KtpbService : IKtpbService +{ + private readonly IRepository _ctgRepo; + private readonly IRepository _dcgRepo; + private readonly IRepository _zbzRepo; + private readonly IRepository _jzctRepo; + private readonly IRepository _deptRepo; + private readonly IRepository _empRepo; + + public KtpbService(IRepository ctgRepo, IRepository dcgRepo, IRepository zbzRepo, + IRepository jzctRepo, IRepository deptRepo, + IRepository empRepo) + { + _ctgRepo = ctgRepo; + _dcgRepo = dcgRepo; + _zbzRepo = zbzRepo; + _jzctRepo = jzctRepo; + _deptRepo = deptRepo; + _empRepo = empRepo; + } + + // ==================== 下拉 ==================== + + public async Task> GetQianxianDepsAsync() + { + var depts = await _deptRepo.GetAllAsync(); + return depts + .Where(d => d.DutyType == Department_DutyType_Enum.前缫) + .OrderBy(d => d.SortOrder).ThenBy(d => d.Id) + .Select(d => new ChejianbanciDepOptionDto { Id = d.Id, Name = d.Name }) + .ToList(); + } + + public async Task> GetJizuOptionsAsync(long depId) + { + var list = await _jzctRepo.FindAsync(x => x.DepartmentId == depId); + return list.OrderBy(x => x.Jizu) + .Select(x => new KtpbJizuOptionDto + { + Jizu = x.Jizu, + ChetaiStart = x.ChetaiStart, + ChetaiEnd = x.ChetaiEnd + }) + .ToList(); + } + + // ==================== 车头工 ==================== + + public async Task> GetCtgPagedAsync(long depId, Prod_Banci_Enum? banci, + int? jizu, string keyword, int pageIndex, int pageSize) + { + if (pageIndex <= 0) pageIndex = 1; + if (pageSize <= 0) pageSize = 20; + + var deptDict = await GetDeptDictAsync(); + var empDict = await GetEmpDictAsync(); + + var all = await _ctgRepo.GetAllAsync(); + var q = all.AsEnumerable(); + if (depId > 0) q = q.Where(x => x.DeptId == depId); + if (banci.HasValue) q = q.Where(x => x.Banci == banci.Value); + if (jizu.HasValue && jizu.Value > 0) q = q.Where(x => x.Jizu == jizu.Value); + + var views = q.OrderBy(x => x.DeptId).ThenBy(x => x.Banci).ThenBy(x => x.Jizu) + .Select(x => ToCtgView(x, deptDict, empDict)).ToList(); + + if (!string.IsNullOrWhiteSpace(keyword)) + { + var kw = keyword.Trim(); + views = views.Where(x => x.DeptName.Contains(kw) || x.BanciName.Contains(kw) + || x.Jizu.ToString().Contains(kw) || x.Ygid1Name.Contains(kw) || x.Ygid2Name.Contains(kw)).ToList(); + } + + return Paged(views, pageIndex, pageSize); + } + + public async Task GetCtgByIdAsync(long id) + { + var e = await _ctgRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404); + return ToCtgView(e, await GetDeptDictAsync(), await GetEmpDictAsync()); + } + + public async Task CreateCtgAsync(KtpbctgReadDto_View dto) + { + await ValidateGroupAsync(dto.DepId, dto.Banci, dto.Jizu, 0); + if (dto.Ygid1 <= 0) throw new ServiceException("请选择车头工1"); + + await _ctgRepo.AddAsync(new KtpbCtg + { + DeptId = dto.DepId, + Banci = dto.Banci, + Jizu = dto.Jizu, + Ygid1 = dto.Ygid1, + Ygid2 = dto.Ygid2 + }); + await _ctgRepo.SaveChangesAsync(); + } + + public async Task UpdateCtgAsync(long id, KtpbctgReadDto_View dto) + { + var e = await _ctgRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404); + await ValidateGroupAsync(dto.DepId, dto.Banci, dto.Jizu, id); + if (dto.Ygid1 <= 0) throw new ServiceException("请选择车头工1"); + + e.DeptId = dto.DepId; + e.Banci = dto.Banci; + e.Jizu = dto.Jizu; + e.Ygid1 = dto.Ygid1; + e.Ygid2 = dto.Ygid2; + await _ctgRepo.UpdateAsync(e); + await _ctgRepo.SaveChangesAsync(); + } + + public async Task DeleteCtgAsync(long id) + { + var e = await _ctgRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404); + await _ctgRepo.DeleteAsync(e); + await _ctgRepo.SaveChangesAsync(); + } + + // ==================== 挡车工 ==================== + + public async Task> GetDcgPagedAsync(long depId, Prod_Banci_Enum? banci, + int? jizu, string keyword, int pageIndex, int pageSize) + { + if (pageIndex <= 0) pageIndex = 1; + if (pageSize <= 0) pageSize = 20; + + var deptDict = await GetDeptDictAsync(); + var empDict = await GetEmpDictAsync(); + + var all = await _dcgRepo.GetAllAsync(); + var q = all.AsEnumerable(); + if (depId > 0) q = q.Where(x => x.DeptId == depId); + if (banci.HasValue) q = q.Where(x => x.Banci == banci.Value); + if (jizu.HasValue && jizu.Value > 0) q = q.Where(x => x.Jizu == jizu.Value); + + var views = q.OrderBy(x => x.DeptId).ThenBy(x => x.Banci).ThenBy(x => x.Jizu) + .ThenBy(x => x.ChetaiStart) + .Select(x => ToDcgView(x, deptDict, empDict)).ToList(); + + if (!string.IsNullOrWhiteSpace(keyword)) + { + var kw = keyword.Trim(); + views = views.Where(x => x.DeptName.Contains(kw) || x.BanciName.Contains(kw) + || x.YgName.Contains(kw) || x.Jizu.ToString().Contains(kw) + || x.ChetaiStart.ToString().Contains(kw) || x.ChetaiEnd.ToString().Contains(kw)).ToList(); + } + + return Paged(views, pageIndex, pageSize); + } + + public async Task> GetDcgGroupAsync(long depId, Prod_Banci_Enum banci, int jizu) + { + if (depId <= 0) throw new ServiceException("请选择车间"); + var deptDict = await GetDeptDictAsync(); + var empDict = await GetEmpDictAsync(); + var list = await _dcgRepo.FindAsync(x => x.DeptId == depId && x.Banci == banci && x.Jizu == jizu); + return list.OrderBy(x => x.ChetaiStart).ThenBy(x => x.ChetaiEnd) + .Select(x => ToDcgView(x, deptDict, empDict)).ToList(); + } + + public async Task SaveDcgBatchAsync(KtpbdcgBatchDto dto) + { + if (dto.DepId <= 0) throw new ServiceException("请选择车间"); + if (dto.Jizu <= 0) throw new ServiceException("请选择机组"); + + var items = dto.Items ?? new List(); + foreach (var it in items) + { + if (it.YgId <= 0) throw new ServiceException("存在未选择挡车工的记录"); + if (it.ChetaiStart <= 0) throw new ServiceException($"挡车工「{it.YgName}」的起始车台必须大于 0"); + if (it.ChetaiEnd < it.ChetaiStart) + throw new ServiceException($"挡车工「{it.YgName}」的结束车台不能小于起始车台"); + } + + var jzct = await _jzctRepo.FirstOrDefaultAsync(x => x.DepartmentId == dto.DepId && x.Jizu == dto.Jizu); + if (jzct != null) + { + foreach (var it in items) + { + if (it.ChetaiStart < jzct.ChetaiStart || it.ChetaiEnd > jzct.ChetaiEnd) + throw new ServiceException( + $"挡车工「{it.YgName}」的车台范围 {it.ChetaiStart}-{it.ChetaiEnd} 超出该机组车台范围 " + + $"{jzct.ChetaiStart}-{jzct.ChetaiEnd}"); + } + } + + // 整组替换:先删后建(对齐 F9 BatchReplaceKtpbdcgCommand) + var olds = await _dcgRepo.FindAsync(x => x.DeptId == dto.DepId && x.Banci == dto.Banci && x.Jizu == dto.Jizu); + if (olds.Count > 0) await _dcgRepo.HardDeleteRangeAsync(olds); + + var dangche = RecalcDangcheshu(items); + foreach (var it in items) + { + await _dcgRepo.AddAsync(new KtpbDcg + { + DeptId = dto.DepId, + Banci = dto.Banci, + Jizu = dto.Jizu, + ChetaiStart = it.ChetaiStart, + ChetaiEnd = it.ChetaiEnd, + YgId = it.YgId, + Dangcheshu = dangche.GetValueOrDefault(BuildDcgKey(it.ChetaiStart, it.ChetaiEnd, it.YgId), 0) + }); + } + await _dcgRepo.SaveChangesAsync(); + return items.Count; + } + + public async Task DeleteDcgAsync(long id) + { + var e = await _dcgRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404); + await _dcgRepo.DeleteAsync(e); + await _dcgRepo.SaveChangesAsync(); + } + + /// + /// 挡车数计算(移植 F9 Page_KTPBDCG_Edit.CalculateSingleDangcheshu): + /// 每个车台默认权重 1;若该车台被多条记录共享,且同时是某记录的起始点与某记录的结束点(接壤车台),权重取 0.5。 + /// + private static Dictionary RecalcDangcheshu(List records) + { + var result = new Dictionary(); + if (records.Count == 0) return result; + + var counts = new Dictionary(); + var starts = new HashSet(); + var ends = new HashSet(); + foreach (var r in records) + { + starts.Add(r.ChetaiStart); + ends.Add(r.ChetaiEnd); + for (var i = r.ChetaiStart; i <= r.ChetaiEnd; i++) + counts[i] = counts.GetValueOrDefault(i) + 1; + } + + foreach (var r in records) + { + double total = 0; + for (var i = r.ChetaiStart; i <= r.ChetaiEnd; i++) + { + double weight = 1; + if (counts.GetValueOrDefault(i) > 1 && starts.Contains(i) && ends.Contains(i)) weight = 0.5; + total += weight; + } + result[BuildDcgKey(r.ChetaiStart, r.ChetaiEnd, r.YgId)] = Math.Round(total, 2); + } + return result; + } + + private static string BuildDcgKey(int start, int end, long ygId) => $"{start}-{end}-{ygId}"; + + // ==================== 值班长 ==================== + + public async Task> GetZbzPagedAsync(long depId, Prod_Banci_Enum? banci, + string keyword, int pageIndex, int pageSize) + { + if (pageIndex <= 0) pageIndex = 1; + if (pageSize <= 0) pageSize = 20; + + var deptDict = await GetDeptDictAsync(); + var empDict = await GetEmpDictAsync(); + + var all = await _zbzRepo.GetAllAsync(); + var q = all.AsEnumerable(); + if (depId > 0) q = q.Where(x => x.DeptId == depId); + if (banci.HasValue) q = q.Where(x => x.Banci == banci.Value); + + var views = q.OrderBy(x => x.DeptId).ThenBy(x => x.Banci).ThenBy(x => x.Id) + .Select(x => ToZbzView(x, deptDict, empDict)).ToList(); + + if (!string.IsNullOrWhiteSpace(keyword)) + { + var kw = keyword.Trim(); + views = views.Where(x => x.DeptName.Contains(kw) || x.BanciName.Contains(kw) || x.YgName.Contains(kw)) + .ToList(); + } + + return Paged(views, pageIndex, pageSize); + } + + public async Task GetZbzByIdAsync(long id) + { + var e = await _zbzRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404); + return ToZbzView(e, await GetDeptDictAsync(), await GetEmpDictAsync()); + } + + public async Task CreateZbzAsync(KtpbzbzReadDto_View dto) + { + if (dto.DepId <= 0) throw new ServiceException("请选择车间"); + if (dto.YgId <= 0) throw new ServiceException("请选择值班长"); + + var dup = await _zbzRepo.AnyAsync(x => x.DeptId == dto.DepId && x.Banci == dto.Banci && x.YgId == dto.YgId); + if (dup) throw new ServiceException("该车间该班次已存在此值班长排班"); + + await _zbzRepo.AddAsync(new KtpbZbz { DeptId = dto.DepId, Banci = dto.Banci, YgId = dto.YgId }); + await _zbzRepo.SaveChangesAsync(); + } + + public async Task UpdateZbzAsync(long id, KtpbzbzReadDto_View dto) + { + var e = await _zbzRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404); + if (dto.DepId <= 0) throw new ServiceException("请选择车间"); + if (dto.YgId <= 0) throw new ServiceException("请选择值班长"); + + var dup = await _zbzRepo.AnyAsync(x => x.Id != id && x.DeptId == dto.DepId + && x.Banci == dto.Banci && x.YgId == dto.YgId); + if (dup) throw new ServiceException("该车间该班次已存在此值班长排班"); + + e.DeptId = dto.DepId; + e.Banci = dto.Banci; + e.YgId = dto.YgId; + await _zbzRepo.UpdateAsync(e); + await _zbzRepo.SaveChangesAsync(); + } + + public async Task DeleteZbzAsync(long id) + { + var e = await _zbzRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404); + await _zbzRepo.DeleteAsync(e); + await _zbzRepo.SaveChangesAsync(); + } + + // ==================== 公共 ==================== + + /// 车头工:同一「车间+班次+机组」只能有一条排班 + private async Task ValidateGroupAsync(long depId, Prod_Banci_Enum banci, int jizu, long excludeId) + { + if (depId <= 0) throw new ServiceException("请选择车间"); + if (jizu <= 0) throw new ServiceException("请选择机组"); + + var dup = await _ctgRepo.AnyAsync(x => x.Id != excludeId && x.DeptId == depId + && x.Banci == banci && x.Jizu == jizu); + if (dup) throw new ServiceException("该车间该班次该机组已有车头工排班"); + } + + private async Task> GetDeptDictAsync() + => (await _deptRepo.GetAllAsync()).ToDictionary(d => d.Id, d => d.Name); + + private async Task> GetEmpDictAsync() + => (await _empRepo.GetAllAsync()).ToDictionary(e => e.Id, e => e.Name); + + private static KtpbctgReadDto_View ToCtgView(KtpbCtg x, Dictionary deptDict, + Dictionary empDict) => new() + { + Id = x.Id, + DepId = x.DeptId, + DeptName = deptDict.GetValueOrDefault(x.DeptId, ""), + Banci = x.Banci, + BanciName = x.Banci.ToString(), + Jizu = x.Jizu, + Ygid1 = x.Ygid1, + Ygid1Name = empDict.GetValueOrDefault(x.Ygid1, ""), + Ygid2 = x.Ygid2, + Ygid2Name = empDict.GetValueOrDefault(x.Ygid2, "") + }; + + private static KtpbdcgReadDto_View ToDcgView(KtpbDcg x, Dictionary deptDict, + Dictionary empDict) => new() + { + Id = x.Id, + DepId = x.DeptId, + DeptName = deptDict.GetValueOrDefault(x.DeptId, ""), + Banci = x.Banci, + BanciName = x.Banci.ToString(), + Jizu = x.Jizu, + ChetaiStart = x.ChetaiStart, + ChetaiEnd = x.ChetaiEnd, + YgId = x.YgId, + YgName = empDict.GetValueOrDefault(x.YgId, ""), + Dangcheshu = x.Dangcheshu + }; + + private static KtpbzbzReadDto_View ToZbzView(KtpbZbz x, Dictionary deptDict, + Dictionary empDict) => new() + { + Id = x.Id, + DepId = x.DeptId, + DeptName = deptDict.GetValueOrDefault(x.DeptId, ""), + Banci = x.Banci, + BanciName = x.Banci.ToString(), + YgId = x.YgId, + YgName = empDict.GetValueOrDefault(x.YgId, "") + }; + + private static PageResult Paged(List all, int pageIndex, int pageSize) => new() + { + Items = all.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(), + Total = all.Count, + PageIndex = pageIndex, + PageSize = pageSize + }; +} diff --git a/backend/F9WebAiTest.Domain/Entities/Prod/Ktpb.cs b/backend/F9WebAiTest.Domain/Entities/Prod/Ktpb.cs new file mode 100644 index 0000000..d379527 --- /dev/null +++ b/backend/F9WebAiTest.Domain/Entities/Prod/Ktpb.cs @@ -0,0 +1,41 @@ +using FreeSql.DataAnnotations; +using F9WebAiTest.Domain.Common; +using F9WebAiTest.Domain.Enums.SYS.Employees; + +namespace F9WebAiTest.Domain.Entities.Prod; + +// 看台排班(对应 F9 生产-前缫 的 KTPB 三张表:车头工 / 挡车工 / 值班长) +// 排班以「车间 + 班次」为组织单元;挡车工/车头工再细分「机组」。 + +/// 车头工看台排班(biz_prod_qs_ktpb_ctg) +[Table(Name = "KtpbCtgs")] +public class KtpbCtg : BaseEntity +{ + public long DeptId { get; set; } // 车间(前缫车间) + public Prod_Banci_Enum Banci { get; set; } // 班次(甲/乙) + public int Jizu { get; set; } // 机组 + public long Ygid1 { get; set; } // 车头工1 + public long Ygid2 { get; set; } // 车头工2 +} + +/// 挡车工看台排班(biz_prod_qs_ktpb_dcg) +[Table(Name = "KtpbDcgs")] +public class KtpbDcg : BaseEntity +{ + public long DeptId { get; set; } // 车间 + public Prod_Banci_Enum Banci { get; set; } // 班次 + public int Jizu { get; set; } // 机组 + public int ChetaiStart { get; set; } // 起始车台号 + public int ChetaiEnd { get; set; } // 结束车台号 + public long YgId { get; set; } // 挡车工 + public double Dangcheshu { get; set; } // 挡车数(相邻车台各 0.5 的口径,保存时重算) +} + +/// 值班长排班(biz_prod_qs_ktpb_zbz) +[Table(Name = "KtpbZbzs")] +public class KtpbZbz : BaseEntity +{ + public long DeptId { get; set; } // 车间 + public Prod_Banci_Enum Banci { get; set; } // 班次 + public long YgId { get; set; } // 值班长 +} diff --git a/backend/F9WebAiTest.Infrastructure/Data/DbSeeder.cs b/backend/F9WebAiTest.Infrastructure/Data/DbSeeder.cs index 0310dd2..e80859b 100644 --- a/backend/F9WebAiTest.Infrastructure/Data/DbSeeder.cs +++ b/backend/F9WebAiTest.Infrastructure/Data/DbSeeder.cs @@ -718,7 +718,8 @@ public static class DbSeeder new (string Name, string Path, string Component, string Permission, string Icon, int Sort)[] { ("落丝记录", "/prod/qianxian/lsjl", "prod/lsjl/index", "prod:lsjl:list", "Document", 1), - ("车间班次", "/prod/qianxian/chejianbanci", "base/chejianbanci/index", "prod:chejianbanci:list", "Timer", 2) + ("车间班次", "/prod/qianxian/chejianbanci", "base/chejianbanci/index", "prod:chejianbanci:list", "Timer", 2), + ("看台排班", "/prod/qianxian/ktpb", "prod/ktpb/index", "prod:ktpb:list", "Grid", 3) }); EnsureTopMenuWithChildren(fsql, snowflake, "/prod/houxian", "生产-后缫", "DataLine", 6, diff --git a/backend/F9WebAiTest.Infrastructure/Data/ProdSeedData.cs b/backend/F9WebAiTest.Infrastructure/Data/ProdSeedData.cs index 7278ee8..d80bf17 100644 --- a/backend/F9WebAiTest.Infrastructure/Data/ProdSeedData.cs +++ b/backend/F9WebAiTest.Infrastructure/Data/ProdSeedData.cs @@ -7,6 +7,7 @@ using F9WebAiTest.Domain.Entities.Base; using F9WebAiTest.Domain.Entities.Prod; using F9WebAiTest.Domain.Enums.SYS.Employees; using SysDept = F9WebAiTest.Domain.Entities.SYS.Departments; +using SysEmp = F9WebAiTest.Domain.Entities.SYS.Employees; namespace F9WebAiTest.Infrastructure.Data; @@ -20,6 +21,9 @@ public static class ProdSeedData { private const string JzctResource = "F9WebAiTest.Infrastructure.Data.SeedData.biz_prod_qs_jzct.json"; private const string CjbcResource = "F9WebAiTest.Infrastructure.Data.SeedData.biz_prod_qs_cjbc.json"; + private const string KtpbCtgResource = "F9WebAiTest.Infrastructure.Data.SeedData.biz_prod_qs_ktpb_ctg.json"; + private const string KtpbDcgResource = "F9WebAiTest.Infrastructure.Data.SeedData.biz_prod_qs_ktpb_dcg.json"; + private const string KtpbZbzResource = "F9WebAiTest.Infrastructure.Data.SeedData.biz_prod_qs_ktpb_zbz.json"; private static readonly JsonSerializerOptions JsonOpts = new() { @@ -31,6 +35,10 @@ public static class ProdSeedData { SeedJizuChetai(fsql); SeedChejianBanci(fsql); + // 看台排班(车头工 / 挡车工 / 值班长) + SeedKtpbCtg(fsql); + SeedKtpbDcg(fsql); + SeedKtpbZbz(fsql); } // ==================== 机组车台 ==================== @@ -154,8 +162,161 @@ public static class ProdSeedData } } + // ==================== 车头工看台排班 ==================== + private static void SeedKtpbCtg(IFreeSql fsql) + { + try + { + var items = Load(KtpbCtgResource); + if (items.Count == 0) return; + + var deptMap = BuildDeptMap(fsql); + var empIds = BuildEmpIdSet(fsql); + var existing = fsql.Select().ToList() + .GroupBy(x => (x.DeptId, x.Banci, x.Jizu)) + .ToDictionary(g => g.Key, g => g.First()); + + int added = 0, updated = 0, skipped = 0; + foreach (var item in items) + { + if (!string.IsNullOrWhiteSpace(item.DeletedAt)) { skipped++; continue; } + if (!deptMap.TryGetValue(item.DepId, out var deptId)) { skipped++; continue; } + if (!empIds.Contains(item.Ygid1)) { skipped++; continue; } + + var ygid2 = empIds.Contains(item.Ygid2) ? item.Ygid2 : 0; + var banci = (Prod_Banci_Enum)item.Banci; + var key = (deptId, banci, item.Jizu); + if (existing.TryGetValue(key, out var e)) + { + if (e.Ygid1 != item.Ygid1 || e.Ygid2 != ygid2) + { + e.Ygid1 = item.Ygid1; + e.Ygid2 = ygid2; + fsql.Update().SetSource(e).ExecuteAffrows(); + updated++; + } + } + else + { + fsql.Insert(new KtpbCtg + { + DeptId = deptId, + Banci = banci, + Jizu = item.Jizu, + Ygid1 = item.Ygid1, + Ygid2 = ygid2 + }).ExecuteAffrows(); + added++; + } + } + + Console.WriteLine($"[ProdSeed] 车头工看台排班:来源 {items.Count} 条,新增 {added} 条,更新 {updated} 条,跳过 {skipped} 条"); + } + catch (Exception ex) + { + Console.WriteLine($"[ProdSeed] 车头工看台排班导入跳过:{ex.Message}"); + } + } + + // ==================== 挡车工看台排班 ==================== + private static void SeedKtpbDcg(IFreeSql fsql) + { + try + { + var items = Load(KtpbDcgResource); + if (items.Count == 0) return; + + var deptMap = BuildDeptMap(fsql); + var empIds = BuildEmpIdSet(fsql); + // 已有排班的「车间+班次+机组」整组跳过,避免每次启动重复插入(人工维护的排班不被覆盖) + var existGroups = fsql.Select().ToList() + .Select(x => (x.DeptId, x.Banci, x.Jizu)) + .ToHashSet(); + + int added = 0, skipped = 0; + var handledGroups = new HashSet<(long, Prod_Banci_Enum, int)>(); + + foreach (var item in items) + { + if (!string.IsNullOrWhiteSpace(item.DeletedAt)) { skipped++; continue; } + if (!deptMap.TryGetValue(item.DepId, out var deptId)) { skipped++; continue; } + if (!empIds.Contains(item.YgId)) { skipped++; continue; } + if (item.ChetaiStart <= 0 || item.ChetaiEnd < item.ChetaiStart) { skipped++; continue; } + + var banci = (Prod_Banci_Enum)item.Banci; + var group = (deptId, banci, item.Jizu); + if (existGroups.Contains(group)) { skipped++; continue; } + + fsql.Insert(new KtpbDcg + { + DeptId = deptId, + Banci = banci, + Jizu = item.Jizu, + ChetaiStart = item.ChetaiStart, + ChetaiEnd = item.ChetaiEnd, + YgId = item.YgId, + Dangcheshu = item.Dangcheshu + }).ExecuteAffrows(); + handledGroups.Add(group); + added++; + } + + Console.WriteLine($"[ProdSeed] 挡车工看台排班:来源 {items.Count} 条,新增 {added} 条({handledGroups.Count} 组),跳过 {skipped} 条"); + } + catch (Exception ex) + { + Console.WriteLine($"[ProdSeed] 挡车工看台排班导入跳过:{ex.Message}"); + } + } + + // ==================== 值班长看台排班 ==================== + private static void SeedKtpbZbz(IFreeSql fsql) + { + try + { + var items = Load(KtpbZbzResource); + if (items.Count == 0) return; + + var deptMap = BuildDeptMap(fsql); + var empIds = BuildEmpIdSet(fsql); + var exist = fsql.Select().ToList() + .Select(x => (x.DeptId, x.Banci, x.YgId)) + .ToHashSet(); + + int added = 0, skipped = 0; + foreach (var item in items) + { + if (!string.IsNullOrWhiteSpace(item.DeletedAt)) { skipped++; continue; } + if (!deptMap.TryGetValue(item.DepId, out var deptId)) { skipped++; continue; } + if (!empIds.Contains(item.YgId)) { skipped++; continue; } + + var banci = (Prod_Banci_Enum)item.Banci; + if (!exist.Add((deptId, banci, item.YgId))) { skipped++; continue; } + + fsql.Insert(new KtpbZbz + { + DeptId = deptId, + Banci = banci, + YgId = item.YgId + }).ExecuteAffrows(); + added++; + } + + Console.WriteLine($"[ProdSeed] 值班长看台排班:来源 {items.Count} 条,新增 {added} 条,跳过 {skipped} 条"); + } + catch (Exception ex) + { + Console.WriteLine($"[ProdSeed] 值班长看台排班导入跳过:{ex.Message}"); + } + } + // ==================== 公共 ==================== + /// 本系统存在的职工 Id 集合(F9 职工导出时保留了原始雪花 Id,可直接比对) + private static HashSet BuildEmpIdSet(IFreeSql fsql) + => fsql.Select().ToList().Select(e => e.Id).ToHashSet(); + + /// 建立 F9 部门 Id → 本系统部门 Id 的映射(以部门名称为桥梁) private static Dictionary BuildDeptMap(IFreeSql fsql) { @@ -199,4 +360,37 @@ public static class ProdSeedData [JsonPropertyName("banci")] public int Banci { get; set; } [JsonPropertyName("kaoqin_dayhours")] public double KaoqinDayhours { get; set; } } + + private class KtpbCtgItem + { + [JsonPropertyName("id")] public long Id { get; set; } + [JsonPropertyName("deleted_at")] public string? DeletedAt { get; set; } + [JsonPropertyName("dep_id")] public long DepId { get; set; } + [JsonPropertyName("banci")] public int Banci { get; set; } + [JsonPropertyName("jizu")] public int Jizu { get; set; } + [JsonPropertyName("ygid_1")] public long Ygid1 { get; set; } + [JsonPropertyName("ygid_2")] public long Ygid2 { get; set; } + } + + private class KtpbDcgItem + { + [JsonPropertyName("id")] public long Id { get; set; } + [JsonPropertyName("deleted_at")] public string? DeletedAt { get; set; } + [JsonPropertyName("dep_id")] public long DepId { get; set; } + [JsonPropertyName("banci")] public int Banci { get; set; } + [JsonPropertyName("jizu")] public int Jizu { get; set; } + [JsonPropertyName("chetai_start")] public int ChetaiStart { get; set; } + [JsonPropertyName("chetai_end")] public int ChetaiEnd { get; set; } + [JsonPropertyName("yg_id")] public long YgId { get; set; } + [JsonPropertyName("dangcheshu")] public double Dangcheshu { get; set; } + } + + private class KtpbZbzItem + { + [JsonPropertyName("id")] public long Id { get; set; } + [JsonPropertyName("deleted_at")] public string? DeletedAt { get; set; } + [JsonPropertyName("dep_id")] public long DepId { get; set; } + [JsonPropertyName("banci")] public int Banci { get; set; } + [JsonPropertyName("yg_id")] public long YgId { get; set; } + } } diff --git a/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_jzct.json b/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_jzct.json index 7dbbf0f..67fda88 100644 --- a/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_jzct.json +++ b/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_jzct.json @@ -1,422 +1,26 @@ [ - { - "id": 16003469039112192, - "created_by": null, - "created_at": "14/11/2025 11:52:04.367", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "14/11/2025 11:53:55.33", - "dep_id": 101122, - "jizu": 23424, - "chetai_start": 324, - "chetai_end": 2342 - }, - { - "id": 16047842267238400, - "created_by": null, - "created_at": "14/11/2025 14:48:23.753", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "14/11/2025 15:26:50.25", - "dep_id": 106, - "jizu": 111, - "chetai_start": 111, - "chetai_end": 118 - }, - { - "id": 16047909204135936, - "created_by": null, - "created_at": "14/11/2025 14:48:39.71", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "14/11/2025 14:48:48.147", - "dep_id": 107, - "jizu": 111, - "chetai_start": 119, - "chetai_end": 125 - }, - { - "id": 16054811803783168, - "created_by": null, - "created_at": "14/11/2025 15:16:05.42", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "14/11/2025 15:26:47.48", - "dep_id": 107, - "jizu": 100, - "chetai_start": 100, - "chetai_end": 110 - }, - { - "id": 17090359817408512, - "created_by": null, - "created_at": "17/11/2025 11:50:59.307", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "20/11/2025 17:47:04.083", - "dep_id": 16047387197837312, - "jizu": 7, - "chetai_start": 3, - "chetai_end": 6 - }, - { - "id": 17124677390438400, - "created_by": null, - "created_at": "17/11/2025 14:07:21.253", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "17/11/2025 15:44:43.493", - "dep_id": 16043931070369792, - "jizu": 1, - "chetai_start": 1, - "chetai_end": 3 - }, - { - "id": 17149134003769344, - "created_by": null, - "created_at": "17/11/2025 15:44:32.167", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "20/11/2025 17:47:08.097", - "dep_id": 16043931070369792, - "jizu": 100, - "chetai_start": 5, - "chetai_end": 11 - }, - { - "id": 17895860616564736, - "created_by": null, - "created_at": "19/11/2025 17:11:45.693", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "20/11/2025 17:47:05.973", - "dep_id": 16047387197837312, - "jizu": 1, - "chetai_start": 1, - "chetai_end": 18 - }, - { - "id": 18267185730293760, - "created_by": null, - "created_at": "20/11/2025 17:47:16.487", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16043931070369792, - "jizu": 1, - "chetai_start": 1, - "chetai_end": 20 - }, - { - "id": 18267223122513920, - "created_by": null, - "created_at": "20/11/2025 17:47:25.383", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16043931070369792, - "jizu": 2, - "chetai_start": 21, - "chetai_end": 40 - }, - { - "id": 18267258883149824, - "created_by": null, - "created_at": "20/11/2025 17:47:33.907", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16043931070369792, - "jizu": 3, - "chetai_start": 41, - "chetai_end": 60 - }, - { - "id": 18267293058338816, - "created_by": null, - "created_at": "20/11/2025 17:47:42.057", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16043931070369792, - "jizu": 4, - "chetai_start": 61, - "chetai_end": 80 - }, - { - "id": 18267333134913536, - "created_by": null, - "created_at": "20/11/2025 17:47:51.61", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16043931070369792, - "jizu": 5, - "chetai_start": 81, - "chetai_end": 100 - }, - { - "id": 18267372687200256, - "created_by": null, - "created_at": "20/11/2025 17:48:01.04", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16043931070369792, - "jizu": 6, - "chetai_start": 101, - "chetai_end": 120 - }, - { - "id": 18267414189838336, - "created_by": null, - "created_at": "20/11/2025 17:48:10.937", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16047387197837312, - "jizu": 1, - "chetai_start": 1, - "chetai_end": 20 - }, - { - "id": 18267443470274560, - "created_by": null, - "created_at": "20/11/2025 17:48:17.917", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16047387197837312, - "jizu": 2, - "chetai_start": 21, - "chetai_end": 40 - }, - { - "id": 18267488391270400, - "created_by": null, - "created_at": "20/11/2025 17:48:28.627", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16047387197837312, - "jizu": 3, - "chetai_start": 41, - "chetai_end": 60 - }, - { - "id": 18267530309144576, - "created_by": null, - "created_at": "20/11/2025 17:48:38.62", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16047387197837312, - "jizu": 4, - "chetai_start": 61, - "chetai_end": 80 - }, - { - "id": 18267562336849920, - "created_by": null, - "created_at": "20/11/2025 17:48:46.257", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16047387197837312, - "jizu": 5, - "chetai_start": 81, - "chetai_end": 100 - }, - { - "id": 18267593483751424, - "created_by": null, - "created_at": "20/11/2025 17:48:53.683", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 16047387197837312, - "jizu": 6, - "chetai_start": 101, - "chetai_end": 120 - }, - { - "id": 18500840679542784, - "created_by": null, - "created_at": "21/11/2025 09:15:44.15", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "24/11/2025 14:30:02.643", - "dep_id": 16043931070369792, - "jizu": 1, - "chetai_start": 1, - "chetai_end": 100 - }, - { - "id": 20436938137800704, - "created_by": null, - "created_at": "26/11/2025 17:29:05.753", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "10/12/2025 13:06:18.217", - "dep_id": 16047387197837312, - "jizu": 7, - "chetai_start": 121, - "chetai_end": 140 - }, - { - "id": 25444260044083200, - "created_by": "余华", - "created_at": "10/12/2025 13:06:24.337", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308600831545344, - "jizu": 1, - "chetai_start": 1, - "chetai_end": 20 - }, - { - "id": 25444289462931456, - "created_by": "余华", - "created_at": "10/12/2025 13:06:31.34", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308600831545344, - "jizu": 2, - "chetai_start": 21, - "chetai_end": 40 - }, - { - "id": 25444329623392256, - "created_by": "余华", - "created_at": "10/12/2025 13:06:40.917", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308600831545344, - "jizu": 3, - "chetai_start": 41, - "chetai_end": 60 - }, - { - "id": 25444371641929728, - "created_by": "余华", - "created_at": "10/12/2025 13:06:50.933", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308600831545344, - "jizu": 4, - "chetai_start": 61, - "chetai_end": 80 - }, - { - "id": 25444402046439424, - "created_by": "余华", - "created_at": "10/12/2025 13:06:58.183", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308600831545344, - "jizu": 5, - "chetai_start": 81, - "chetai_end": 100 - }, - { - "id": 25444430567706624, - "created_by": "余华", - "created_at": "10/12/2025 13:07:04.983", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308600831545344, - "jizu": 6, - "chetai_start": 101, - "chetai_end": 120 - }, - { - "id": 25444457453195264, - "created_by": "余华", - "created_at": "10/12/2025 13:07:11.393", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308683820044288, - "jizu": 1, - "chetai_start": 1, - "chetai_end": 20 - }, - { - "id": 25444480718999552, - "created_by": "余华", - "created_at": "10/12/2025 13:07:16.94", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308683820044288, - "jizu": 2, - "chetai_start": 21, - "chetai_end": 40 - }, - { - "id": 25444507617071104, - "created_by": "余华", - "created_at": "10/12/2025 13:07:23.353", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308683820044288, - "jizu": 3, - "chetai_start": 41, - "chetai_end": 60 - }, - { - "id": 25444531084201984, - "created_by": "余华", - "created_at": "10/12/2025 13:07:28.947", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308683820044288, - "jizu": 4, - "chetai_start": 61, - "chetai_end": 80 - }, - { - "id": 25444554995929088, - "created_by": "余华", - "created_at": "10/12/2025 13:07:34.65", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308683820044288, - "jizu": 5, - "chetai_start": 81, - "chetai_end": 100 - }, - { - "id": 25444577833914368, - "created_by": "余华", - "created_at": "10/12/2025 13:07:40.093", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": null, - "dep_id": 22308683820044288, - "jizu": 6, - "chetai_start": 101, - "chetai_end": 120 - }, - { - "id": 37410963145625600, - "created_by": "余华", - "created_at": "12/1/2026 13:37:48.69", - "update_by": null, - "updated_at": "1/1/1970 00:00:00", - "deleted_at": "13/2/2026 13:59:24.617", - "dep_id": 22308683820044288, - "jizu": -1, - "chetai_start": 0, - "chetai_end": 0 - } -] \ No newline at end of file + {"id":18267185730293760,"deleted_at":null,"dep_id":16043931070369792,"jizu":1,"chetai_start":1,"chetai_end":20}, + {"id":18267223122513920,"deleted_at":null,"dep_id":16043931070369792,"jizu":2,"chetai_start":21,"chetai_end":40}, + {"id":18267258883149824,"deleted_at":null,"dep_id":16043931070369792,"jizu":3,"chetai_start":41,"chetai_end":60}, + {"id":18267293058338816,"deleted_at":null,"dep_id":16043931070369792,"jizu":4,"chetai_start":61,"chetai_end":80}, + {"id":18267333134913536,"deleted_at":null,"dep_id":16043931070369792,"jizu":5,"chetai_start":81,"chetai_end":100}, + {"id":18267372687200256,"deleted_at":null,"dep_id":16043931070369792,"jizu":6,"chetai_start":101,"chetai_end":120}, + {"id":18267414189838336,"deleted_at":null,"dep_id":16047387197837312,"jizu":1,"chetai_start":1,"chetai_end":20}, + {"id":18267443470274560,"deleted_at":null,"dep_id":16047387197837312,"jizu":2,"chetai_start":21,"chetai_end":40}, + {"id":18267488391270400,"deleted_at":null,"dep_id":16047387197837312,"jizu":3,"chetai_start":41,"chetai_end":60}, + {"id":18267530309144576,"deleted_at":null,"dep_id":16047387197837312,"jizu":4,"chetai_start":61,"chetai_end":80}, + {"id":18267562336849920,"deleted_at":null,"dep_id":16047387197837312,"jizu":5,"chetai_start":81,"chetai_end":100}, + {"id":18267593483751424,"deleted_at":null,"dep_id":16047387197837312,"jizu":6,"chetai_start":101,"chetai_end":120}, + {"id":25444260044083200,"deleted_at":null,"dep_id":22308600831545344,"jizu":1,"chetai_start":1,"chetai_end":20}, + {"id":25444289462931456,"deleted_at":null,"dep_id":22308600831545344,"jizu":2,"chetai_start":21,"chetai_end":40}, + {"id":25444329623392256,"deleted_at":null,"dep_id":22308600831545344,"jizu":3,"chetai_start":41,"chetai_end":60}, + {"id":25444371641929728,"deleted_at":null,"dep_id":22308600831545344,"jizu":4,"chetai_start":61,"chetai_end":80}, + {"id":25444402046439424,"deleted_at":null,"dep_id":22308600831545344,"jizu":5,"chetai_start":81,"chetai_end":100}, + {"id":25444430567706624,"deleted_at":null,"dep_id":22308600831545344,"jizu":6,"chetai_start":101,"chetai_end":120}, + {"id":25444457453195264,"deleted_at":null,"dep_id":22308683820044288,"jizu":1,"chetai_start":1,"chetai_end":20}, + {"id":25444480718999552,"deleted_at":null,"dep_id":22308683820044288,"jizu":2,"chetai_start":21,"chetai_end":40}, + {"id":25444507617071104,"deleted_at":null,"dep_id":22308683820044288,"jizu":3,"chetai_start":41,"chetai_end":60}, + {"id":25444531084201984,"deleted_at":null,"dep_id":22308683820044288,"jizu":4,"chetai_start":61,"chetai_end":80}, + {"id":25444554995929088,"deleted_at":null,"dep_id":22308683820044288,"jizu":5,"chetai_start":81,"chetai_end":100}, + {"id":25444577833914368,"deleted_at":null,"dep_id":22308683820044288,"jizu":6,"chetai_start":101,"chetai_end":120} +] diff --git a/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_ctg.json b/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_ctg.json new file mode 100644 index 0000000..e22f8c6 --- /dev/null +++ b/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_ctg.json @@ -0,0 +1,35 @@ +[ + {"id":28679759856668672,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":1,"ygid_1":25394251403628544,"ygid_2":25394252687085568}, + {"id":28679881613119488,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":2,"ygid_1":25394250963226624,"ygid_2":25394262359150592}, + {"id":28680097309396992,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":4,"ygid_1":25394277458644992,"ygid_2":25394289907339264}, + {"id":28680552307494912,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":2,"ygid_1":25394262090715136,"ygid_2":25394283020292096}, + {"id":28680630204108800,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":3,"ygid_1":25394270579986432,"ygid_2":25394277022437376}, + {"id":28680704229380096,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":4,"ygid_1":25394267270680576,"ygid_2":25394252900995072}, + {"id":28680809309278208,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":5,"ygid_1":25394253106515968,"ygid_2":25394287445282816}, + {"id":28680902095671296,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":6,"ygid_1":25394255677624320,"ygid_2":25394257221128192}, + {"id":28681049068277760,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":1,"ygid_1":25394255895728128,"ygid_2":25394256793309184}, + {"id":28681224268550144,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":2,"ygid_1":25394271423041536,"ygid_2":25394275898363904}, + {"id":28681355063726080,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":3,"ygid_1":25394256373878784,"ygid_2":25394258567499776}, + {"id":28681491718344704,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":4,"ygid_1":25394254591299584,"ygid_2":25394268763852800}, + {"id":28681656072146944,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":5,"ygid_1":25394257665724416,"ygid_2":25394262770192384}, + {"id":28681864378060800,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":6,"ygid_1":25394271871832064,"ygid_2":25394298862178304}, + {"id":32345734678319104,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":1,"ygid_1":25394253521752064,"ygid_2":25394263684550656}, + {"id":56622802173693952,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":2,"ygid_1":25394269191671808,"ygid_2":25394322589356032}, + {"id":56622892196040704,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":3,"ygid_1":25394266616369152,"ygid_2":25394277928407040}, + {"id":56623050757509120,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":4,"ygid_1":25394267681722368,"ygid_2":25394272979128320}, + {"id":56623178239184896,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":5,"ygid_1":25394317203869696,"ygid_2":25394331179290624}, + {"id":76302819312799744,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":3,"ygid_1":25394318558629888,"ygid_2":25394285343936512}, + {"id":76303037706014720,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":6,"ygid_1":25394277232152576,"ygid_2":25394292637831168}, + {"id":93614566272929792,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":2,"ygid_1":93227931605667840,"ygid_2":25394275269218304}, + {"id":93614668416815104,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":3,"ygid_1":93224498219716608,"ygid_2":93590450325164032}, + {"id":93614844455948288,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":4,"ygid_1":93224782811631616,"ygid_2":93225053415542784}, + {"id":93624586561654784,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":1,"ygid_1":25394252687085568,"ygid_2":25394298644074496}, + {"id":93624684989386752,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":2,"ygid_1":25394252473176064,"ygid_2":25394352024981504}, + {"id":93624758398095360,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":3,"ygid_1":25394313286389760,"ygid_2":25394334945775616}, + {"id":93624861590556672,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":4,"ygid_1":25394261000196096,"ygid_2":25394320357986304}, + {"id":93624972055941120,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":5,"ygid_1":25394301747859456,"ygid_2":25394321599500288}, + {"id":93625060534784000,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":6,"ygid_1":25394318810288128,"ygid_2":25394343514738688}, + {"id":120347729640558592,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"ygid_1":93225232566849536,"ygid_2":93590965738016768}, + {"id":120348037049487360,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"ygid_1":93225456668512256,"ygid_2":25394269623685120}, + {"id":121079483326271488,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":1,"ygid_1":93226261979074560,"ygid_2":93225788580564992} +] diff --git a/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_dcg.json b/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_dcg.json new file mode 100644 index 0000000..883c925 --- /dev/null +++ b/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_dcg.json @@ -0,0 +1,204 @@ +[ + {"id":120344961106317312,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":1,"chetai_start":1,"chetai_end":4,"yg_id":89529295612940288,"dangcheshu":3.5}, + {"id":120344961139871744,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":1,"chetai_start":4,"chetai_end":7,"yg_id":93233888171659264,"dangcheshu":3.5}, + {"id":120344961156648960,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":1,"chetai_start":8,"chetai_end":10,"yg_id":87098603226533888,"dangcheshu":3}, + {"id":120344961173426176,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":1,"chetai_start":11,"chetai_end":14,"yg_id":93241010255040512,"dangcheshu":3.5}, + {"id":120344961190203392,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":1,"chetai_start":14,"chetai_end":17,"yg_id":93233703257378816,"dangcheshu":3.5}, + {"id":120344961206980608,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":1,"chetai_start":18,"chetai_end":20,"yg_id":93237556027592704,"dangcheshu":3}, + {"id":120389028775202816,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":1,"chetai_start":1,"chetai_end":4,"yg_id":25394323948310528,"dangcheshu":3.5}, + {"id":120389028812951552,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":1,"chetai_start":4,"chetai_end":7,"yg_id":25394323277221888,"dangcheshu":3.5}, + {"id":120389028833923072,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":1,"chetai_start":8,"chetai_end":10,"yg_id":25394286870663168,"dangcheshu":3}, + {"id":120389028859088896,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":1,"chetai_start":11,"chetai_end":14,"yg_id":25394273205620736,"dangcheshu":3.5}, + {"id":120389028880060416,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":1,"chetai_start":14,"chetai_end":17,"yg_id":25394307603107840,"dangcheshu":3.5}, + {"id":120389028901031936,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":1,"chetai_start":18,"chetai_end":20,"yg_id":25394291484397568,"dangcheshu":3}, + {"id":120389304567468032,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":2,"chetai_start":21,"chetai_end":24,"yg_id":25394274388414464,"dangcheshu":3.5}, + {"id":120389304592633856,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":2,"chetai_start":24,"chetai_end":27,"yg_id":25394292184846336,"dangcheshu":3.5}, + {"id":120389304609411072,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":2,"chetai_start":28,"chetai_end":30,"yg_id":25394272094130176,"dangcheshu":3}, + {"id":120389304626188288,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":2,"chetai_start":31,"chetai_end":34,"yg_id":25394354193436672,"dangcheshu":3.5}, + {"id":120389304638771200,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":2,"chetai_start":34,"chetai_end":37,"yg_id":25394302033072128,"dangcheshu":3.5}, + {"id":120389304655548416,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":2,"chetai_start":38,"chetai_end":40,"yg_id":25394303777902592,"dangcheshu":3}, + {"id":120389564396212224,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":3,"chetai_start":41,"chetai_end":44,"yg_id":25394273868320768,"dangcheshu":3.5}, + {"id":120389564429766656,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":3,"chetai_start":44,"chetai_end":47,"yg_id":25394300577648640,"dangcheshu":3.5}, + {"id":120389564446543872,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":3,"chetai_start":48,"chetai_end":50,"yg_id":25394307166900224,"dangcheshu":3}, + {"id":120389564463321088,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":3,"chetai_start":51,"chetai_end":54,"yg_id":25394267904020480,"dangcheshu":3.5}, + {"id":120389564480098304,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":3,"chetai_start":54,"chetai_end":57,"yg_id":25394309872226304,"dangcheshu":3.5}, + {"id":120389564496875520,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":3,"chetai_start":58,"chetai_end":60,"yg_id":25394309482156032,"dangcheshu":3}, + {"id":120389903656685568,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":4,"chetai_start":61,"chetai_end":64,"yg_id":25394308739764224,"dangcheshu":3.5}, + {"id":120389903681851392,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":4,"chetai_start":64,"chetai_end":67,"yg_id":25394330747277312,"dangcheshu":3.5}, + {"id":120389903698628608,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":4,"chetai_start":68,"chetai_end":70,"yg_id":25394326401978368,"dangcheshu":3}, + {"id":120389903715405824,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":4,"chetai_start":71,"chetai_end":74,"yg_id":25394294764343296,"dangcheshu":3.5}, + {"id":120389903732183040,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":4,"chetai_start":74,"chetai_end":77,"yg_id":55117587129831424,"dangcheshu":3.5}, + {"id":120389903748960256,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":4,"chetai_start":78,"chetai_end":80,"yg_id":25394285914361856,"dangcheshu":3}, + {"id":120390213137600512,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":5,"chetai_start":81,"chetai_end":84,"yg_id":25394264351444992,"dangcheshu":3.5}, + {"id":120390213166960640,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":5,"chetai_start":84,"chetai_end":87,"yg_id":25394303547215872,"dangcheshu":3.5}, + {"id":120390213183737856,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":5,"chetai_start":88,"chetai_end":90,"yg_id":25394324619399168,"dangcheshu":3}, + {"id":120390213204709376,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":5,"chetai_start":91,"chetai_end":94,"yg_id":56616898418184192,"dangcheshu":3.5}, + {"id":120390213221486592,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":5,"chetai_start":94,"chetai_end":97,"yg_id":25394335637835776,"dangcheshu":3.5}, + {"id":120390213238263808,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":5,"chetai_start":98,"chetai_end":100,"yg_id":25394308521660416,"dangcheshu":3}, + {"id":120404584362414080,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":1,"chetai_start":1,"chetai_end":4,"yg_id":25394312703381504,"dangcheshu":3.5}, + {"id":120404584391774208,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":1,"chetai_start":4,"chetai_end":7,"yg_id":25394315442262016,"dangcheshu":3.5}, + {"id":120404584408551424,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":1,"chetai_start":8,"chetai_end":10,"yg_id":25394305950552064,"dangcheshu":3}, + {"id":120404584425328640,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":1,"chetai_start":11,"chetai_end":14,"yg_id":25394326620082176,"dangcheshu":3.5}, + {"id":120404584442105856,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":1,"chetai_start":14,"chetai_end":17,"yg_id":25394299948503040,"dangcheshu":3.5}, + {"id":120404584458883072,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":1,"chetai_start":18,"chetai_end":20,"yg_id":25394311185043456,"dangcheshu":3}, + {"id":120411788704485376,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":1,"chetai_start":1,"chetai_end":4,"yg_id":25394278435917824,"dangcheshu":3.5}, + {"id":120411788729651200,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":1,"chetai_start":4,"chetai_end":7,"yg_id":25394306164461568,"dangcheshu":3.5}, + {"id":120411788742234112,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":1,"chetai_start":8,"chetai_end":10,"yg_id":25394335184850944,"dangcheshu":3}, + {"id":120411788759011328,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":1,"chetai_start":11,"chetai_end":14,"yg_id":25394254381584384,"dangcheshu":3.5}, + {"id":120411788775788544,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":1,"chetai_start":14,"chetai_end":17,"yg_id":25394264573743104,"dangcheshu":3.5}, + {"id":120411788792565760,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":1,"chetai_start":18,"chetai_end":20,"yg_id":25394261629341696,"dangcheshu":3}, + {"id":120413456527527936,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":3,"chetai_start":41,"chetai_end":45,"yg_id":25394325974159360,"dangcheshu":5}, + {"id":120413456552693760,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":3,"chetai_start":46,"chetai_end":50,"yg_id":25394257451814912,"dangcheshu":5}, + {"id":120413456569470976,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":3,"chetai_start":51,"chetai_end":55,"yg_id":25394253316231168,"dangcheshu":5}, + {"id":120413456586248192,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":3,"chetai_start":56,"chetai_end":60,"yg_id":25394259884511232,"dangcheshu":5}, + {"id":120414505472626688,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":5,"chetai_start":81,"chetai_end":85,"yg_id":25394284488298496,"dangcheshu":5}, + {"id":120414505501986816,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":5,"chetai_start":86,"chetai_end":90,"yg_id":25394258324230144,"dangcheshu":5}, + {"id":120414505518764032,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":5,"chetai_start":91,"chetai_end":95,"yg_id":25394308257419264,"dangcheshu":5}, + {"id":120414505531346944,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":5,"chetai_start":96,"chetai_end":100,"yg_id":25394265102225408,"dangcheshu":5}, + {"id":120415064866951168,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":6,"chetai_start":101,"chetai_end":104,"yg_id":25394267052576768,"dangcheshu":3.5}, + {"id":120415064887922688,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":6,"chetai_start":104,"chetai_end":107,"yg_id":25394265983029248,"dangcheshu":3.5}, + {"id":120415064908894208,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":6,"chetai_start":108,"chetai_end":110,"yg_id":25394300376322048,"dangcheshu":3}, + {"id":120415064925671424,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":6,"chetai_start":111,"chetai_end":114,"yg_id":25394315178020864,"dangcheshu":3.5}, + {"id":120415064942448640,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":6,"chetai_start":114,"chetai_end":117,"yg_id":25394333142224896,"dangcheshu":3.5}, + {"id":120415064959225856,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":6,"chetai_start":118,"chetai_end":120,"yg_id":25394308953673728,"dangcheshu":3}, + {"id":120415827617910784,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":4,"chetai_start":61,"chetai_end":64,"yg_id":25394276531703808,"dangcheshu":3.5}, + {"id":120415827634688000,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":4,"chetai_start":64,"chetai_end":67,"yg_id":25394328620765184,"dangcheshu":3.5}, + {"id":120415827651465216,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":4,"chetai_start":68,"chetai_end":70,"yg_id":25394277718691840,"dangcheshu":3}, + {"id":120415827668242432,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":4,"chetai_start":71,"chetai_end":74,"yg_id":25394338246692864,"dangcheshu":3.5}, + {"id":120415827685019648,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":4,"chetai_start":74,"chetai_end":77,"yg_id":25394316000104448,"dangcheshu":3.5}, + {"id":120415827705991168,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":4,"chetai_start":78,"chetai_end":80,"yg_id":25394288552579072,"dangcheshu":3}, + {"id":120416422688985088,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":2,"chetai_start":21,"chetai_end":24,"yg_id":25394273654411264,"dangcheshu":3.5}, + {"id":120416422701568000,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":2,"chetai_start":24,"chetai_end":27,"yg_id":25394288808431616,"dangcheshu":3.5}, + {"id":120416422705762304,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":2,"chetai_start":28,"chetai_end":30,"yg_id":25394260790480896,"dangcheshu":3}, + {"id":120416422718345216,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":2,"chetai_start":31,"chetai_end":34,"yg_id":25394336363450368,"dangcheshu":3.5}, + {"id":120416422726733824,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":2,"chetai_start":34,"chetai_end":37,"yg_id":25394280528875520,"dangcheshu":3.5}, + {"id":120416422735122432,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"jizu":2,"chetai_start":38,"chetai_end":40,"yg_id":25394293594132480,"dangcheshu":3}, + {"id":120544922305564672,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":5,"chetai_start":81,"chetai_end":85,"yg_id":25394323059118080,"dangcheshu":5}, + {"id":120544922322341888,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":5,"chetai_start":86,"chetai_end":90,"yg_id":25394253727272960,"dangcheshu":5}, + {"id":120544922339119104,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":5,"chetai_start":91,"chetai_end":95,"yg_id":25394255010729984,"dangcheshu":5}, + {"id":120544922355896320,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":5,"chetai_start":96,"chetai_end":100,"yg_id":25394284916117504,"dangcheshu":5}, + {"id":120545630580903936,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":6,"chetai_start":101,"chetai_end":104,"yg_id":25394268558331904,"dangcheshu":3.5}, + {"id":120545630606069760,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":6,"chetai_start":104,"chetai_end":107,"yg_id":25394273444696064,"dangcheshu":3.5}, + {"id":120545630622846976,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":6,"chetai_start":108,"chetai_end":110,"yg_id":25394336074043392,"dangcheshu":3}, + {"id":120545630639624192,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":6,"chetai_start":111,"chetai_end":114,"yg_id":25394343724453888,"dangcheshu":3.5}, + {"id":120545630656401408,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":6,"chetai_start":114,"chetai_end":117,"yg_id":25394294344912896,"dangcheshu":3.5}, + {"id":120545630668984320,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":6,"chetai_start":118,"chetai_end":120,"yg_id":25394282781216768,"dangcheshu":3}, + {"id":121885127797116928,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":2,"chetai_start":21,"chetai_end":24,"yg_id":25394320131493888,"dangcheshu":3.5}, + {"id":121885127826477056,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":2,"chetai_start":24,"chetai_end":27,"yg_id":25394353119694848,"dangcheshu":3.5}, + {"id":121885127843254272,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":2,"chetai_start":28,"chetai_end":30,"yg_id":25394331602915328,"dangcheshu":3}, + {"id":121885127860031488,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":2,"chetai_start":31,"chetai_end":34,"yg_id":102725859500101632,"dangcheshu":3.5}, + {"id":121885127876808704,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":2,"chetai_start":34,"chetai_end":37,"yg_id":25394321809215488,"dangcheshu":3.5}, + {"id":121885127893585920,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":2,"chetai_start":38,"chetai_end":40,"yg_id":25394352679292928,"dangcheshu":3}, + {"id":121885246168764416,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":3,"chetai_start":41,"chetai_end":44,"yg_id":58023703778168832,"dangcheshu":3.5}, + {"id":121885246189735936,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":3,"chetai_start":44,"chetai_end":47,"yg_id":25394345465090048,"dangcheshu":3.5}, + {"id":121885246202318848,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":3,"chetai_start":48,"chetai_end":50,"yg_id":25394310325211136,"dangcheshu":3}, + {"id":121885246219096064,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":3,"chetai_start":51,"chetai_end":54,"yg_id":57706516936921088,"dangcheshu":3.5}, + {"id":121885246235873280,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":3,"chetai_start":54,"chetai_end":57,"yg_id":36260154701778944,"dangcheshu":3.5}, + {"id":121885246252650496,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":3,"chetai_start":58,"chetai_end":60,"yg_id":89158837713506304,"dangcheshu":3}, + {"id":121885553049210880,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":3,"chetai_start":41,"chetai_end":44,"yg_id":25394298417582080,"dangcheshu":3.5}, + {"id":121885553074376704,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":3,"chetai_start":44,"chetai_end":47,"yg_id":25394331879739392,"dangcheshu":3.5}, + {"id":121885553086959616,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":3,"chetai_start":48,"chetai_end":50,"yg_id":25394332085260288,"dangcheshu":3}, + {"id":121885553107931136,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":3,"chetai_start":51,"chetai_end":54,"yg_id":25394322836819968,"dangcheshu":3.5}, + {"id":121885553124708352,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":3,"chetai_start":54,"chetai_end":57,"yg_id":25394343061753856,"dangcheshu":3.5}, + {"id":121885553145679872,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":3,"chetai_start":58,"chetai_end":60,"yg_id":25394287898267648,"dangcheshu":3}, + {"id":121885819202965504,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":4,"chetai_start":61,"chetai_end":64,"yg_id":25394336598331392,"dangcheshu":3.5}, + {"id":121885819228131328,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":4,"chetai_start":64,"chetai_end":67,"yg_id":25394343292440576,"dangcheshu":3.5}, + {"id":121885819244908544,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":4,"chetai_start":68,"chetai_end":70,"yg_id":25394351068680192,"dangcheshu":3}, + {"id":121885819270074368,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":4,"chetai_start":71,"chetai_end":74,"yg_id":25394331397394432,"dangcheshu":3.5}, + {"id":121885819291045888,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":4,"chetai_start":74,"chetai_end":77,"yg_id":25394308014149632,"dangcheshu":3.5}, + {"id":121885819312017408,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":4,"chetai_start":78,"chetai_end":80,"yg_id":25394351525859328,"dangcheshu":3}, + {"id":121885952749604864,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":5,"chetai_start":81,"chetai_end":84,"yg_id":25394342315167744,"dangcheshu":3.5}, + {"id":121885952774770688,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":5,"chetai_start":84,"chetai_end":87,"yg_id":25394307397586944,"dangcheshu":3.5}, + {"id":121885952791547904,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":5,"chetai_start":88,"chetai_end":90,"yg_id":25394348786978816,"dangcheshu":3}, + {"id":121885952812519424,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":5,"chetai_start":91,"chetai_end":94,"yg_id":25394310102913024,"dangcheshu":3.5}, + {"id":121885952829296640,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":5,"chetai_start":94,"chetai_end":97,"yg_id":75481403743014912,"dangcheshu":3.5}, + {"id":121885952846073856,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":5,"chetai_start":98,"chetai_end":100,"yg_id":25394310966939648,"dangcheshu":3}, + {"id":121886067652562944,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":6,"chetai_start":101,"chetai_end":104,"yg_id":25394251827253248,"dangcheshu":3.5}, + {"id":121886067673534464,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":6,"chetai_start":104,"chetai_end":107,"yg_id":25394340423536640,"dangcheshu":3.5}, + {"id":121886067690311680,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":6,"chetai_start":108,"chetai_end":110,"yg_id":25394301508784128,"dangcheshu":3}, + {"id":121886067707088896,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":6,"chetai_start":111,"chetai_end":114,"yg_id":25394313785511936,"dangcheshu":3.5}, + {"id":121886067723866112,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":6,"chetai_start":114,"chetai_end":117,"yg_id":25394260090032128,"dangcheshu":3.5}, + {"id":121886067740643328,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"jizu":6,"chetai_start":118,"chetai_end":120,"yg_id":25394254805209088,"dangcheshu":3}, + {"id":121887275310125056,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":4,"chetai_start":61,"chetai_end":64,"yg_id":57707023516569600,"dangcheshu":3.5}, + {"id":121887275335290880,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":4,"chetai_start":64,"chetai_end":67,"yg_id":55473100082384896,"dangcheshu":3.5}, + {"id":121887275352068096,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":4,"chetai_start":68,"chetai_end":70,"yg_id":36260136813072384,"dangcheshu":3}, + {"id":121887275368845312,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":4,"chetai_start":71,"chetai_end":74,"yg_id":56619152755920896,"dangcheshu":3.5}, + {"id":121887275385622528,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":4,"chetai_start":74,"chetai_end":77,"yg_id":25394305396903936,"dangcheshu":3.5}, + {"id":121887275402399744,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":4,"chetai_start":78,"chetai_end":80,"yg_id":114291502120701952,"dangcheshu":3}, + {"id":123606871947874304,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":6,"chetai_start":101,"chetai_end":104,"yg_id":84087718895685632,"dangcheshu":3.5}, + {"id":123606871968845824,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":6,"chetai_start":104,"chetai_end":107,"yg_id":88552717080858624,"dangcheshu":3.5}, + {"id":123606871989817344,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":6,"chetai_start":108,"chetai_end":110,"yg_id":93241166341869568,"dangcheshu":3}, + {"id":123606872006594560,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":6,"chetai_start":111,"chetai_end":114,"yg_id":93238232686268416,"dangcheshu":3.5}, + {"id":123606872023371776,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":6,"chetai_start":114,"chetai_end":117,"yg_id":84084713496514560,"dangcheshu":3.5}, + {"id":123606872040148992,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"jizu":6,"chetai_start":118,"chetai_end":120,"yg_id":84089998294388736,"dangcheshu":3}, + {"id":123662101523730432,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":81,"chetai_end":82,"yg_id":111640051850416128,"dangcheshu":2}, + {"id":123662102295482368,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":83,"chetai_end":84,"yg_id":121069184883888128,"dangcheshu":2}, + {"id":123662102370979840,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":85,"chetai_end":86,"yg_id":93228252994211840,"dangcheshu":2}, + {"id":123662102400339968,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":87,"chetai_end":88,"yg_id":93227633852026880,"dangcheshu":2}, + {"id":123662102425505792,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":89,"chetai_end":90,"yg_id":111639830290501632,"dangcheshu":2}, + {"id":123662102442283008,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":91,"chetai_end":92,"yg_id":93227022582550528,"dangcheshu":2}, + {"id":123662102467448832,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":93,"chetai_end":94,"yg_id":111640631461285888,"dangcheshu":2}, + {"id":123662102488420352,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":95,"chetai_end":96,"yg_id":111639603936497664,"dangcheshu":2}, + {"id":123662102509391872,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":97,"chetai_end":98,"yg_id":111640416700338176,"dangcheshu":2}, + {"id":123662102526169088,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":5,"chetai_start":99,"chetai_end":100,"yg_id":111639258053218304,"dangcheshu":2}, + {"id":123696286305095680,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":2,"chetai_start":21,"chetai_end":24,"yg_id":58372032244486144,"dangcheshu":3.5}, + {"id":123696286464479232,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":2,"chetai_start":24,"chetai_end":27,"yg_id":25394319879835648,"dangcheshu":3.5}, + {"id":123696286519005184,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":2,"chetai_start":28,"chetai_end":30,"yg_id":25394312409780224,"dangcheshu":3}, + {"id":123696286539976704,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":2,"chetai_start":31,"chetai_end":34,"yg_id":55473760022564864,"dangcheshu":3.5}, + {"id":123696286560948224,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":2,"chetai_start":34,"chetai_end":37,"yg_id":55471125118849024,"dangcheshu":3.5}, + {"id":123696286569336832,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":2,"chetai_start":38,"chetai_end":40,"yg_id":55462259811422208,"dangcheshu":3}, + {"id":123712008896909312,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":2,"chetai_start":21,"chetai_end":24,"yg_id":25394320567701504,"dangcheshu":3.5}, + {"id":123712008926269440,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":2,"chetai_start":24,"chetai_end":27,"yg_id":25394333368717312,"dangcheshu":3.5}, + {"id":123712008947240960,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":2,"chetai_start":28,"chetai_end":30,"yg_id":25394272303845376,"dangcheshu":3}, + {"id":123712008964018176,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":2,"chetai_start":31,"chetai_end":34,"yg_id":25394288103788544,"dangcheshu":3.5}, + {"id":123712008984989696,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":2,"chetai_start":34,"chetai_end":37,"yg_id":25394274837204992,"dangcheshu":3.5}, + {"id":123712009001766912,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":2,"chetai_start":38,"chetai_end":40,"yg_id":25394346626912256,"dangcheshu":3}, + {"id":123712112307474432,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":3,"chetai_start":41,"chetai_end":44,"yg_id":25394262979907584,"dangcheshu":3.5}, + {"id":123712112332640256,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":3,"chetai_start":44,"chetai_end":47,"yg_id":25394337118425088,"dangcheshu":3.5}, + {"id":123712112353611776,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":3,"chetai_start":48,"chetai_end":50,"yg_id":25394302385393664,"dangcheshu":3}, + {"id":123712112374583296,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":3,"chetai_start":51,"chetai_end":54,"yg_id":25394346350088192,"dangcheshu":3.5}, + {"id":123712112391360512,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":3,"chetai_start":54,"chetai_end":57,"yg_id":25394342852038656,"dangcheshu":3.5}, + {"id":123712112408137728,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":3,"chetai_start":58,"chetai_end":60,"yg_id":25394287084572672,"dangcheshu":3}, + {"id":123715314398531584,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":4,"chetai_start":61,"chetai_end":64,"yg_id":25394316927045632,"dangcheshu":3.5}, + {"id":123715314415308800,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":4,"chetai_start":64,"chetai_end":67,"yg_id":25394330747277312,"dangcheshu":3.5}, + {"id":123715314432086016,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":4,"chetai_start":68,"chetai_end":70,"yg_id":25394323495325696,"dangcheshu":3}, + {"id":123715314444668928,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":4,"chetai_start":71,"chetai_end":74,"yg_id":25394303983423488,"dangcheshu":3.5}, + {"id":123715314457251840,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":4,"chetai_start":74,"chetai_end":77,"yg_id":55117587129831424,"dangcheshu":3.5}, + {"id":123715314465640448,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":4,"chetai_start":78,"chetai_end":80,"yg_id":25394291484397568,"dangcheshu":3}, + {"id":123715494162206720,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":5,"chetai_start":81,"chetai_end":84,"yg_id":25394328411049984,"dangcheshu":3.5}, + {"id":123715494187372544,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":5,"chetai_start":84,"chetai_end":87,"yg_id":25394309238886400,"dangcheshu":3.5}, + {"id":123715494204149760,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":5,"chetai_start":88,"chetai_end":90,"yg_id":25394301273903104,"dangcheshu":3}, + {"id":123715494216732672,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":5,"chetai_start":91,"chetai_end":94,"yg_id":25394311449284608,"dangcheshu":3.5}, + {"id":123715494233509888,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":5,"chetai_start":94,"chetai_end":97,"yg_id":25394338452213760,"dangcheshu":3.5}, + {"id":123715494262870016,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"jizu":5,"chetai_start":98,"chetai_end":100,"yg_id":25394319443628032,"dangcheshu":3}, + {"id":124085100756340736,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":1,"chetai_start":1,"chetai_end":4,"yg_id":25394300791558144,"dangcheshu":3.5}, + {"id":124085100798283776,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":1,"chetai_start":4,"chetai_end":7,"yg_id":25394348992499712,"dangcheshu":3.5}, + {"id":124085100819255296,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":1,"chetai_start":8,"chetai_end":10,"yg_id":25394250522824704,"dangcheshu":3}, + {"id":124085100848615424,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":1,"chetai_start":11,"chetai_end":14,"yg_id":25394251181330432,"dangcheshu":3.5}, + {"id":124085100873781248,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":1,"chetai_start":14,"chetai_end":17,"yg_id":25394300154023936,"dangcheshu":3.5}, + {"id":124085100898947072,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":1,"chetai_start":18,"chetai_end":20,"yg_id":25394274627489792,"dangcheshu":3}, + {"id":124085260844535808,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":2,"chetai_start":21,"chetai_end":24,"yg_id":25394297989763072,"dangcheshu":3.5}, + {"id":124085260886478848,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":2,"chetai_start":24,"chetai_end":27,"yg_id":25394285700452352,"dangcheshu":3.5}, + {"id":124085260907450368,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":2,"chetai_start":28,"chetai_end":30,"yg_id":25394258097737728,"dangcheshu":3}, + {"id":124085260924227584,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":2,"chetai_start":31,"chetai_end":34,"yg_id":25394289043312640,"dangcheshu":3.5}, + {"id":124085260941004800,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":2,"chetai_start":34,"chetai_end":37,"yg_id":25394260572377088,"dangcheshu":3.5}, + {"id":124085260957782016,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":2,"chetai_start":38,"chetai_end":40,"yg_id":25394276103884800,"dangcheshu":3}, + {"id":124085321473200128,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":3,"chetai_start":41,"chetai_end":45,"yg_id":25394275688648704,"dangcheshu":5}, + {"id":124085321494171648,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":3,"chetai_start":46,"chetai_end":50,"yg_id":25394257451814912,"dangcheshu":5}, + {"id":124085321510948864,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":3,"chetai_start":51,"chetai_end":55,"yg_id":25394267476201472,"dangcheshu":5}, + {"id":124085321523531776,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":3,"chetai_start":56,"chetai_end":60,"yg_id":25394259020484608,"dangcheshu":5}, + {"id":124085394332454912,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":4,"chetai_start":61,"chetai_end":64,"yg_id":25394288347058176,"dangcheshu":3.5}, + {"id":124085394353426432,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":4,"chetai_start":64,"chetai_end":67,"yg_id":25394266192744448,"dangcheshu":3.5}, + {"id":124085394395369472,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":4,"chetai_start":68,"chetai_end":70,"yg_id":25394282345009152,"dangcheshu":3}, + {"id":124085394416340992,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":4,"chetai_start":71,"chetai_end":74,"yg_id":25394284706402304,"dangcheshu":3.5}, + {"id":124085394433118208,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":4,"chetai_start":74,"chetai_end":77,"yg_id":25394293271171072,"dangcheshu":3.5}, + {"id":124085394449895424,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"jizu":4,"chetai_start":78,"chetai_end":80,"yg_id":25394248987709440,"dangcheshu":3}, + {"id":124422175993106432,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"chetai_start":101,"chetai_end":103,"yg_id":93237880561864704,"dangcheshu":2.5}, + {"id":124422176030855168,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"chetai_start":103,"chetai_end":105,"yg_id":93590060657545216,"dangcheshu":2.5}, + {"id":124422176056020992,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"chetai_start":106,"chetai_end":108,"yg_id":93240184245587968,"dangcheshu":2.5}, + {"id":124422176081186816,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"chetai_start":108,"chetai_end":110,"yg_id":88556029159149568,"dangcheshu":2.5}, + {"id":124422176106352640,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"chetai_start":111,"chetai_end":113,"yg_id":93238706298687488,"dangcheshu":2.5}, + {"id":124422176131518464,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"chetai_start":113,"chetai_end":115,"yg_id":88553603400208384,"dangcheshu":2.5}, + {"id":124422176152489984,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"chetai_start":116,"chetai_end":118,"yg_id":93236409787224064,"dangcheshu":2.5}, + {"id":124422176181850112,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"jizu":6,"chetai_start":118,"chetai_end":120,"yg_id":93239113490108416,"dangcheshu":2.5} +] diff --git a/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_zbz.json b/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_zbz.json new file mode 100644 index 0000000..99264dd --- /dev/null +++ b/backend/F9WebAiTest.Infrastructure/Data/SeedData/biz_prod_qs_ktpb_zbz.json @@ -0,0 +1,9 @@ +[ + {"id":30318522743656448,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"yg_id":25394296936992768}, + {"id":30318912478384128,"deleted_at":null,"dep_id":16043931070369792,"banci":1,"yg_id":25394278175870976}, + {"id":30318977318129664,"deleted_at":null,"dep_id":16047387197837312,"banci":1,"yg_id":25394284219863040}, + {"id":30574578740760576,"deleted_at":null,"dep_id":22308683820044288,"banci":1,"yg_id":25394286337986560}, + {"id":30574628829138944,"deleted_at":null,"dep_id":22308683820044288,"banci":2,"yg_id":25394249843347456}, + {"id":32372395503259648,"deleted_at":null,"dep_id":22308600831545344,"banci":1,"yg_id":25394250304720896}, + {"id":56641710280675328,"deleted_at":null,"dep_id":22308600831545344,"banci":2,"yg_id":25394284219863040} +] diff --git a/web/src/components/select/EmployeeSelect.vue b/web/src/components/select/EmployeeSelect.vue new file mode 100644 index 0000000..faa280a --- /dev/null +++ b/web/src/components/select/EmployeeSelect.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/web/src/router/index.js b/web/src/router/index.js index f2ebe1e..adb69ac 100644 --- a/web/src/router/index.js +++ b/web/src/router/index.js @@ -65,6 +65,7 @@ export const componentMap = { 'prod/lsjl/index': () => import('../views/prod/lsjl/index.vue'), 'prod/xdjy/index': () => import('../views/prod/xdjy/index.vue'), 'prod/hbjy/index': () => import('../views/prod/hbjy/index.vue'), + 'prod/ktpb/index': () => import('../views/prod/ktpb/index.vue'), 'notification/messages/index': () => import('../views/notification/messages/index.vue'), 'notification/subscribe/index': () => import('../views/notification/subscribe/index.vue'), 'notification/type/index': () => import('../views/notification/type/index.vue'), diff --git a/web/src/views/prod/ktpb/index.vue b/web/src/views/prod/ktpb/index.vue new file mode 100644 index 0000000..f70bda4 --- /dev/null +++ b/web/src/views/prod/ktpb/index.vue @@ -0,0 +1,650 @@ + + + + + diff --git a/工作进度/工作进度-12.md b/工作进度/工作进度-12.md new file mode 100644 index 0000000..e11b556 --- /dev/null +++ b/工作进度/工作进度-12.md @@ -0,0 +1,135 @@ +# 工作进度-12:生产-前缫「看台排班」+ 机组车台/看台排班数据导入 + +> 时间:2026-10-22(承接工作进度-11) +> 需求:仿照 `D:\AntaiProject - 副本` 生产-前缫的「机组车台 / 看台排班」,在本系统落地看台排班功能,并导入随附的 4 张表数据: +> `biz_prod_qs_jzct`(机组车台)、`biz_prod_qs_ktpb_ctg`(车头工)、`biz_prod_qs_ktpb_dcg`(挡车工)、`biz_prod_qs_ktpb_zbz`(值班长)。 +> 参考实现:`WinClient\F9.Business.Prod\QS\KTPB\`(Page_KTPB、Page_KTPBCTG_Edit、Page_KTPBDCG_Edit、Page_KTPBZBZ_Edit)、`Application\CQRS\Business\PROD\QS\KTPB\`、`Domain\Entities\Business\PROD\QS\KTPB\`。 + +--- + +## 一、功能设计 + +``` +生产-前缫 +├── 落丝记录 +├── 车间班次 +└── 看台排班(新增) /prod/qianxian/ktpb + 顶部:车间(职责类型=前缫)+ 班次(甲/乙)+ 机组 + 关键字 + 页签:挡车工 / 车头工 / 值班长 + ├── 挡车工:按「车间+班次+机组」整组维护 + │ 弹窗内可批量添加挡车工(多选职工),逐行填起止车台, + │ 挡车数自动计算(接壤车台各计 0.5),实时显示「已分配 x / y 台」 + ├── 车头工:一个「车间+班次+机组」一条记录,含车头工1 / 车头工2 + └── 值班长:一个「车间+班次」可有多名值班长 +``` + +与 F9 的对应关系: +| F9 | 本系统 | +|---|---| +| `Page_KTPB`(三个页签 + 车间/班次/机组过滤) | `views/prod/ktpb/index.vue` | +| `Page_KTPBDCG_Edit`(整组批量编辑 + 挡车数计算) | 挡车工弹窗 + `POST /dcg/batch` | +| `Page_KTPBCTG_Edit` / `Page_KTPBZBZ_Edit` | 车头工 / 值班长弹窗 | +| `BatchReplaceKtpbdcgCommand` | `KtpbService.SaveDcgBatchAsync`(先删后建) | + +**挡车数算法**(移植 `CalculateSingleDangcheshu`):每台车权重默认 1;若某车台被多条记录覆盖,且同时是某记录的起点与另一记录的终点(接壤),该车台权重取 0.5,最后四舍五入保留两位。前后端实现完全一致。 + +--- + +## 二、后端 + +### 2.1 实体(`Domain/Entities/PROD/Ktpb.cs`) + +| 类 | 表 | 主要字段 | +|---|---|---| +| `KtpbCtg` | `KtpbCtgs` | DeptId、Banci、Jizu、Ygid1、Ygid2 | +| `KtpbDcg` | `KtpbDcgs` | DeptId、Banci、Jizu、ChetaiStart、ChetaiEnd、YgId、Dangcheshu | +| `KtpbZbz` | `KtpbZbzs` | DeptId、Banci、YgId | + +### 2.2 服务与接口(`KtpbService` / `KtpbController`,路由 `api/prod/ktpb`) + +``` +GET qianxian-deps 车间下拉(DutyType=前缫) +GET jizu-options?depId= 机组下拉(含车台范围,取机组车台) +GET ctg?depId=&banci=&jizu=&like= 车头工分页 +POST ctg | PUT ctg/{id} | DELETE ctg/{id} +GET dcg?depId=&banci=&jizu=&like= 挡车工分页 +GET dcg/group?depId=&banci=&jizu= 某机组整组排班 +POST dcg/batch 整组替换(空集合=清空) +DELETE dcg/{id} +GET zbz?depId=&banci=&like= 值班长分页 +POST zbz | PUT zbz/{id} | DELETE zbz/{id} +``` + +校验规则: +- 车头工:同「车间+班次+机组」唯一,车头工1 必填。 +- 挡车工:起始车台>0、结束≥起始、必须落在该机组车台范围内;保存时服务端重算挡车数。 +- 值班长:同「车间+班次+值班长」不重复。 + +### 2.3 数据导入(`ProdSeedData`,幂等) + +新增 3 个内嵌资源 `SeedData/biz_prod_qs_ktpb_ctg.json`、`_dcg.json`、`_zbz.json`,并把 `biz_prod_qs_jzct.json` 按本次导出数据重新生成。 + +映射规则: +- **部门**:xlsx 中的 `dep_id` 是 F9 部门 Id,经 `BusinessSeedData.DeptData`(F9 Id → 部门名)映射到本系统 `Departments.Id`; +- **职工**:F9 职工导出时保留了原始雪花 Id,本系统 `Employees.Id` 与之一致,直接按 Id 关联(不存在的职工行跳过); +- **清洗**:剔除 `deleted_at` 非空的软删除行(4 张表中大量为测试/删除数据)、部门无法映射或不在前缫四车间的行、机组/车台号非法行; +- **去重**:机组车台按「车间+机组」保留规范行(优先 `起始号 = (机组-1)*20+1`);车头工按「车间+班次+机组」;值班长按「车间+班次+值班长」;挡车工按整行; +- **幂等**:机组车台按「车间+机组」upsert;车头工按「车间+班次+机组」upsert;挡车工按「车间+班次+机组」整组已存在则跳过;值班长按唯一键跳过。 + +导入结果(本次启动日志): + +``` +[ProdSeed] 机组车台:来源 24 条,新增 0,更新 0(此前已导入) +[ProdSeed] 车头工看台排班:来源 33 条,新增 33 条 +[ProdSeed] 挡车工看台排班:来源 202 条,新增 202 条(34 组) +[ProdSeed] 值班长看台排班:来源 7 条,新增 7 条 +``` + +> 原始 xlsx 行数:机组车台 35、车头工 75、挡车工 4543、值班长 13;其中挡车工 4341 行是 F9 里已软删除的历史/测试数据,故有效数据仅 202 行。 + +### 2.4 菜单 + +`DbSeeder.SeedProdMenus` 在生产-前缫下新增第 3 个子菜单「看台排班」,权限标识 `prod:ktpb:list`,admin 自动授权。 + +--- + +## 三、前端 + +| 文件 | 说明 | +|---|---| +| `views/prod/ktpb/index.vue` | 看台排班主页面(三页签 + 过滤 + 分页 + 三个弹窗) | +| `components/select/EmployeeSelect.vue` | 职工选择弹窗(单选/多选,支持按部门过滤与姓名/工号搜索) | +| `router/index.js` | 注册 `prod/ktpb/index` 路由组件 | + +前端交互要点: +- 挡车工维护必须先在顶部选定「车间 + 机组」,弹窗内展示该机组车台范围; +- 弹窗顶部实时显示「已分配 x / y 台」,未满额时标签变黄,避免漏排; +- 起止车台用 `el-input-number` 限制在机组范围内,改动即刷新挡车数; +- 车头工/值班长新建时默认带出当前过滤的车间与班次。 + +--- + +## 四、验证记录 + +| 项 | 结果 | +|---|---| +| `dotnet build` | ✅ 0 错误 | +| `vite build` | ✅ 通过(仅既有体积/SignalR 注释警告) | +| 菜单 | ✅ 生产-前缫 → 落丝记录 / 车间班次 / 看台排班 | +| 车间下拉 | ✅ 前缫车间、前缫一~四车间 | +| 机组下拉(前缫一车间) | ✅ 机组1-6,车台 1-20 / 21-40 / … / 101-120 | +| 挡车工列表 | ✅ 202 条,姓名/车台/挡车数正确(3.5、3、3.5…) | +| 车头工列表 | ✅ 33 条 | +| 值班长列表 | ✅ 7 条 | +| 整组保存 + 挡车数重算 | ✅ 行1 1-10、行2 10-20 → 9.5 / 10.5(接壤车台各 0.5) | +| 超范围校验 | ✅ 车台 1-99 于机组1(1-20)返回 400「超出该机组车台范围 1-20」 | +| 测试数据清理 | ✅ 临时数据删除后组内 0 行 | + +--- + +## 五、说明与后续 + +1. 职工姓名沿用 F9 档案原文(部分带「宁兴」等后缀,如「谢群生宁兴」),属于基础数据层面的既有情况,本次未改动。 +2. 「机组车台」维护页面仍在 基础数据 下(`/base/jizuchetai`);F9 是放在生产-前缫组内。如需完全对齐,可把该菜单整体平移到生产-前缫(数据接口不变)。 +3. 挡车工排班目前按「整组替换」保存,没有保留历史版本;若需要留痕,可增加排班生效日期 + 版本表。 +4. 后续若要支持「按班组/按日期」排班(F9 另有班组维度),可在现有三张表上扩展 BanCi 组合键。