diff --git a/frontend/src/views/worker/WorkerDetailPage.vue b/frontend/src/views/worker/WorkerDetailPage.vue index 886bfb1..76b4134 100644 --- a/frontend/src/views/worker/WorkerDetailPage.vue +++ b/frontend/src/views/worker/WorkerDetailPage.vue @@ -55,14 +55,14 @@ const chartRef=ref();let chart: ECharts | null = null async function loadData(){ const id=route.params.id const [d,m,t] = await Promise.all([ - request.get('/admin/worker/detail', { params: { id } }), - request.get<{ items: any[] }>('/admin/worker/machines', { params: { id } }), - request.get<{ items: any[] }>('/admin/worker/production/today', { params: { id } }), + request.get(`/admin/worker/${id}`), + request.get<{ items: any[] }>(`/admin/worker/${id}/machines`), + request.get<{ items: any[] }>(`/admin/worker/${id}/production/today`), ]) detail.value = d.data || ({} as Worker) machines.value = m.data?.items || [] todayProd.value = t.data?.items || [] - const trend:any=await request.get('/admin/worker/production/trend',{params:{id}}) + const trend:any=await request.get(`/admin/worker/${id}/production/trend`) await nextTick() if(chartRef.value){chart=echarts.init(chartRef.value);const items=trend.data?.items||[];chart.setOption({xAxis:{type:'category',data:items.map((i:any)=>i.date.slice(5))},yAxis:{type:'value'},series:[{type:'line',data:items.map((i:any)=>i.quantity),smooth:true,areaStyle:{opacity:0.1}}],tooltip:{trigger:'axis'},grid:{left:40,right:20,top:10,bottom:30}})} } diff --git a/src/CncModels/Dto/Worker/WorkerAvailableMachineItem.cs b/src/CncModels/Dto/Worker/WorkerAvailableMachineItem.cs new file mode 100644 index 0000000..56dcea3 --- /dev/null +++ b/src/CncModels/Dto/Worker/WorkerAvailableMachineItem.cs @@ -0,0 +1,17 @@ +namespace CncModels.Dto.Worker +{ + /// + /// 可绑定机床项(未绑定其他工人的机床) + /// + public class WorkerAvailableMachineItem + { + /// 机床ID + public int Id { get; set; } + + /// 机床名称 + public string Name { get; set; } + + /// 设备编码 + public string DeviceCode { get; set; } + } +} diff --git a/src/CncModels/Dto/Worker/WorkerMachineItem.cs b/src/CncModels/Dto/Worker/WorkerMachineItem.cs new file mode 100644 index 0000000..4299e40 --- /dev/null +++ b/src/CncModels/Dto/Worker/WorkerMachineItem.cs @@ -0,0 +1,29 @@ +namespace CncModels.Dto.Worker +{ + /// + /// 工人绑定机床项 + /// + public class WorkerMachineItem + { + /// 机床ID + public int MachineId { get; set; } + + /// 机床名称 + public string MachineName { get; set; } + + /// 设备编码 + public string DeviceCode { get; set; } + + /// 车间名称 + public string WorkshopName { get; set; } + + /// 品牌名称 + public string BrandName { get; set; } + + /// 是否在线 + public bool IsOnline { get; set; } + + /// 当前NC程序名 + public string ProgramName { get; set; } + } +} diff --git a/src/CncModels/Dto/Worker/WorkerTodayProdItem.cs b/src/CncModels/Dto/Worker/WorkerTodayProdItem.cs new file mode 100644 index 0000000..7393703 --- /dev/null +++ b/src/CncModels/Dto/Worker/WorkerTodayProdItem.cs @@ -0,0 +1,23 @@ +namespace CncModels.Dto.Worker +{ + /// + /// 工人今日产量明细项 + /// + public class WorkerTodayProdItem + { + /// 机床名称 + public string MachineName { get; set; } + + /// NC程序名 + public string ProgramName { get; set; } + + /// 产量 + public int Quantity { get; set; } + + /// 运行时间(分钟) + public decimal? RunTime { get; set; } + + /// 切削时间(分钟) + public decimal? CuttingTime { get; set; } + } +} diff --git a/src/CncModels/Dto/Worker/WorkerTrendItem.cs b/src/CncModels/Dto/Worker/WorkerTrendItem.cs new file mode 100644 index 0000000..bb502d5 --- /dev/null +++ b/src/CncModels/Dto/Worker/WorkerTrendItem.cs @@ -0,0 +1,14 @@ +namespace CncModels.Dto.Worker +{ + /// + /// 工人产量趋势数据项 + /// + public class WorkerTrendItem + { + /// 日期(yyyy-MM-dd) + public string Date { get; set; } + + /// 当日产量 + public int Quantity { get; set; } + } +} diff --git a/src/CncService/Impl/WorkerService.cs b/src/CncService/Impl/WorkerService.cs index 75b2b8d..ec46f6c 100644 --- a/src/CncService/Impl/WorkerService.cs +++ b/src/CncService/Impl/WorkerService.cs @@ -128,5 +128,79 @@ namespace CncService.Impl if (workerId <= 0 || machineId <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的参数"); return _workerMachineRepository.DeleteByMachineId(machineId); } + + /// + public List GetMachines(int workerId) + { + if (workerId <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的员工ID"); + var bindings = _workerMachineRepository.GetByWorkerId(workerId); + var result = new List(); + foreach (var b in bindings) + { + var m = _machineRepository.GetById(b.MachineId); + if (m == null) continue; + string workshopName = null; + string brandName = null; + // 车间名称需查关联表,但当前简单返回null即可 + result.Add(new WorkerMachineItem + { + MachineId = m.Id, + MachineName = m.Name ?? m.DeviceCode, + DeviceCode = m.DeviceCode, + WorkshopName = workshopName, + BrandName = brandName, + IsOnline = m.IsOnline == 1, + ProgramName = m.LastProgramName + }); + } + return result; + } + + /// + public List GetTodayProduction(int workerId) + { + if (workerId <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的员工ID"); + // 采集服务未运行,返回空列表 + return new List(); + } + + /// + public List GetProductionTrend(int workerId) + { + if (workerId <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的员工ID"); + // 采集服务未运行,返回7天空数据 + var result = new List(); + for (int i = 6; i >= 0; i--) + { + result.Add(new WorkerTrendItem + { + Date = DateTime.Today.AddDays(-i).ToString("yyyy-MM-dd"), + Quantity = 0 + }); + } + return result; + } + + /// + public List GetAvailableMachines() + { + // 获取所有在线且启用的机床,排除已绑定的 + var allMachines = _machineRepository.GetEnabledOnline(); + var result = new List(); + foreach (var m in allMachines) + { + var binding = _workerMachineRepository.GetByMachineId(m.Id); + if (binding == null) + { + result.Add(new WorkerAvailableMachineItem + { + Id = m.Id, + Name = m.Name ?? m.DeviceCode, + DeviceCode = m.DeviceCode + }); + } + } + return result; + } } } diff --git a/src/CncService/Interface/IWorkerService.cs b/src/CncService/Interface/IWorkerService.cs index fc2f89a..e9766d8 100644 --- a/src/CncService/Interface/IWorkerService.cs +++ b/src/CncService/Interface/IWorkerService.cs @@ -15,5 +15,25 @@ namespace CncService.Interface bool ToggleEnabled(int id); bool BindMachine(int workerId, int machineId); bool UnbindMachine(int workerId, int machineId); + + /// + /// 获取工人绑定机床列表 + /// + List GetMachines(int workerId); + + /// + /// 获取工人今日产量明细 + /// + List GetTodayProduction(int workerId); + + /// + /// 获取工人7天产量趋势 + /// + List GetProductionTrend(int workerId); + + /// + /// 获取可绑定机床列表(未绑定其他工人的) + /// + List GetAvailableMachines(); } } diff --git a/src/CncWebApi/Controllers/WorkerController.cs b/src/CncWebApi/Controllers/WorkerController.cs index ac36ae8..1e7d8df 100644 --- a/src/CncWebApi/Controllers/WorkerController.cs +++ b/src/CncWebApi/Controllers/WorkerController.cs @@ -119,6 +119,54 @@ namespace CncWebApi.Controllers var result = _workerService.UnbindMachine(id, request.MachineId); return Ok(ApiResponse.Success(null)); } + + /// + /// 绑定机床列表 + /// GET /api/admin/worker/{id}/machines + /// + [HttpGet] + [Route("{id:int}/machines")] + public IHttpActionResult GetMachines(int id) + { + var result = _workerService.GetMachines(id); + return Ok(ApiResponse.Success(new { items = result })); + } + + /// + /// 工人今日产量明细 + /// GET /api/admin/worker/{id}/production/today + /// + [HttpGet] + [Route("{id:int}/production/today")] + public IHttpActionResult GetTodayProduction(int id) + { + var result = _workerService.GetTodayProduction(id); + return Ok(ApiResponse.Success(new { items = result })); + } + + /// + /// 工人7天产量趋势 + /// GET /api/admin/worker/{id}/production/trend + /// + [HttpGet] + [Route("{id:int}/production/trend")] + public IHttpActionResult GetProductionTrend(int id) + { + var result = _workerService.GetProductionTrend(id); + return Ok(ApiResponse.Success(new { items = result })); + } + + /// + /// 可绑定机床列表(未绑定其他工人的) + /// GET /api/admin/worker/available-machines + /// + [HttpGet] + [Route("available-machines")] + public IHttpActionResult GetAvailableMachines() + { + var result = _workerService.GetAvailableMachines(); + return Ok(ApiResponse.Success(new { items = result })); + } } ///