完善机组车台功能,并导入机组车台 / 车间班次数据
一、机组车台功能完善 - 车间下拉改为只取「前缫」职责类型的部门(新增接口 /api/jizuchetai/qianxian-deps) - 补齐校验:车间、机组号、开始车台号必填;结束车台号不得小于开始车台号;同车间同机组不可重复 - 前端页面同步调整:车间改为下拉选择、增加必填提示、表格加 row-key 二、数据导入(新增 ProdSeedData,幂等导入器) - biz_prod_qs_jzct:机组车台 35 条(其中 11 条已删除)→ 有效 24 条 - biz_prod_qs_cjbc:车间班次 7 条(其中 1 条已删除)→ 有效 6 条 - F9 的部门 Id 通过部门名称映射到本系统部门;已删除的数据不导入; 已存在且一致的数据不重复写入,缺失的自动补回
This commit is contained in:
@@ -130,6 +130,11 @@ public class JizuChetaiController : ControllerBase
|
||||
public async Task<IActionResult> GetPaged([FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 20, [FromQuery] string keyword = "")
|
||||
=> Ok(ApiResult<PageResult<JizuChetaiDto>>.Ok(await _svc.GetPagedAsync(pageIndex, pageSize, keyword)));
|
||||
|
||||
// 车间下拉(前缫车间)
|
||||
[HttpGet("qianxian-deps")]
|
||||
public async Task<IActionResult> GetQianxianDeps()
|
||||
=> Ok(ApiResult<List<DeptOptionDto>>.Ok(await _svc.GetQianxianDepsAsync()));
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Create([FromBody] JizuChetaiDto dto)
|
||||
{
|
||||
|
||||
Binary file not shown.
@@ -84,3 +84,10 @@ public class JizuChetaiDto
|
||||
public int ChetaiStart { get; set; }
|
||||
public int ChetaiEnd { get; set; }
|
||||
}
|
||||
|
||||
// ---- 部门下拉项(机组车台等模块选用车间)----
|
||||
public class DeptOptionDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using F9WebAiTest.Application.Dtos.Base;
|
||||
using F9WebAiTest.Domain.Common;
|
||||
using F9WebAiTest.Domain.Entities;
|
||||
using F9WebAiTest.Domain.Entities.Base;
|
||||
using F9WebAiTest.Domain.Enums.SYS.Departments;
|
||||
using SysDept = F9WebAiTest.Domain.Entities.SYS.Departments;
|
||||
|
||||
namespace F9WebAiTest.Application.Services.Base;
|
||||
@@ -251,6 +252,9 @@ public interface IJizuChetaiService
|
||||
Task<JizuChetaiDto> CreateAsync(JizuChetaiDto dto);
|
||||
Task<JizuChetaiDto> UpdateAsync(long id, JizuChetaiDto dto);
|
||||
Task DeleteAsync(long id);
|
||||
|
||||
/// <summary>车间下拉:只取职责类型为「前缫」的部门</summary>
|
||||
Task<List<DeptOptionDto>> GetQianxianDepsAsync();
|
||||
}
|
||||
|
||||
public class JizuChetaiService : IJizuChetaiService
|
||||
@@ -296,6 +300,7 @@ public class JizuChetaiService : IJizuChetaiService
|
||||
|
||||
public async Task<JizuChetaiDto> CreateAsync(JizuChetaiDto dto)
|
||||
{
|
||||
await ValidateAsync(dto, 0);
|
||||
var e = new JizuChetai { DepartmentId = dto.DepartmentId, Jizu = dto.Jizu, ChetaiStart = dto.ChetaiStart, ChetaiEnd = dto.ChetaiEnd };
|
||||
await _repo.AddAsync(e);
|
||||
await _repo.SaveChangesAsync();
|
||||
@@ -306,12 +311,36 @@ public class JizuChetaiService : IJizuChetaiService
|
||||
{
|
||||
var e = await _repo.GetByIdAsync(id);
|
||||
if (e == null) throw new ServiceException("记录不存在", 404);
|
||||
await ValidateAsync(dto, id);
|
||||
e.DepartmentId = dto.DepartmentId; e.Jizu = dto.Jizu; e.ChetaiStart = dto.ChetaiStart; e.ChetaiEnd = dto.ChetaiEnd;
|
||||
await _repo.UpdateAsync(e);
|
||||
await _repo.SaveChangesAsync();
|
||||
return await GetDto(e);
|
||||
}
|
||||
|
||||
/// <summary>校验:车间、机组号、车台范围必填且合理,同一车间的机组不可重复</summary>
|
||||
private async Task ValidateAsync(JizuChetaiDto dto, long excludeId)
|
||||
{
|
||||
if (dto.DepartmentId <= 0) throw new ServiceException("请选择车间");
|
||||
if (dto.Jizu <= 0) throw new ServiceException("机组号必须大于 0");
|
||||
if (dto.ChetaiStart <= 0) throw new ServiceException("开始车台号必须大于 0");
|
||||
if (dto.ChetaiEnd < dto.ChetaiStart) throw new ServiceException("结束车台号不能小于开始车台号");
|
||||
|
||||
var all = await _repo.GetAllAsync();
|
||||
if (all.Any(x => x.Id != excludeId && x.DepartmentId == dto.DepartmentId && x.Jizu == dto.Jizu))
|
||||
throw new ServiceException("该车间的此机组已存在,请勿重复配置");
|
||||
}
|
||||
|
||||
public async Task<List<DeptOptionDto>> 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 DeptOptionDto { Id = d.Id, Name = d.Name })
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(long id)
|
||||
{
|
||||
var e = await _repo.GetByIdAsync(id);
|
||||
|
||||
@@ -68,6 +68,9 @@ public static class DbSeeder
|
||||
GongyingshangSeedData.Seed(fsql);
|
||||
EmployeeSeedData.Seed(fsql);
|
||||
|
||||
// 6.655 生产模块基础数据(机组车台 + 车间班次,F9 导出数据幂等导入)
|
||||
ProdSeedData.Seed(fsql, snowflake);
|
||||
|
||||
// 6.66 基础数据菜单(工种管理、账期管理、注册表、原料庄口、物资目录、往来单位)
|
||||
SeedWorkTypeMenus(fsql, snowflake);
|
||||
SeedZhangqiMenus(fsql, snowflake);
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using FreeSql;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Entities.Base;
|
||||
using F9WebAiTest.Domain.Entities.Prod;
|
||||
using F9WebAiTest.Domain.Enums.SYS.Employees;
|
||||
using SysDept = F9WebAiTest.Domain.Entities.SYS.Departments;
|
||||
|
||||
namespace F9WebAiTest.Infrastructure.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 生产模块基础数据种子(来源于 F9 系统导出):
|
||||
/// 1) biz_prod_qs_jzct —— 机组车台
|
||||
/// 2) biz_prod_qs_cjbc —— 车间班次
|
||||
/// 幂等:按「车间 + 机组」/「车间 + 班次」匹配,存在则校正,不存在则新增;已删除的数据不导入。
|
||||
/// </summary>
|
||||
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 static readonly JsonSerializerOptions JsonOpts = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
NumberHandling = JsonNumberHandling.AllowReadingFromString
|
||||
};
|
||||
|
||||
public static void Seed(IFreeSql fsql, ISnowflakeIdGenerator snowflake)
|
||||
{
|
||||
SeedJizuChetai(fsql);
|
||||
SeedChejianBanci(fsql);
|
||||
}
|
||||
|
||||
// ==================== 机组车台 ====================
|
||||
private static void SeedJizuChetai(IFreeSql fsql)
|
||||
{
|
||||
try
|
||||
{
|
||||
var items = Load<JzctItem>(JzctResource);
|
||||
if (items.Count == 0) return;
|
||||
|
||||
var deptMap = BuildDeptMap(fsql);
|
||||
var existing = fsql.Select<JizuChetai>().ToList()
|
||||
.GroupBy(x => (x.DepartmentId, x.Jizu))
|
||||
.ToDictionary(g => g.Key, g => g.First());
|
||||
|
||||
int added = 0, updated = 0, skipped = 0;
|
||||
var unmappedDeps = new HashSet<long>();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(item.DeletedAt)) { skipped++; continue; }
|
||||
|
||||
if (!deptMap.TryGetValue(item.DepId, out var deptId))
|
||||
{
|
||||
unmappedDeps.Add(item.DepId);
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var key = (deptId, item.Jizu);
|
||||
if (existing.TryGetValue(key, out var e))
|
||||
{
|
||||
if (e.ChetaiStart != item.ChetaiStart || e.ChetaiEnd != item.ChetaiEnd)
|
||||
{
|
||||
e.ChetaiStart = item.ChetaiStart;
|
||||
e.ChetaiEnd = item.ChetaiEnd;
|
||||
fsql.Update<JizuChetai>().SetSource(e).ExecuteAffrows();
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fsql.Insert(new JizuChetai
|
||||
{
|
||||
DepartmentId = deptId,
|
||||
Jizu = item.Jizu,
|
||||
ChetaiStart = item.ChetaiStart,
|
||||
ChetaiEnd = item.ChetaiEnd
|
||||
}).ExecuteAffrows();
|
||||
added++;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"[ProdSeed] 机组车台:来源 {items.Count} 条,新增 {added} 条,更新 {updated} 条,跳过(已删除/无法映射){skipped} 条");
|
||||
if (unmappedDeps.Count > 0)
|
||||
Console.WriteLine($"[ProdSeed] 提示:以下 F9 部门 Id 未匹配到本系统部门,已跳过 -> {string.Join(", ", unmappedDeps)}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[ProdSeed] 机组车台导入跳过:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 车间班次 ====================
|
||||
private static void SeedChejianBanci(IFreeSql fsql)
|
||||
{
|
||||
try
|
||||
{
|
||||
var items = Load<CjbcItem>(CjbcResource);
|
||||
if (items.Count == 0) return;
|
||||
|
||||
var deptMap = BuildDeptMap(fsql);
|
||||
var existing = fsql.Select<ChejianBanci>().ToList()
|
||||
.GroupBy(x => (x.DeptId, x.Banci))
|
||||
.ToDictionary(g => g.Key, g => g.First());
|
||||
|
||||
int added = 0, updated = 0, skipped = 0;
|
||||
var unmappedDeps = new HashSet<long>();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(item.DeletedAt)) { skipped++; continue; }
|
||||
|
||||
if (!deptMap.TryGetValue(item.DepId, out var deptId))
|
||||
{
|
||||
unmappedDeps.Add(item.DepId);
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var banci = (Prod_Banci_Enum)item.Banci;
|
||||
var key = (deptId, banci);
|
||||
if (existing.TryGetValue(key, out var e))
|
||||
{
|
||||
if (Math.Abs(e.KaoqinDayhours - item.KaoqinDayhours) > 0.001)
|
||||
{
|
||||
e.KaoqinDayhours = item.KaoqinDayhours;
|
||||
fsql.Update<ChejianBanci>().SetSource(e).ExecuteAffrows();
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fsql.Insert(new ChejianBanci
|
||||
{
|
||||
DeptId = deptId,
|
||||
Banci = banci,
|
||||
KaoqinDayhours = item.KaoqinDayhours
|
||||
}).ExecuteAffrows();
|
||||
added++;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"[ProdSeed] 车间班次:来源 {items.Count} 条,新增 {added} 条,更新 {updated} 条,跳过(已删除/无法映射){skipped} 条");
|
||||
if (unmappedDeps.Count > 0)
|
||||
Console.WriteLine($"[ProdSeed] 提示:以下 F9 部门 Id 未匹配到本系统部门,已跳过 -> {string.Join(", ", unmappedDeps)}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[ProdSeed] 车间班次导入跳过:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 公共 ====================
|
||||
|
||||
/// <summary>建立 F9 部门 Id → 本系统部门 Id 的映射(以部门名称为桥梁)</summary>
|
||||
private static Dictionary<long, long> BuildDeptMap(IFreeSql fsql)
|
||||
{
|
||||
var f9NameMap = BusinessSeedData.DeptData.ToDictionary(x => x.Id, x => x.Name);
|
||||
var localNameMap = fsql.Select<SysDept.Department>().ToList()
|
||||
.GroupBy(d => d.Name)
|
||||
.ToDictionary(g => g.Key, g => g.First().Id);
|
||||
|
||||
var map = new Dictionary<long, long>();
|
||||
foreach (var (f9Id, name) in f9NameMap)
|
||||
{
|
||||
if (localNameMap.TryGetValue(name, out var localId)) map[f9Id] = localId;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static List<T> Load<T>(string resourceName)
|
||||
{
|
||||
var asm = Assembly.GetExecutingAssembly();
|
||||
using var stream = asm.GetManifestResourceStream(resourceName);
|
||||
if (stream == null) return new List<T>();
|
||||
return JsonSerializer.Deserialize<List<T>>(stream, JsonOpts) ?? new List<T>();
|
||||
}
|
||||
|
||||
// ---- 数据项 ----
|
||||
private class JzctItem
|
||||
{
|
||||
[JsonPropertyName("id")] public long Id { get; set; }
|
||||
[JsonPropertyName("deleted_at")] public string? DeletedAt { get; set; }
|
||||
[JsonPropertyName("dep_id")] public long DepId { 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; }
|
||||
}
|
||||
|
||||
private class CjbcItem
|
||||
{
|
||||
[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("kaoqin_dayhours")] public double KaoqinDayhours { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
[
|
||||
{
|
||||
"id": 18269488810037248,
|
||||
"deleted_at": "",
|
||||
"dep_id": 16043931070369792,
|
||||
"banci": 1,
|
||||
"kaoqin_dayhours": 9
|
||||
},
|
||||
{
|
||||
"id": 18500791564242944,
|
||||
"deleted_at": "10/12/2025 13:05:07.557",
|
||||
"dep_id": 16043931070369792,
|
||||
"banci": 2,
|
||||
"kaoqin_dayhours": 6
|
||||
},
|
||||
{
|
||||
"id": 20744935502254080,
|
||||
"deleted_at": "",
|
||||
"dep_id": 16047387197837312,
|
||||
"banci": 1,
|
||||
"kaoqin_dayhours": 9
|
||||
},
|
||||
{
|
||||
"id": 25443995760988160,
|
||||
"deleted_at": "",
|
||||
"dep_id": 22308600831545344,
|
||||
"banci": 1,
|
||||
"kaoqin_dayhours": 9
|
||||
},
|
||||
{
|
||||
"id": 25444063712907264,
|
||||
"deleted_at": "",
|
||||
"dep_id": 22308683820044288,
|
||||
"banci": 1,
|
||||
"kaoqin_dayhours": 9
|
||||
},
|
||||
{
|
||||
"id": 25444106268315648,
|
||||
"deleted_at": "",
|
||||
"dep_id": 22308683820044288,
|
||||
"banci": 2,
|
||||
"kaoqin_dayhours": 9
|
||||
},
|
||||
{
|
||||
"id": 35745732161966080,
|
||||
"deleted_at": "",
|
||||
"dep_id": 22308600831545344,
|
||||
"banci": 2,
|
||||
"kaoqin_dayhours": 9
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,422 @@
|
||||
[
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
@@ -1,61 +1,103 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import request from '../../../utils/request';
|
||||
import { buildDeptTree } from '../../../utils/dept';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
|
||||
const list = ref([]);
|
||||
const total = ref(0);
|
||||
const loading = ref(false);
|
||||
const deptTree = ref([]);
|
||||
const query = reactive({ pageIndex: 1, pageSize: 20, keyword: '' });
|
||||
|
||||
// 车间下拉:只取职责类型为「前缫」的部门(后端接口)
|
||||
const deptOptions = ref([]);
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const dialogTitle = ref('新增机组车台');
|
||||
const isEdit = ref(false);
|
||||
const editId = ref(null);
|
||||
const form = reactive({ departmentId: null, jizu: 0, chetaiStart: 0, chetaiEnd: 0 });
|
||||
const form = reactive({ departmentId: 0, jizu: 0, chetaiStart: 0, chetaiEnd: 0 });
|
||||
|
||||
async function load() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await request.get('/jizuchetai', { params: query });
|
||||
list.value = res.data.items;
|
||||
total.value = res.data.total;
|
||||
list.value = res.data.items || [];
|
||||
total.value = res.data.total || 0;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDepts() {
|
||||
const res = await request.get('/sys/department');
|
||||
deptTree.value = buildDeptTree(res.data);
|
||||
try {
|
||||
const res = await request.get('/jizuchetai/qianxian-deps');
|
||||
deptOptions.value = res.data || [];
|
||||
} catch (e) {
|
||||
deptOptions.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
// 分页组件挂载时会触发一次 current-change:页码未变化时忽略,避免首次打开重复请求
|
||||
function handlePageChange(p) {
|
||||
if (p === query.pageIndex) return;
|
||||
query.pageIndex = p;
|
||||
load();
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
query.pageIndex = 1;
|
||||
load();
|
||||
}
|
||||
|
||||
function openCreate() {
|
||||
isEdit.value = false;
|
||||
dialogTitle.value = '新增机组车台';
|
||||
Object.assign(form, { departmentId: null, jizu: 0, chetaiStart: 0, chetaiEnd: 0 });
|
||||
Object.assign(form, {
|
||||
departmentId: Number(deptOptions.value[0]?.id) || 0,
|
||||
jizu: 0,
|
||||
chetaiStart: 0,
|
||||
chetaiEnd: 0
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
|
||||
function openEdit(row) {
|
||||
isEdit.value = true;
|
||||
editId.value = row.id;
|
||||
dialogTitle.value = '编辑机组车台';
|
||||
Object.assign(form, { departmentId: row.departmentId, jizu: row.jizu, chetaiStart: row.chetaiStart, chetaiEnd: row.chetaiEnd });
|
||||
dialogTitle.value = '修改机组车台';
|
||||
Object.assign(form, {
|
||||
departmentId: Number(row.departmentId),
|
||||
jizu: Number(row.jizu),
|
||||
chetaiStart: Number(row.chetaiStart),
|
||||
chetaiEnd: Number(row.chetaiEnd)
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
|
||||
async function save() {
|
||||
if (!form.departmentId) { ElMessage.warning('请选择车间'); return; }
|
||||
if (!form.departmentId) {
|
||||
ElMessage.warning('请选择车间');
|
||||
return;
|
||||
}
|
||||
if (!form.jizu || form.jizu <= 0) {
|
||||
ElMessage.warning('机组号必须大于 0');
|
||||
return;
|
||||
}
|
||||
if (!form.chetaiStart || form.chetaiStart <= 0) {
|
||||
ElMessage.warning('开始车台号必须大于 0');
|
||||
return;
|
||||
}
|
||||
if (form.chetaiEnd < form.chetaiStart) {
|
||||
ElMessage.warning('结束车台号不能小于开始车台号');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (isEdit.value) {
|
||||
await request.put(`/jizuchetai/${editId.value}`, form);
|
||||
ElMessage.success('更新成功');
|
||||
ElMessage.success('修改成功');
|
||||
} else {
|
||||
await request.post('/jizuchetai', form);
|
||||
ElMessage.success('创建成功');
|
||||
ElMessage.success('新增成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
load();
|
||||
@@ -63,7 +105,7 @@ async function save() {
|
||||
}
|
||||
|
||||
async function del(row) {
|
||||
await ElMessageBox.confirm(`确定删除机组「${row.jizu}」吗?`, '提示', { type: 'warning' });
|
||||
await ElMessageBox.confirm(`确定删除「${row.departmentName} · 机组${row.jizu}」吗?`, '提示', { type: 'warning' });
|
||||
try {
|
||||
await request.delete(`/jizuchetai/${row.id}`);
|
||||
ElMessage.success('删除成功');
|
||||
@@ -71,13 +113,10 @@ async function del(row) {
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function handlePageChange(p) {
|
||||
// 分页组件挂载时会触发一次 current-change,页码未变化时忽略,避免首次打开重复请求
|
||||
if (p === query.pageIndex) return;
|
||||
query.pageIndex = p;
|
||||
onMounted(() => {
|
||||
loadDepts();
|
||||
load();
|
||||
}
|
||||
onMounted(() => { load(); loadDepts(); });
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -90,40 +129,55 @@ onMounted(() => { load(); loadDepts(); });
|
||||
</template>
|
||||
|
||||
<div class="search-bar">
|
||||
<el-input v-model="query.keyword" placeholder="车间/机组号" clearable style="width: 200px" @keyup.enter="query.pageIndex=1;load()" />
|
||||
<el-button type="primary" @click="query.pageIndex=1;load()">搜索</el-button>
|
||||
<el-input
|
||||
v-model="query.keyword"
|
||||
placeholder="车间 / 机组号"
|
||||
clearable
|
||||
style="width: 220px"
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
</div>
|
||||
|
||||
<el-table v-loading="loading" :data="list" border stripe>
|
||||
<el-table v-loading="loading" :data="list" row-key="id" border stripe>
|
||||
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||
<el-table-column prop="departmentName" label="车间" min-width="200" />
|
||||
<el-table-column prop="jizu" label="机组号" width="120" />
|
||||
<el-table-column prop="chetaiStart" label="开始车台号" width="120" />
|
||||
<el-table-column prop="chetaiEnd" label="结束车台号" width="120" />
|
||||
<el-table-column label="操作" width="140" fixed="right">
|
||||
<el-table-column prop="chetaiStart" label="开始车台号" width="130" />
|
||||
<el-table-column prop="chetaiEnd" label="结束车台号" width="130" />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button size="small" type="primary" @click="openEdit(row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="del(row)">删除</el-button>
|
||||
<el-button size="small" type="primary" link @click="openEdit(row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" link @click="del(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination class="pagination" :current-page="query.pageIndex" :page-size="query.pageSize" :total="total" layout="total, prev, pager, next" @current-change="handlePageChange" />
|
||||
<el-pagination
|
||||
class="pagination"
|
||||
:current-page="query.pageIndex"
|
||||
:page-size="query.pageSize"
|
||||
:total="total"
|
||||
layout="total, prev, pager, next"
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="480px">
|
||||
<el-form :model="form" label-width="100px">
|
||||
<el-form-item label="车间">
|
||||
<el-tree-select
|
||||
v-model="form.departmentId"
|
||||
:data="deptTree"
|
||||
:props="{ label: 'name', value: 'id', children: 'children' }"
|
||||
check-strictly
|
||||
placeholder="选择车间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="520px">
|
||||
<el-form :model="form" label-width="110px">
|
||||
<el-form-item label="车间" required>
|
||||
<el-select v-model="form.departmentId" placeholder="请选择车间" style="width: 100%">
|
||||
<el-option v-for="d in deptOptions" :key="d.id" :label="d.name" :value="Number(d.id)" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="机组号" required>
|
||||
<el-input-number v-model="form.jizu" :min="1" :precision="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开始车台号" required>
|
||||
<el-input-number v-model="form.chetaiStart" :min="1" :precision="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束车台号" required>
|
||||
<el-input-number v-model="form.chetaiEnd" :min="1" :precision="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="机组号"><el-input-number v-model="form.jizu" :min="0" /></el-form-item>
|
||||
<el-form-item label="开始车台号"><el-input-number v-model="form.chetaiStart" :min="0" /></el-form-item>
|
||||
<el-form-item label="结束车台号"><el-input-number v-model="form.chetaiEnd" :min="0" /></el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
@@ -135,6 +189,6 @@ onMounted(() => { load(); loadDepts(); });
|
||||
|
||||
<style scoped>
|
||||
.card-header { display: flex; justify-content: space-between; align-items: center; }
|
||||
.search-bar { display: flex; gap: 12px; margin-bottom: 16px; }
|
||||
.search-bar { display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
|
||||
.pagination { margin-top: 16px; justify-content: flex-end; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user