using System.Collections.Generic; using System.Linq; using Dapper; using CncModels.Entity; using CncModels.Dto; using CncModels.Dto.Machine; using CncRepository.Base; using CncRepository.Interface; namespace CncRepository.Impl { /// /// 机床实现 /// public class MachineRepository : BusinessRepository, IMachineRepository { public MachineRepository(string connectionString) : base(connectionString) { } /// 机床SELECT列映射模板(snake_case列名 → PascalCase属性名) /// 在线判断SQL片段:last_ping_time在20秒内视为在线 private const string OnlineExpr = "(CASE WHEN last_ping_time IS NOT NULL AND last_ping_time >= NOW() - INTERVAL 20 SECOND THEN 1 ELSE 0 END)"; private const string SelectColumns = @"id as Id, device_code as DeviceCode, name as Name, workshop_id as WorkshopId, collect_address_id as CollectAddressId, ip_address as IpAddress, brand_id as BrandId, is_enabled as IsEnabled, {0} as IsOnline, last_ping_time as LastPingTime, last_ping_latency as LastPingLatency, last_collect_time as LastCollectTime, last_device_status as LastDeviceStatus, last_run_status as LastRunStatus, last_program_name as LastProgramName, last_part_count as LastPartCount, last_operate_mode as LastOperateMode, last_machining_status as LastMachiningStatus, created_at as CreatedAt, updated_at as UpdatedAt"; public Machine GetById(int id) { using (var conn = CreateConnection()) { var cols = string.Format(SelectColumns, OnlineExpr); var sql = $"SELECT {cols} FROM cnc_machine WHERE id = @Id"; return conn.QuerySingleOrDefault(sql, new { Id = id }); } } public MachineDetailResponse GetDetailById(int id) { using (var conn = CreateConnection()) { var sql = @"SELECT m.id as Id, m.device_code as DeviceCode, m.name as Name, m.workshop_id as WorkshopId, ws.name as WorkshopName, m.collect_address_id as CollectAddressId, m.brand_id as BrandId, b.brand_name as BrandName, m.ip_address as IpAddress, m.is_enabled as IsEnabled, (CASE WHEN m.last_ping_time IS NOT NULL AND m.last_ping_time >= NOW() - INTERVAL 20 SECOND THEN 1 ELSE 0 END) as IsOnline, m.last_ping_latency as LastPingLatency, w.id as WorkerId, w.name as WorkerName, m.last_program_name as LastProgramName, m.last_collect_time as LastCollectTime FROM cnc_machine m LEFT JOIN cnc_workshop ws ON m.workshop_id = ws.id LEFT JOIN cnc_brand b ON m.brand_id = b.id LEFT JOIN cnc_worker_machine wm ON m.id = wm.machine_id LEFT JOIN cnc_worker w ON wm.worker_id = w.id WHERE m.id = @Id"; return conn.QuerySingleOrDefault(sql, new { Id = id }); } } public PagedResult GetList(MachineQuery query) { using (var conn = CreateConnection()) { var where = " WHERE 1=1"; var p = new DynamicParameters(); if (!string.IsNullOrWhiteSpace(query.Keyword)) { where += " AND (m.name LIKE @Keyword OR m.device_code LIKE @Keyword)"; p.Add("Keyword", $"%{query.Keyword}%"); } if (query.WorkshopId.HasValue) { where += " AND m.workshop_id = @WorkshopId"; p.Add("WorkshopId", query.WorkshopId.Value); } if (query.IsOnline.HasValue) { if (query.IsOnline.Value == 1) where += " AND m.last_ping_time IS NOT NULL AND m.last_ping_time >= NOW() - INTERVAL 20 SECOND"; else where += " AND (m.last_ping_time IS NULL OR m.last_ping_time < NOW() - INTERVAL 20 SECOND)"; } if (query.BrandId.HasValue) { where += " AND m.brand_id = @BrandId"; p.Add("BrandId", query.BrandId.Value); } var limit = query.PageSize; var offset = query.Offset; var sql = @"SELECT m.id as Id, m.device_code as DeviceCode, m.name as Name, m.workshop_id as WorkshopId, ws.name as WorkshopName, m.collect_address_id as CollectAddressId, m.brand_id as BrandId, b.brand_name as BrandName, m.ip_address as IpAddress, m.is_enabled as IsEnabled, (CASE WHEN m.last_ping_time IS NOT NULL AND m.last_ping_time >= NOW() - INTERVAL 20 SECOND THEN 1 ELSE 0 END) as IsOnline, m.last_ping_latency as LastPingLatency, m.last_program_name as LastProgramName, m.last_collect_time as LastCollectTime, w.id as WorkerId, w.name as WorkerName FROM cnc_machine m LEFT JOIN cnc_workshop ws ON m.workshop_id = ws.id LEFT JOIN cnc_brand b ON m.brand_id = b.id LEFT JOIN cnc_worker_machine wm ON m.id = wm.machine_id LEFT JOIN cnc_worker w ON wm.worker_id = w.id" + where + @" ORDER BY m.id DESC LIMIT @Limit OFFSET @Offset"; p.Add("Limit", limit); p.Add("Offset", offset); var totalSql = @"SELECT COUNT(*) FROM cnc_machine m" + where + @""; var total = conn.ExecuteScalar(totalSql, p); var items = conn.Query(sql, p).ToList(); return new PagedResult { Items = items, Total = total, Page = query.Page, PageSize = limit }; } } public int Create(Machine entity) { using (var conn = CreateConnection()) { var sql = @"INSERT INTO cnc_machine (device_code, name, workshop_id, collect_address_id, ip_address, brand_id, is_enabled, created_at, updated_at) VALUES (@DeviceCode, @Name, @WorkshopId, @CollectAddressId, @IpAddress, @BrandId, @IsEnabled, @CreatedAt, @UpdatedAt); SELECT LAST_INSERT_ID();"; return conn.QuerySingle(sql, entity); } } public bool Update(Machine entity) { using (var conn = CreateConnection()) { var sql = @"UPDATE cnc_machine SET device_code = @DeviceCode, name = @Name, workshop_id = @WorkshopId, collect_address_id = @CollectAddressId, ip_address = @IpAddress, brand_id = @BrandId, is_enabled = @IsEnabled, updated_at = @UpdatedAt, last_program_name = @LastProgramName, last_collect_time = @LastCollectTime, last_device_status = @LastDeviceStatus, last_run_status = @LastRunStatus, last_machining_status = @LastMachiningStatus WHERE id = @Id"; return conn.Execute(sql, entity) > 0; } } public bool Delete(int id) { using (var conn = CreateConnection()) { var sql = @"DELETE FROM cnc_machine WHERE id = @Id"; return conn.Execute(sql, new { Id = id }) > 0; } } public int BatchDelete(List ids) { if (ids == null || ids.Count == 0) return 0; using (var conn = CreateConnection()) { var sql = @"DELETE FROM cnc_machine WHERE id IN @Ids"; return conn.Execute(sql, new { Ids = ids }); } } public bool ToggleEnabled(int id) { using (var conn = CreateConnection()) { var sql = @"UPDATE cnc_machine SET is_enabled = CASE WHEN is_enabled = 1 THEN 0 ELSE 1 END, updated_at = NOW() WHERE id = @Id"; return conn.Execute(sql, new { Id = id }) > 0; } } public Machine GetByDeviceCode(string deviceCode) { using (var conn = CreateConnection()) { var cols = string.Format(SelectColumns, OnlineExpr); var sql = $"SELECT {cols} FROM cnc_machine WHERE device_code = @DeviceCode"; return conn.QuerySingleOrDefault(sql, new { DeviceCode = deviceCode }); } } public List GetEnabledByAddressId(int collectAddressId) { using (var conn = CreateConnection()) { var cols = string.Format(SelectColumns, OnlineExpr); var sql = $"SELECT {cols} FROM cnc_machine WHERE collect_address_id = @CollectAddressId AND is_enabled = 1"; return conn.Query(sql, new { CollectAddressId = collectAddressId }).ToList(); } } public List GetEnabledOnline() { using (var conn = CreateConnection()) { var cols = string.Format(SelectColumns, OnlineExpr); var sql = $"SELECT {cols} FROM cnc_machine WHERE is_enabled = 1 AND last_ping_time IS NOT NULL AND last_ping_time >= NOW() - INTERVAL 20 SECOND"; return conn.Query(sql).ToList(); } } public void UpdateLastCollect(int id, Machine entity) { using (var conn = CreateConnection()) { var sql = @"UPDATE cnc_machine SET last_collect_time = @LastCollectTime, last_program_name = @LastProgramName, last_machining_status = @LastMachiningStatus, updated_at = NOW() WHERE id = @Id"; var param = new { Id = id, LastCollectTime = entity.LastCollectTime, LastProgramName = entity.LastProgramName, LastMachiningStatus = entity.LastMachiningStatus }; conn.Execute(sql, param); } } public void SetCollectAddress(int machineId, int? collectAddressId) { using (var conn = CreateConnection()) { conn.Execute("UPDATE cnc_machine SET collect_address_id = @AddressId, updated_at = NOW() WHERE id = @Id", new { Id = machineId, AddressId = collectAddressId }); } } /// public MachineCollectRecordItem GetLatestCollectRecord(int machineId) { using (var conn = CreateConnection()) { string sql = @"SELECT DATE_FORMAT(cr.collect_time, '%Y-%m-%d %H:%i:%s') AS CollectTime, cr.program_name AS ProgramName, cr.part_count AS PartCount, cr.run_status AS RunStatus FROM cnc_collect_record cr WHERE cr.machine_id = @MachineId ORDER BY cr.collect_time DESC LIMIT 1"; return conn.QuerySingleOrDefault(sql, new { MachineId = machineId }); } } /// public List GetTodayProduction(int machineId) { using (var conn = CreateConnection()) { // 优先从已汇总的日产量表取 string dpSql = @"SELECT program_name AS ProgramName, CAST(total_quantity AS SIGNED) AS Quantity, total_run_time AS RunTime, total_cutting_time AS CuttingTime FROM cnc_daily_production WHERE machine_id = @MachineId AND production_date = CURDATE()"; var dpItems = conn.Query(dpSql, new { MachineId = machineId }).AsList(); if (dpItems.Count > 0) return dpItems; // 没有汇总数据则从分段表实时计算 string segSql = @"SELECT seg.program_name AS ProgramName, CAST(SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) AS SIGNED) AS Quantity, NULL AS RunTime, NULL AS CuttingTime FROM cnc_production_segment seg WHERE seg.machine_id = @MachineId AND seg.production_date = CURDATE() GROUP BY seg.program_name"; return conn.Query(segSql, new { MachineId = machineId }).AsList(); } } /// public List GetProductionTrend(int machineId, int days = 7) { using (var conn = CreateConnection()) { // 优先从日产量表取近N天数据 string sql = @"SELECT DATE_FORMAT(dp.production_date, '%Y-%m-%d') AS Date, CAST(SUM(dp.total_quantity) AS SIGNED) AS Quantity FROM cnc_daily_production dp WHERE dp.machine_id = @MachineId AND dp.production_date >= DATE_SUB(CURDATE(), INTERVAL @Days DAY) GROUP BY dp.production_date ORDER BY dp.production_date"; var items = conn.Query(sql, new { MachineId = machineId, Days = days - 1 }).AsList(); if (items.Count > 0) return items; // 没有汇总数据则从分段表实时计算 string segSql = @"SELECT DATE_FORMAT(seg.production_date, '%Y-%m-%d') AS Date, CAST(SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) AS SIGNED) AS Quantity FROM cnc_production_segment seg WHERE seg.machine_id = @MachineId AND seg.production_date >= DATE_SUB(CURDATE(), INTERVAL @Days DAY) GROUP BY seg.production_date ORDER BY seg.production_date"; return conn.Query(segSql, new { MachineId = machineId, Days = days - 1 }).AsList(); } } /// public List GetRecentCollectRecords(int machineId, int limit = 20) { using (var conn = CreateConnection()) { string sql = @"SELECT DATE_FORMAT(cr.collect_time, '%Y-%m-%d %H:%i:%s') AS CollectTime, cr.program_name AS ProgramName, cr.part_count AS PartCount, cr.run_status AS RunStatus FROM cnc_collect_record cr WHERE cr.machine_id = @MachineId ORDER BY cr.collect_time DESC LIMIT @Limit"; return conn.Query(sql, new { MachineId = machineId, Limit = limit }).AsList(); } } } }